running clang scan-build with g++ on linux - c++

I have the following code:
#include <iostream>
#include <memory>
using namespace std;
class A
{
public:
void foo() const;
};
void A::foo() const {}
std::unique_ptr<A> foo2()
{
std::unique_ptr<A> pa(new A());
return pa;
}
void
foo()
{
const A& ra = *foo2();
ra.foo();
}
int
main()
{
foo();
return 0;
}
I am trying to use clang's scan-build:
scan-build g++ --std=c++11 unique_ptr.cpp
This program compiles and runs fine with g++.
I am using CentOS and clang3.8 and g++4.8.5.
Error Message:
error: no type named 'unique_ptr' in namespace 'std'
std::unique_ptr<A> foo2()
~~~~~^

You should use:
scan-build g++ -std=c++11 unique_ptr.cpp
Instead of:
scan-build g++ --std=c++11 unique_ptr.cpp
-std works (while --std doesn't) because scan-build checks specifically for the -std flag.
In clang/tools/scan-build/libexec/ccc-analyzer:
if ($Arg =~ /^-std=/) {
push #CompileOpts,$Arg;
next;
}

Related

Clang plugin to print function call locations

Here is a minimal Clang plugin to print location of function calls.
I have a RecursiveASTVisitor visitor named FuncCallVisitor that is initialized with an ASTContext and tries to print the source location of the CallExpr.
#include "clang/AST/AST.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include <clang/Frontend/CompilerInstance.h>
#include <clang/Frontend/FrontendPluginRegistry.h>
#include <clang/Frontend/ASTConsumers.h>
#include <iostream>
using std::unique_ptr;
using std::make_unique;
using std::string;
using namespace clang;
class FuncCallVisitor : public RecursiveASTVisitor<FuncCallVisitor> {
public:
explicit FuncCallVisitor(CompilerInstance *CI)
: astContext(&(CI->getASTContext()))
{ }
bool VisitCallExpr(CallExpr * expr) {
auto loc = expr->getDirectCallee()->getLocation();
std::cerr << loc.printToString(astContext->getSourceManager()) << std::endl;
return true;
}
private:
ASTContext *astContext;
};
class FuncCallConsumer : public ASTConsumer {
public:
explicit FuncCallConsumer(CompilerInstance *CI)
: m_visitor(FuncCallVisitor(CI))
{ }
virtual bool HandleTopLevelDecl(DeclGroupRef dg) override {
for (Decl *decl : dg)
m_visitor.TraverseDecl(decl);
return true;
}
private:
FuncCallVisitor m_visitor;
};
class ParameterNameChecker : public PluginASTAction {
protected:
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &ci,
llvm::StringRef) override {
return make_unique<FuncCallConsumer>(&ci);
}
bool ParseArgs(const CompilerInstance&, const std::vector<string>&) override {
return true;
}
};
static FrontendPluginRegistry::Add<ParameterNameChecker>
X("-print-calls", "print location of function calls");
This expression from the above code causes a SEGFAULT
loc.printToString(astContext->getSourceManager())
https://i.stack.imgur.com/AQQWU.png
clang invocation:
clang-10 test.c -Xclang -load -Xclang ./Plugin.so -Xclang -plugin -Xclang -print-calls -c
Stack dump:
0. Program arguments: clang-10 ../../ast_test.c -o ast_test -Xclang -load -Xclang ./Plugin.so -Xclang -plugin -Xclang -print-calls -c
1. <eof> parser at end of file
/lib/x86_64-linux-gnu/libLLVM-10.so.1(_ZN4llvm3sys15PrintStackTraceERNS_11raw_ostreamE+0x1f)[0x7f17ba3c94ff]
/lib/x86_64-linux-gnu/libLLVM-10.so.1(_ZN4llvm3sys17RunSignalHandlersEv+0x50)[0x7f17ba3c77b0]
/lib/x86_64-linux-gnu/libLLVM-10.so.1(_ZN4llvm3sys15CleanupOnSignalEm+0xdd)[0x7f17ba3c8c4d]
/lib/x86_64-linux-gnu/libLLVM-10.so.1(+0x8d6e60)[0x7f17ba31ee60]
/lib/x86_64-linux-gnu/libpthread.so.0(+0x153c0)[0x7f17c0b993c0]
/lib/x86_64-linux-gnu/libclang-cpp.so.10(+0x797ffe)[0x7f17be873ffe]
/lib/x86_64-linux-gnu/libclang-cpp.so.10(+0x795cb7)[0x7f17be871cb7]
/lib/x86_64-linux-gnu/libclang-cpp.so.10(_ZNK5clang13SourceManager14getPresumedLocENS_14SourceLocationEb+0x25)[0x7f17be874da5]
/lib/x86_64-linux-gnu/libclang-cpp.so.10(_ZNK5clang14SourceLocation5printERN4llvm11raw_ostreamERKNS_13SourceManagerE+0x2d)[0x7f17be86f77d]
/lib/x86_64-linux-gnu/libclang-cpp.so.10(_ZNK5clang14SourceLocation13printToStringB5cxx11ERKNS_13SourceManagerE+0x69)[0x7f17be86fa09]
./Plugin.so(_ZN15FuncCallVisitor13VisitCallExprEPN5clang8CallExprE+0x48)[0x7f17b803a378]
./Plugin.so(_ZN5clang19RecursiveASTVisitorI15FuncCallVisitorE18WalkUpFromCallExprEPNS_8CallExprE+0x60)[0x7f17b8035e90]
./Plugin.so(_ZN5clang19RecursiveASTVisitorI15FuncCallVisitorE16TraverseCallExprEPNS_8CallExprEPN4llvm15SmallVectorImplINS5_14PointerIntPairIPNS_4StmtELj1EbNS5_21PointerLikeTypeTraitsIS9_EENS5_18PointerIntPairInfoIS9_Lj1ESB_EEEEEE+0x5f)[0x7f17b80511ef]
./Plugin.so(_ZN5clang19RecursiveASTVisitorI15FuncCallVisitorE16dataTraverseNodeEPNS_4StmtEPN4llvm15SmallVectorImplINS5_14PointerIntPairIS4_Lj1EbNS5_21PointerLikeTypeTraitsIS4_EENS5_18PointerIntPairInfoIS4_Lj1ES9_EEEEEE+0x16ab)[0x7f17b80309bb]
./Plugin.so(_ZN5clang19RecursiveASTVisitorI15FuncCallVisitorE12TraverseStmtEPNS_4StmtEPN4llvm15SmallVectorImplINS5_14PointerIntPairIS4_Lj1EbNS5_21PointerLikeTypeTraitsIS4_EENS5_18PointerIntPairInfoIS4_Lj1ES9_EEEEEE+0x233)[0x7f17b802c143]
./Plugin.so(_ZN5clang19RecursiveASTVisitorI15FuncCallVisitorE22TraverseFunctionHelperEPNS_12FunctionDeclE+0x55f)[0x7f17b80bf92f]
./Plugin.so(_ZN5clang19RecursiveASTVisitorI15FuncCallVisitorE20TraverseFunctionDeclEPNS_12FunctionDeclE+0x7e)[0x7f17b800fa5e]
./Plugin.so(_ZN5clang19RecursiveASTVisitorI15FuncCallVisitorE12TraverseDeclEPNS_4DeclE+0x9a6)[0x7f17b8007a56]
./Plugin.so(_ZN16FuncCallConsumer18HandleTopLevelDeclEN5clang12DeclGroupRefE+0x69)[0x7f17b8006d89]
/lib/x86_64-linux-gnu/libclang-cpp.so.10(_ZN5clang17MultiplexConsumer18HandleTopLevelDeclENS_12DeclGroupRefE+0x2c)[0x7f17bfddc8bc]
/lib/x86_64-linux-gnu/libclang-cpp.so.10(_ZN5clang8ParseASTERNS_4SemaEbb+0x214)[0x7f17be931ba4]
/lib/x86_64-linux-gnu/libclang-cpp.so.10(_ZN5clang14FrontendAction7ExecuteEv+0x48)[0x7f17bfda7e58]
/lib/x86_64-linux-gnu/libclang-cpp.so.10(_ZN5clang16CompilerInstance13ExecuteActionERNS_14FrontendActionE+0x621)[0x7f17bfd608a1]
/lib/x86_64-linux-gnu/libclang-cpp.so.10(_ZN5clang25ExecuteCompilerInvocationEPNS_16CompilerInstanceE+0x66f)[0x7f17bfe0bdaf]
clang-10(_Z8cc1_mainN4llvm8ArrayRefIPKcEES2_Pv+0x98d)[0x41229d]
clang-10[0x4105b1]
/lib/x86_64-linux-gnu/libclang-cpp.so.10(+0x19d58f2)[0x7f17bfab18f2]
/lib/x86_64-linux-gnu/libLLVM-10.so.1(_ZN4llvm20CrashRecoveryContext9RunSafelyENS_12function_refIFvvEEE+0xd7)[0x7f17ba31ec67]
/lib/x86_64-linux-gnu/libclang-cpp.so.10(_ZNK5clang6driver10CC1Command7ExecuteEN4llvm8ArrayRefINS2_8OptionalINS2_9StringRefEEEEEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPb+0x13f)[0x7f17bfab0e2f]
/lib/x86_64-linux-gnu/libclang-cpp.so.10(_ZNK5clang6driver11Compilation14ExecuteCommandERKNS0_7CommandERPS3_+0x2df)[0x7f17bfa8952f]
/lib/x86_64-linux-gnu/libclang-cpp.so.10(_ZNK5clang6driver11Compilation11ExecuteJobsERKNS0_7JobListERN4llvm15SmallVectorImplISt4pairIiPKNS0_7CommandEEEE+0x7a)[0x7f17bfa896da]
/lib/x86_64-linux-gnu/libclang-cpp.so.10(_ZN5clang6driver6Driver18ExecuteCompilationERNS0_11CompilationERN4llvm15SmallVectorImplISt4pairIiPKNS0_7CommandEEEE+0xdc)[0x7f17bfa9c93c]
clang-10(main+0x259f)[0x41002f]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0x7f17b95300b3]
clang-10(_start+0x2e)[0x40d7ce]
clang: error: clang frontend command failed due to signal (use -v to see invocation)
clang version 10.0.0-4ubuntu1
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
clang: note: diagnostic msg: PLEASE submit a bug report to https://bugs.llvm.org/ and include the crash backtrace, preprocessed source, and associated run script.
clang: error: unable to execute command: Segmentation fault (core dumped)
clang: note: diagnostic msg: Error generating preprocessed source(s).

