1 // RUN: rm -rf %t && mkdir %t 2 // RUN: mkdir -p %t/ctudir 3 // RUN: %clang_cc1 -std=c++14 -triple x86_64-pc-linux-gnu \ 4 // RUN: -emit-pch -o %t/ctudir/ctu-other.cpp.ast %S/Inputs/ctu-other.cpp 5 // RUN: %clang_cc1 -std=c++14 -triple x86_64-pc-linux-gnu \ 6 // RUN: -emit-pch -o %t/ctudir/ctu-chain.cpp.ast %S/Inputs/ctu-chain.cpp 7 // RUN: cp %S/Inputs/ctu-other.cpp.externalDefMap.ast-dump.txt %t/ctudir/externalDefMap.txt 8 // RUN: %clang_analyze_cc1 -std=c++14 -triple x86_64-pc-linux-gnu \ 9 // RUN: -analyzer-checker=core,debug.ExprInspection \ 10 // RUN: -analyzer-config experimental-enable-naive-ctu-analysis=true \ 11 // RUN: -analyzer-config ctu-dir=%t/ctudir \ 12 // RUN: -verify %s 13 // RUN: %clang_analyze_cc1 -std=c++14 -triple x86_64-pc-linux-gnu \ 14 // RUN: -analyzer-checker=core,debug.ExprInspection \ 15 // RUN: -analyzer-config experimental-enable-naive-ctu-analysis=true \ 16 // RUN: -analyzer-config ctu-dir=%t/ctudir \ 17 // RUN: -analyzer-config display-ctu-progress=true 2>&1 %s | FileCheck %s 18 19 // CHECK: CTU loaded AST file: {{.*}}ctu-other.cpp.ast 20 // CHECK: CTU loaded AST file: {{.*}}ctu-chain.cpp.ast 21 22 #include "ctu-hdr.h" 23 24 void clang_analyzer_eval(int); 25 26 int f(int); 27 int g(int); 28 int h(int); 29 30 int callback_to_main(int x) { return x + 1; } 31 32 namespace myns { 33 int fns(int x); 34 35 namespace embed_ns { 36 int fens(int x); 37 } 38 39 class embed_cls { 40 public: 41 int fecl(int x); 42 }; 43 } 44 45 class mycls { 46 public: 47 int fcl(int x); 48 virtual int fvcl(int x); 49 static int fscl(int x); 50 51 class embed_cls2 { 52 public: 53 int fecl2(int x); 54 }; 55 }; 56 57 class derived : public mycls { 58 public: 59 virtual int fvcl(int x) override; 60 }; 61 62 namespace chns { 63 int chf1(int x); 64 } 65 66 int fun_using_anon_struct(int); 67 int other_macro_diag(int); 68 69 extern const int extInt; 70 namespace intns { 71 extern const int extInt; 72 } 73 struct S { 74 int a; 75 }; 76 extern const S extS; 77 extern S extNonConstS; 78 struct NonTrivialS { 79 int a; 80 // User declaring a dtor makes it non-trivial. 81 ~NonTrivialS(); 82 }; 83 extern const NonTrivialS extNTS; 84 extern const int extHere; 85 const int extHere = 6; 86 struct A { 87 static const int a; 88 }; 89 struct SC { 90 const int a; 91 }; 92 extern const SC extSC; 93 struct ST { 94 static const struct SC sc; 95 }; 96 struct SCNest { 97 struct SCN { 98 const int a; 99 } scn; 100 }; 101 extern SCNest extSCN; 102 extern const SCNest::SCN extSubSCN; 103 struct SCC { 104 SCC(int c); 105 const int a; 106 }; 107 extern SCC extSCC; 108 union U { 109 const int a; 110 const unsigned int b; 111 }; 112 extern const U extU; 113 114 void test_virtual_functions(mycls* obj) { 115 // The dynamic type is known. 116 clang_analyzer_eval(mycls().fvcl(1) == 8); // expected-warning{{TRUE}} 117 clang_analyzer_eval(derived().fvcl(1) == 9); // expected-warning{{TRUE}} 118 // We cannot decide about the dynamic type. 119 clang_analyzer_eval(obj->fvcl(1) == 8); // expected-warning{{FALSE}} expected-warning{{TRUE}} 120 } 121 122 class TestAnonUnionUSR { 123 public: 124 inline float f(int value) { 125 union { 126 float f; 127 int i; 128 }; 129 i = value; 130 return f; 131 } 132 static const int Test; 133 }; 134 135 extern int testImportOfIncompleteDefaultParmDuringImport(int); 136 137 extern int testImportOfDelegateConstructor(int); 138 139 int main() { 140 clang_analyzer_eval(f(3) == 2); // expected-warning{{TRUE}} 141 clang_analyzer_eval(f(4) == 3); // expected-warning{{TRUE}} 142 clang_analyzer_eval(f(5) == 3); // expected-warning{{FALSE}} 143 clang_analyzer_eval(g(4) == 6); // expected-warning{{TRUE}} 144 clang_analyzer_eval(h(2) == 8); // expected-warning{{TRUE}} 145 146 clang_analyzer_eval(myns::fns(2) == 9); // expected-warning{{TRUE}} 147 clang_analyzer_eval(myns::embed_ns::fens(2) == -1); // expected-warning{{TRUE}} 148 clang_analyzer_eval(mycls().fcl(1) == 6); // expected-warning{{TRUE}} 149 clang_analyzer_eval(mycls::fscl(1) == 7); // expected-warning{{TRUE}} 150 clang_analyzer_eval(myns::embed_cls().fecl(1) == -6); // expected-warning{{TRUE}} 151 clang_analyzer_eval(mycls::embed_cls2().fecl2(0) == -11); // expected-warning{{TRUE}} 152 153 clang_analyzer_eval(chns::chf1(4) == 12); // expected-warning{{TRUE}} 154 clang_analyzer_eval(fun_using_anon_struct(8) == 8); // expected-warning{{TRUE}} 155 156 clang_analyzer_eval(other_macro_diag(1) == 1); // expected-warning{{TRUE}} 157 // expected-warning@Inputs/ctu-other.cpp:93{{REACHABLE}} 158 MACRODIAG(); // expected-warning{{REACHABLE}} 159 160 clang_analyzer_eval(extInt == 2); // expected-warning{{TRUE}} 161 clang_analyzer_eval(intns::extInt == 3); // expected-warning{{TRUE}} 162 clang_analyzer_eval(extS.a == 4); // expected-warning{{TRUE}} 163 clang_analyzer_eval(extNonConstS.a == 4); // expected-warning{{TRUE}} expected-warning{{FALSE}} 164 // Do not import non-trivial classes' initializers. 165 clang_analyzer_eval(extNTS.a == 4); // expected-warning{{TRUE}} expected-warning{{FALSE}} 166 clang_analyzer_eval(extHere == 6); // expected-warning{{TRUE}} 167 clang_analyzer_eval(A::a == 3); // expected-warning{{TRUE}} 168 clang_analyzer_eval(extSC.a == 8); // expected-warning{{TRUE}} 169 clang_analyzer_eval(ST::sc.a == 2); // expected-warning{{TRUE}} 170 // clang_analyzer_eval(extSCN.scn.a == 9); // TODO 171 clang_analyzer_eval(extSubSCN.a == 1); // expected-warning{{TRUE}} 172 // clang_analyzer_eval(extSCC.a == 7); // TODO 173 clang_analyzer_eval(extU.a == 4); // expected-warning{{TRUE}} 174 175 clang_analyzer_eval(TestAnonUnionUSR::Test == 5); // expected-warning{{TRUE}} 176 177 clang_analyzer_eval(testImportOfIncompleteDefaultParmDuringImport(9) == 9); // expected-warning{{TRUE}} 178 179 clang_analyzer_eval(testImportOfDelegateConstructor(10) == 10); // expected-warning{{TRUE}} 180 } 181