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 9 // RUN: %clang_analyze_cc1 -std=c++14 -triple x86_64-pc-linux-gnu \ 10 // RUN: -analyzer-checker=core,debug.ExprInspection \ 11 // RUN: -analyzer-config eagerly-assume=false \ 12 // RUN: -analyzer-config experimental-enable-naive-ctu-analysis=true \ 13 // RUN: -analyzer-config ctu-dir=%t/ctudir \ 14 // RUN: -analyzer-config ctu-phase1-inlining=none \ 15 // RUN: -verify=newctu %s 16 17 // Simulate the behavior of the previous CTU implementation by inlining all 18 // functions during the first phase. This way, the second phase is a noop. 19 // RUN: %clang_analyze_cc1 -std=c++14 -triple x86_64-pc-linux-gnu \ 20 // RUN: -analyzer-checker=core,debug.ExprInspection \ 21 // RUN: -analyzer-config eagerly-assume=false \ 22 // RUN: -analyzer-config experimental-enable-naive-ctu-analysis=true \ 23 // RUN: -analyzer-config ctu-dir=%t/ctudir \ 24 // RUN: -analyzer-config ctu-phase1-inlining=all \ 25 // RUN: -verify=oldctu %s 26 27 // RUN: %clang_analyze_cc1 -std=c++14 -triple x86_64-pc-linux-gnu \ 28 // RUN: -analyzer-checker=core,debug.ExprInspection \ 29 // RUN: -analyzer-config experimental-enable-naive-ctu-analysis=true \ 30 // RUN: -analyzer-config ctu-dir=%t/ctudir \ 31 // RUN: -analyzer-config display-ctu-progress=true 2>&1 %s | FileCheck %s 32 33 // CHECK: CTU loaded AST file: {{.*}}ctu-other.cpp.ast 34 // CHECK: CTU loaded AST file: {{.*}}ctu-chain.cpp.ast 35 36 #include "ctu-hdr.h" 37 38 void clang_analyzer_eval(int); 39 40 int f(int); 41 int g(int); 42 int h(int); 43 callback_to_main(int x)44int callback_to_main(int x) { return x + 1; } 45 46 namespace myns { 47 int fns(int x); 48 49 namespace embed_ns { 50 int fens(int x); 51 } 52 53 class embed_cls { 54 public: 55 int fecl(int x); 56 }; 57 } 58 59 class mycls { 60 public: 61 int fcl(int x); 62 virtual int fvcl(int x); 63 static int fscl(int x); 64 65 class embed_cls2 { 66 public: 67 int fecl2(int x); 68 }; 69 }; 70 71 class derived : public mycls { 72 public: 73 virtual int fvcl(int x) override; 74 }; 75 76 namespace chns { 77 int chf1(int x); 78 } 79 80 int fun_using_anon_struct(int); 81 int other_macro_diag(int); 82 83 extern const int extInt; 84 namespace intns { 85 extern const int extInt; 86 } 87 struct S { 88 int a; 89 }; 90 extern const S extS; 91 extern S extNonConstS; 92 struct NonTrivialS { 93 int a; 94 // User declaring a dtor makes it non-trivial. 95 ~NonTrivialS(); 96 }; 97 extern const NonTrivialS extNTS; 98 extern const int extHere; 99 const int extHere = 6; 100 struct A { 101 static const int a; 102 }; 103 struct SC { 104 const int a; 105 }; 106 extern const SC extSC; 107 struct ST { 108 static const struct SC sc; 109 }; 110 struct SCNest { 111 struct SCN { 112 const int a; 113 } scn; 114 }; 115 extern SCNest extSCN; 116 extern const SCNest::SCN extSubSCN; 117 struct SCC { 118 SCC(int c); 119 const int a; 120 }; 121 extern SCC extSCC; 122 union U { 123 const int a; 124 const unsigned int b; 125 }; 126 extern const U extU; 127 test_virtual_functions(mycls * obj)128void test_virtual_functions(mycls* obj) { 129 // The dynamic type is known. 130 clang_analyzer_eval(mycls().fvcl(1) == 8); // newctu-warning{{TRUE}} ctu 131 // newctu-warning@-1{{UNKNOWN}} stu 132 // oldctu-warning@-2{{TRUE}} 133 clang_analyzer_eval(derived().fvcl(1) == 9); // newctu-warning{{TRUE}} ctu 134 // newctu-warning@-1{{UNKNOWN}} stu 135 // oldctu-warning@-2{{TRUE}} 136 // We cannot decide about the dynamic type. 137 clang_analyzer_eval(obj->fvcl(1) == 8); // newctu-warning{{TRUE}} ctu 138 // newctu-warning@-1{{UNKNOWN}} ctu, stu 139 // oldctu-warning@-2{{TRUE}} 140 // oldctu-warning@-3{{UNKNOWN}} 141 } 142 143 class TestAnonUnionUSR { 144 public: f(int value)145 inline float f(int value) { 146 union { 147 float f; 148 int i; 149 }; 150 i = value; 151 return f; 152 } 153 static const int Test; 154 }; 155 156 extern int testImportOfIncompleteDefaultParmDuringImport(int); 157 158 extern int testImportOfDelegateConstructor(int); 159 main()160int main() { 161 clang_analyzer_eval(f(3) == 2); // newctu-warning{{TRUE}} ctu 162 // newctu-warning@-1{{UNKNOWN}} stu 163 // oldctu-warning@-2{{TRUE}} 164 clang_analyzer_eval(f(4) == 3); // newctu-warning{{TRUE}} ctu 165 // newctu-warning@-1{{UNKNOWN}} stu 166 // oldctu-warning@-2{{TRUE}} 167 clang_analyzer_eval(f(5) == 3); // newctu-warning{{FALSE}} ctu 168 // newctu-warning@-1{{UNKNOWN}} stu 169 // oldctu-warning@-2{{FALSE}} 170 clang_analyzer_eval(g(4) == 6); // newctu-warning{{TRUE}} ctu 171 // newctu-warning@-1{{UNKNOWN}} stu 172 // oldctu-warning@-2{{TRUE}} 173 clang_analyzer_eval(h(2) == 8); // newctu-warning{{TRUE}} ctu 174 // newctu-warning@-1{{UNKNOWN}} stu 175 // oldctu-warning@-2{{TRUE}} 176 177 clang_analyzer_eval(myns::fns(2) == 9); // newctu-warning{{TRUE}} ctu 178 // newctu-warning@-1{{UNKNOWN}} stu 179 // oldctu-warning@-2{{TRUE}} 180 clang_analyzer_eval(myns::embed_ns::fens(2) == -1); // newctu-warning{{TRUE}} ctu 181 // newctu-warning@-1{{UNKNOWN}} stu 182 // oldctu-warning@-2{{TRUE}} 183 clang_analyzer_eval(mycls().fcl(1) == 6); // newctu-warning{{TRUE}} ctu 184 // newctu-warning@-1{{UNKNOWN}} stu 185 // oldctu-warning@-2{{TRUE}} 186 clang_analyzer_eval(mycls::fscl(1) == 7); // newctu-warning{{TRUE}} ctu 187 // newctu-warning@-1{{UNKNOWN}} stu 188 // oldctu-warning@-2{{TRUE}} 189 clang_analyzer_eval(myns::embed_cls().fecl(1) == -6); // newctu-warning{{TRUE}} ctu 190 // newctu-warning@-1{{UNKNOWN}} stu 191 // oldctu-warning@-2{{TRUE}} 192 clang_analyzer_eval(mycls::embed_cls2().fecl2(0) == -11); // newctu-warning{{TRUE}} ctu 193 // newctu-warning@-1{{UNKNOWN}} stu 194 // oldctu-warning@-2{{TRUE}} 195 196 clang_analyzer_eval(chns::chf1(4) == 12); // newctu-warning{{TRUE}} ctu 197 // newctu-warning@-1{{UNKNOWN}} stu 198 // oldctu-warning@-2{{TRUE}} 199 clang_analyzer_eval(fun_using_anon_struct(8) == 8); // newctu-warning{{TRUE}} ctu 200 // newctu-warning@-1{{UNKNOWN}} stu 201 // oldctu-warning@-2{{TRUE}} 202 203 clang_analyzer_eval(other_macro_diag(1) == 1); // newctu-warning{{TRUE}} ctu 204 // newctu-warning@-1{{UNKNOWN}} stu 205 // oldctu-warning@-2{{TRUE}} 206 // newctu-warning@Inputs/ctu-other.cpp:93{{REACHABLE}} 207 // oldctu-warning@Inputs/ctu-other.cpp:93{{REACHABLE}} 208 MACRODIAG(); // newctu-warning{{REACHABLE}} 209 // oldctu-warning@-1{{REACHABLE}} 210 211 // FIXME we should report an UNKNOWN as well for all external variables! 212 clang_analyzer_eval(extInt == 2); // newctu-warning{{TRUE}} 213 // oldctu-warning@-1{{TRUE}} 214 clang_analyzer_eval(intns::extInt == 3); // newctu-warning{{TRUE}} 215 // oldctu-warning@-1{{TRUE}} 216 clang_analyzer_eval(extS.a == 4); // newctu-warning{{TRUE}} 217 // oldctu-warning@-1{{TRUE}} 218 clang_analyzer_eval(extNonConstS.a == 4); // newctu-warning{{UNKNOWN}} 219 // oldctu-warning@-1{{UNKNOWN}} 220 // Do not import non-trivial classes' initializers. 221 clang_analyzer_eval(extNTS.a == 4); // newctu-warning{{UNKNOWN}} 222 // oldctu-warning@-1{{UNKNOWN}} 223 clang_analyzer_eval(extHere == 6); // newctu-warning{{TRUE}} 224 // oldctu-warning@-1{{TRUE}} 225 clang_analyzer_eval(A::a == 3); // newctu-warning{{TRUE}} 226 // oldctu-warning@-1{{TRUE}} 227 clang_analyzer_eval(extSC.a == 8); // newctu-warning{{TRUE}} 228 // oldctu-warning@-1{{TRUE}} 229 clang_analyzer_eval(ST::sc.a == 2); // newctu-warning{{TRUE}} 230 // oldctu-warning@-1{{TRUE}} 231 // clang_analyzer_eval(extSCN.scn.a == 9); // TODO 232 clang_analyzer_eval(extSubSCN.a == 1); // newctu-warning{{TRUE}} 233 // oldctu-warning@-1{{TRUE}} 234 // clang_analyzer_eval(extSCC.a == 7); // TODO 235 clang_analyzer_eval(extU.a == 4); // newctu-warning{{TRUE}} 236 // oldctu-warning@-1{{TRUE}} 237 clang_analyzer_eval(TestAnonUnionUSR::Test == 5); // newctu-warning{{TRUE}} 238 // oldctu-warning@-1{{TRUE}} 239 240 clang_analyzer_eval(testImportOfIncompleteDefaultParmDuringImport(9) == 9); 241 // newctu-warning@-1{{TRUE}} ctu 242 // newctu-warning@-2{{UNKNOWN}} stu 243 // oldctu-warning@-3{{TRUE}} 244 245 clang_analyzer_eval(testImportOfDelegateConstructor(10) == 10); 246 // newctu-warning@-1{{TRUE}} ctu 247 // newctu-warning@-2{{UNKNOWN}} stu 248 // oldctu-warning@-3{{TRUE}} 249 } 250