Why does g++ accept a reference type with missing underlying type?

I was meaning to add a copy constructor to a class but forgot to add the type. g++ 5.4.0 compiled the class successfully.
Here's a minimal program that g++ 5.4.0 compiles and builds successfully.
struct Foo
{
Foo(const&) {}
Foo() {}
};
int main()
{
Foo f1;
Foo f2 = f1;
}
Why does g++ not report Foo(const&) {} as an error?
This seems to be a defect in my installation of g++ 5.4.0.
It fails to compile using g++ 6.3 at https://ideone.com/D0vGrw.
I have used the same block of code.
struct Foo
{
Foo(const&) {}
Foo() {}
};
int main()
{
Foo f1;
Foo f2 = f1;
}
It also fails to compile using g++ 5.4.0 at Wandbox.

Symbol not found in debugger only, when having templated template argument

Given the following code as test.cpp,
Building using clang++ -c test.cpp -o test.o -g; clang++ test.o -g -all_load, setting breakpoint at return a.getValue(); and attempting to p a.getValue() from lldb:
Running llvm 3.8.0 on unix - works perfectly
Running xcode or llvm 8.1.0 on OSX - I get the following error:
error: Couldn't lookup symbols:
__ZNK4Test7MyClassILi2ELi3EE8getValueEv
Two interesting facts:
If I remove the last template argument - all works well
If I build directly without going through the .o file (clang++ test.cpp) = all goes well
Anyone has a clue what is going on, and how can it be fixed?
namespace Test{
template<class T>
class BLA{
public:
T getBlaValue() const{return 3;}
};
template <int N1, int N2, template<class T>class Impl = BLA>
class MyClass {
private:
public:
__attribute__((used))
int getValue() const
{
return 3;
}
};
}
int main()
{
Test::MyClass<2, 3> a;
return a.getValue();
}

