Issue with LLVM FunctionPass iterator? - c++11

I have a very basic pass that need to print how many BasicBlocks are there in a Function.
#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/Support/raw_ostream.h"
#include "iostream"
using namespace llvm;
namespace {
struct Mypass : public FunctionPass {
public:
static char ID; // Pass identification
Mypass() : FunctionPass(ID){}
bool runOnFunction(Function &F) override {
errs()<<"Function Name:";
errs()<<F.getName()<<"\n";
Function::iterator bb_i = F.begin();
int bb_count = 0;
for (Function::iterator I = F.begin(); I != F.end(); I++){
std::cout<< "Basic Block: BB"<<bb_count++<<std::endl;
}
return false;
}
};
}
char Mypass::ID = 0;
static RegisterPass<Mypass> X("Epass","Pass",true,false);
I run the pass using opt. And get this error:
> Function Name:testfnc1
> Basic Block: BB0 0 libLLVM-3.4.so 0x000000388b1935d2 llvm::sys::PrintStackTrace(_IO_FILE*) + 34 1 libLLVM-3.4.so
> 0x000000388b193dfa 2 libpthread.so.0 0x0000003feaa0f790 3
> EstimatePass.so 0x00007f04eb789737 4 libLLVM-3.4.so
> 0x000000388aad12b4 llvm::FPPassManager::runOnFunction(llvm::Function&)
> + 468 5 libLLVM-3.4.so 0x000000388aad139b llvm::FPPassManager::runOnModule(llvm::Module&) + 43 6 libLLVM-3.4.so
> 0x000000388aad0f1e llvm::legacy::PassManagerImpl::run(llvm::Module&) +
> 686 7 opt 0x000000000041f8d9 main + 5977 8 libc.so.6
> 0x0000003fea21ed5d __libc_start_main + 253 9 opt
> 0x000000000040ebf9 Stack dump:
> 0. Program arguments: opt -load /net/home/shaheen/llvm/mypass/EstimatePass.so -Epass -time-passes
> test.bc
> 1. Running pass 'Function Pass Manager' on module 'test.bc'.
> 2. Running pass 'Pass' on function '#testfnc1' Segmentation fault
I narrowed down to the issue and it happens when I increment the iterator. But I dont know why.
Here is the test file I am running my pass on:
#include "stdio.h"
void testfnc1(){
int i=1;int j=0;
for(i=1;i<10;i++)
for(j=1;j<10;j++)
printf("test");
};
int main()
{
int i;
printf("hello\n");
for(i=0;i<3;i++){
printf("hello:");
for(i=1;i<4;i++)
printf("asd");}
testfnc1();
}

The problem was that I was using llvm 3.6 while compiling the pass and the bitcode file I was generating was from clang version 3.4.
I just changed the Clang version to 3.6 and its now clompletely working fine.
Thank you

Related

Detecting uninitialized variables in gcc

The following (broken) example code scanf's an input string to an integer, but allow an empty string through to as 0:
#include <stdio.h>
#include <string.h>
int parse(const char *p)
{
int value; // whoops! forgot to 0 here.
if (*p && sscanf(p, "%d", &value) != 1)
return -1;
return value;
}
int main(int argc, char **argv)
{
const char *p = argc > 1 ? argv[1] : "";
int value = parse(p);
printf("value = %d\n", value);
}
but it compiles clean with -Wall.
https://godbolt.org/z/sPbx99Ms5
but fails with obvious problems:
$ ./test 123
value = 123
$ ./test xxx
value = -1
$ ./test ""
value = 32765
I realise it's quite hard for it to work out that the scanf might not fill in a value as it
can't see the code, but is there a flag or a scanner I could run on a (large) body of code to try and find if there are places where uninitialized variables are being passed by pointer?
... even something that would just find all uninitialized variables would be useful.

How to use std::chrono::milliseconds as a default parameter

Scenario
I have a C++ function which intakes a parameter as std::chrono::milliseconds. It is basically a timeout value. And, it is a default parameter set to some value by default.
Code
#include <iostream>
#include <chrono>
void Fun(const std::chrono::milliseconds someTimeout = std::chrono::milliseconds(100)) {
if (someTimeout > 0) {
std::cout << "someNumberInMillis is: " << someNumberInMillis.count() << std::endl;
}
}
int main() {
unsigned int someValue = 500;
Fun(std::chrono::milliseconds(someValue))
}
Issue
All of above is okay but, when I call Fun with a value then fails to compile and I get the following error:
No viable conversion from 'bool' to 'std::chrono::milliseconds' (aka
'duration >')
Question:
What am I doing wrong here? I want the caller of Fun to be explicitly aware that it is using std::chrono::milliseconds when it invokes Fun. But the compiler doesn't seem to allow using std::chrono::milliseconds as a parameter?
How use std::chrono::milliseconds as a default parameter?
Environment
Compiler used is clang on macOS High Sierra
With the other syntax errors fixed, this compiles without warnings in GCC 9:
#include <iostream>
#include <chrono>
void Fun(const std::chrono::milliseconds someNumberInMillis
= std::chrono::milliseconds(100))
{
if (someNumberInMillis > std::chrono::milliseconds{0}) {
std::cout << "someNumberInMillis is: " << someNumberInMillis.count()
<< std::endl;
}
}
int main()
{
unsigned int someValue = 500;
Fun(std::chrono::milliseconds(someValue));
}

warning: use of old-style cast [-Wold-style-cast]

Ubuntu 18.04, gcc version 6.4.0 20180424 (Ubuntu 6.4.0-17ubuntu1)
The following program calling the Eigen library in the Openfoam2.3.1 (a Computational Fluid Dynamics (CFD) class library) build environment, and it is built by g ++ - 5 compiler.
OpenFOAM 2.3.1 shell environment: source \$HOME/OpenFOAM/OpenFOAM-2.3.1/etc/bashrc $FOAM_SETTINGS; export WM_CC=gcc-5; export WM_CXX=g++-5
#include <iostream>
#include <Eigen/Dense>
using namespace std;
int main()
{
cout << "hello CFD" << endl;
return 0;
}
I got this wanrning
./Eigen/src/Core/util/XprHelper.h:438:68: warning: use of old-style cast [-Wold-style-cast]
enum { diag_size = EIGEN_SIZE_MIN_PREFER_DYNAMIC(ExpressionType::RowsAtCompileTime, ExpressionType::ColsAtCompileTime),
^
./Eigen/src/Core/util/Macros.h:376:51: note: in definition of macro ‘EIGEN_SIZE_MIN_PREFER_DYNAMIC’
#define EIGEN_SIZE_MIN_PREFER_DYNAMIC(a,b) (((int)a == 0 || (int)b == 0) ? 0 \
^
./Eigen/src/Core/util/XprHelper.h:438:103: warning: use of old-style cast [-Wold-style-cast]
enum { diag_size = EIGEN_SIZE_MIN_PREFER_DYNAMIC(ExpressionType::RowsAtCompileTime, ExpressionType::ColsAtCompileTime),
^
./Eigen/src/Core/util/Macros.h:376:66: note: in definition of macro ‘EIGEN_SIZE_MIN_PREFER_DYNAMIC’
#define EIGEN_SIZE_MIN_PREFER_DYNAMIC(a,b) (((int)a == 0 || (int)b == 0) ? 0 \
^
./Eigen/src/Core/util/XprHelper.h:438:68: warning: use of old-style cast [-Wold-style-cast]
enum { diag_size = EIGEN_SIZE_MIN_PREFER_DYNAMIC(ExpressionType::RowsAtCompileTime, ExpressionType::ColsAtCompileTime),
^
when I use g++ to compile this programm, I will not get this warning.
can you help me?

How to compile in Xcode C file with C11 language dialect?

I want to compile this source code:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
int main(int argc, const char *argv[]) {
While:
printf("MacBook-Pro-...:~ ...$ ");
char command[128];
gets_s(command);
if (strncmp(command, "exit", 4) == 0)
exit(0);
pid_t return_value = fork();
if (return_value == 0) {
int outfile;
if ((outfile = dup(1)) == -1)
return -1;
close(1);
if ((outfile = open("/Users/.../1.txt",
O_WRONLY | O_TRUNC | O_CREAT, 0644)) >= 0) {
execl("/bin/sh", "sh", "-c", command, NULL);
}
close(outfile);
exit(0);
} else {
wait();
FILE *fp;
char str[128];
fp = fopen("/Users/.../1.txt", "r");
while(!feof(fp)) {
if(fgets(str, 126, fp))
printf("%s", str);
}
fclose(fp);
goto While;
}
return 0;
}
But i have some errors:
Semantic Issue
Implicit declaration of function 'gets_s' is invalid in C99
Implicitly declaring library function 'exit' with type 'void (int) attribute((noreturn))'
Implicit declaration of function 'wait' is invalid in C99
Too few arguments to function call, expected 1, have 0
Project settings:
System:
ProductName: Mac OS X
ProductVersion: 10.12.1
BuildVersion: 16B2555
Xcode Version 8.0 (8A218a)
Apple LLVM version 8.0.0 (clang-800.0.38)
Target: x86_64-apple-darwin16.1.0
Thread model: posix
There are few problems:
Xcode doesn't see function definitions, that's why it says 'Implicit declaration of function 'foobar' is invalid in C99'. Even despite that Xcode attempts to compile your code assuming that unknown functions will be resolved during linking phase. In the case of exit and wait it will work, but to suppress the warning you just need to include stdlib: #include <stdlib.h>.
As of gets_s you need to do some extra actions to make it work (I don't know where it comes from).
Second problem is that signature of the wait function looks like this: int wait(int *), while you are not giving any parameters to it. Simply add 0 or NULL if you don't need to get exit code from a child process back.

getline on MacOSX 10.6 crashing C compiler?

I'm having a really hard time getting an R library installed that requires some compilation in C. I'm using a Mac OSX Snow Leopard machine and trying to install this R package (here).
I've looked at the thread talking about getline on macs and have tried a few of these fixes, but nothing is working! I'm a newbie and don't know any C, so that may be why! Can anyone give me some tips on how I could modify files in this package to get it to install?? Anyhelp would be pathetically appreciated! Here's the error I'm getting:
** libs
** arch - i386
g++ -arch i386 -I/Library/Frameworks/R.framework/Resources/include -I/Library/Frameworks/R.framework/Resources/include/i386 -I/usr/local/include -D_FASTMAP -DMAQ_LONGREADS -fPIC -g -O2 -c bed2vector.C -o bed2vector.o
In file included from /usr/include/c++/4.2.1/backward/strstream:51,
from bed2vector.C:8:
/usr/include/c++/4.2.1/backward/backward_warning.h:32:2: warning: #warning This file includes at least one deprecated or antiquated header. Please consider using one of the 32 headers found in section 17.4.1.2 of the C++ standard. Examples include substituting the <X> header for the <X.h> header for C++ includes, or <iostream> instead of the deprecated header <iostream.h>. To disable this warning use -Wno-deprecated.
bed2vector.C: In function ‘int get_a_line(FILE*, BZFILE*, int, std::string&)’:
bed2vector.C:74: error: no matching function for call to ‘getline(char**, size_t*, FILE*&)’
make: *** [bed2vector.o] Error 1
chmod: /Library/Frameworks/R.framework/Resources/library/spp/libs/i386/*: No such file or directory
ERROR: compilation failed for package 'spp'
The easiest solution is probably to add a static definition for getline() to bed2vector.c. This might be good enough:
/* PASTE AT TOP OF FILE */
#include <stdio.h> /* flockfile, getc_unlocked, funlockfile */
#include <stdlib.h> /* malloc, realloc */
#include <errno.h> /* errno */
#include <unistd.h> /* ssize_t */
extern "C" ssize_t getline(char **lineptr, size_t *n, FILE *stream);
/* PASTE REMAINDER AT BOTTOM OF FILE */
ssize_t
getline(char **linep, size_t *np, FILE *stream)
{
char *p = NULL;
size_t i = 0;
if (!linep || !np) {
errno = EINVAL;
return -1;
}
if (!(*linep) || !(*np)) {
*np = 120;
*linep = (char *)malloc(*np);
if (!(*linep)) {
return -1;
}
}
flockfile(stream);
p = *linep;
for (int ch = 0; (ch = getc_unlocked(stream)) != EOF;) {
if (i > *np) {
/* Grow *linep. */
size_t m = *np * 2;
char *s = (char *)realloc(*linep, m);
if (!s) {
int error = errno;
funlockfile(stream);
errno = error;
return -1;
}
*linep = s;
*np = m;
}
p[i] = ch;
if ('\n' == ch) break;
i += 1;
}
funlockfile(stream);
/* Null-terminate the string. */
if (i > *np) {
/* Grow *linep. */
size_t m = *np * 2;
char *s = (char *)realloc(*linep, m);
if (!s) {
return -1;
}
*linep = s;
*np = m;
}
p[i + 1] = '\0';
return ((i > 0)? i : -1);
}
This doesn't handle the case where the line is longer than the maximum value that ssize_t can represent. If you run into that case, you've likely got other problems.
Zeroth question: Have you considered using a package manager like fink or MacPorts rather than compiling yourself? I know that fink has an R package.
First question: How is the R build managed? Is there a ./configure? If so have you looked at the options to it? Does it use make? Scons? Some other dependency manager?
Second question: Have you told the build system that you are working on a Mac? Can you specify that you don't have a libc with native getline?
If the build system doesn't support Mac OS---but I image that R's does---you are probably going to have to download the standalone version, and hack the build to include it. How exactly you do that depends on the build system. And you may need to hack the source some.

Resources