Warnings for uninitialized members disappear on the C++11

I compile this simple program:
#include <cstdio>
#include <iostream>
using namespace std;
struct Foo
{
int a;
int b;
};
struct Bar
{
//Bar() = default;
int d;
};
int main()
{
Foo foo;
Bar bar;
printf("%d %d\n", foo.a, foo.b);
return 0;
}
and I get those warnings:
$ g++ -std=c++11 -Wall -Wextra -Wpedantic foo.cpp -o foo
foo.cpp: In function ‘int main()’:
foo.cpp:21:9: warning: unused variable ‘bar’ [-Wunused-variable]
Bar bar;
^
foo.cpp:23:11: warning: ‘foo.Foo::b’ is used uninitialized in this function [-Wuninitialized]
printf("%d %d\n", foo.a, foo.b);
^
foo.cpp:23:11: warning: ‘foo.Foo::a’ is used uninitialized in this function [-Wuninitialized]
Of course, this is what we expect. But when I uncomment the Bar default ctor, there is a problem - all warnings disappear.
Why the Bar ctor disables warnings for Foo?
My GCC version is: g++ (Ubuntu 5.4.0-6ubuntu1~16.04.2) 5.4.0 20160609.
The problem does not occur on the C++03, only on the C++11 or newer.
It's a compiler bug, which as Jarod pointed out, has been fixed.

Can't compile program with clang

I`am trying to compile code bellow. GCC compile it, but clang not.
Error: no member named 'sa' in 'A' static void sf() {A::sa('j');}
What's problem?
test.cpp:
template<typename T>
class A
{
private:
public:
void f() {this->a('j');}
static void sf() {A::sa('j');}
#ifdef U
void a(char x) {}
static void sa(char x) {}
#endif
};
UPD:
I use compilers, that included in Android NDK r10c
gcc 4.9:
cd C:\Tools\android-ndk-r10c\toolchains\x86-4.9\prebuilt\windows-x86_64\bin
clang++.exe -c C:\Users\Barkov_V\Desktop\test.cpp
clang 3.5:
cd C:\Tools\android-ndk-r10c\toolchains\llvm-3.5\prebuilt\windows-x86_64\bin
i686-linux-android-gcc-4.9.exe -c C:\Users\Barkov_V\Desktop\test.cpp