brintos

brintos / llvm-project-archived public Read only

0
0
Text · 19.8 KiB · d6cef88 Raw
692 lines · cpp
1// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -Wno-error=invalid-gnu-asm-cast -std=c++11 -analyzer-config cfg-rich-constructors=false %s > %t 2>&12// RUN: FileCheck --input-file=%t -check-prefixes=CHECK,WARNINGS %s3// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -Wno-error=invalid-gnu-asm-cast -std=c++11 -analyzer-config cfg-rich-constructors=true %s > %t 2>&14// RUN: FileCheck --input-file=%t -check-prefixes=CHECK,ANALYZER %s5 6// This file tests how we construct two different flavors of the Clang CFG -7// the CFG used by the Sema analysis-based warnings and the CFG used by the8// static analyzer. The difference in the behavior is checked via FileCheck9// prefixes (WARNINGS and ANALYZER respectively). When introducing new analyzer10// flags, no new run lines should be added - just these flags would go to the11// respective line depending on where is it turned on and where is it turned12// off. Feel free to add tests that test only one of the CFG flavors if you're13// not sure how the other flavor is supposed to work in your case.14 15// CHECK-LABEL: void checkDeclStmts()16// CHECK: ENTRY17// CHECK-NEXT: Succs (1): B118// CHECK: [B1]19// CHECK-NEXT:   1: int i;20// CHECK-NEXT:   2: int j;21// CHECK-NEXT:   3: 122// CHECK-NEXT:   4: int k = 1;23// CHECK-NEXT:   5: int l;24// CHECK-NEXT:   6: 225// CHECK-NEXT:   7: int m = 2;26// WARNINGS-NEXT: (CXXConstructExpr, struct standalone)27// ANALYZER-NEXT: (CXXConstructExpr, [B1.9], struct standalone)28// CHECK-NEXT:   9: struct standalone myStandalone;29// WARNINGS-NEXT: (CXXConstructExpr, struct (unnamed struct at {{.*}}))30// ANALYZER-NEXT: (CXXConstructExpr, [B1.11], struct (unnamed struct at {{.*}}))31// CHECK-NEXT:  11: struct (unnamed struct at {{.*}}) myAnon;32// WARNINGS-NEXT: (CXXConstructExpr, struct named)33// ANALYZER-NEXT: (CXXConstructExpr, [B1.13], struct named)34// CHECK-NEXT:  13: struct named myNamed;35// CHECK-NEXT:   Preds (1): B236// CHECK-NEXT:   Succs (1): B037void checkDeclStmts() {38  int i, j;39  int k = 1, l, m = 2;40 41  struct standalone { int x, y; };42  struct standalone myStandalone;43 44  struct { int x, y; } myAnon;45 46  struct named { int x, y; } myNamed;47 48  static_assert(1, "abc");49}50 51// CHECK-LABEL: void F(EmptyE e)52// CHECK: ENTRY53// CHECK-NEXT: Succs (1): B154// CHECK: [B1]55// CHECK-NEXT:   1: e56// CHECK-NEXT:   2: [B1.1] (ImplicitCastExpr, LValueToRValue, EmptyE)57// CHECK-NEXT:   3: [B1.2] (ImplicitCastExpr, IntegralCast, int)58// CHECK-NEXT:   T: switch [B1.3]59// CHECK-NEXT:   Preds (1): B260// CHECK-NEXT:   Succs (1): B061// CHECK: [B0 (EXIT)]62// CHECK-NEXT:   Preds (1): B163enum EmptyE {};64void F(EmptyE e) {65  switch (e) {}66}67 68// CHECK-LABEL: void testBuiltinSize()69// CHECK: ENTRY70// CHECK-NEXT: Succs (1): B171// CHECK: [B1]72// CHECK-NEXT:   1: __builtin_object_size73// CHECK-NEXT:   2: [B1.1] (ImplicitCastExpr, BuiltinFnToFnPtr, __size_t (*)(const void *, int) noexcept)74// CHECK-NEXT:   3: [B1.2](dummy(), 0)75// CHECK-NEXT:   4: (void)[B1.3] (CStyleCastExpr, ToVoid, void)76// CHECK-NEXT:   Preds (1): B277// CHECK-NEXT:   Succs (1): B078// CHECK: [B0 (EXIT)]79// CHECK-NEXT:   Preds (1): B180void testBuiltinSize() {81  extern int *dummy();82  (void)__builtin_object_size(dummy(), 0);83}84 85class A {86public:87  A() {}88  ~A() {}89};90 91// CHECK-LABEL: void test_deletedtor()92// CHECK: [B2 (ENTRY)]93// CHECK-NEXT:   Succs (1): B194// CHECK: [B1]95// CHECK-NEXT:   1:  CFGNewAllocator(A *)96// WARNINGS-NEXT:   2:  (CXXConstructExpr, A)97// ANALYZER-NEXT:   2:  (CXXConstructExpr, [B1.3], A)98// CHECK-NEXT:   3: new A([B1.2])99// CHECK-NEXT:   4: A *a = new A();100// CHECK-NEXT:   5: a101// CHECK-NEXT:   6: [B1.5] (ImplicitCastExpr, LValueToRValue, A *)102// CHECK-NEXT:   7: [B1.6]->~A() (Implicit destructor)103// CHECK-NEXT:   8: delete [B1.6]104// CHECK-NEXT:   Preds (1): B2105// CHECK-NEXT:   Succs (1): B0106// CHECK: [B0 (EXIT)]107// CHECK-NEXT:   Preds (1): B1108void test_deletedtor() {109  A *a = new A();110  delete a;111}112 113// CHECK-LABEL: void test_deleteArraydtor()114// CHECK: [B2 (ENTRY)]115// CHECK-NEXT:   Succs (1): B1116// CHECK: [B1]117// CHECK-NEXT:   1: 5118// CHECK-NEXT:   2: CFGNewAllocator(A *)119// WARNINGS-NEXT:   3:  (CXXConstructExpr, A[5])120// ANALYZER-NEXT:   3:  (CXXConstructExpr, [B1.4], A[5])121// CHECK-NEXT:   4: new A {{\[\[}}B1.1]]122// CHECK-NEXT:   5: A *a = new A [5];123// CHECK-NEXT:   6: a124// CHECK-NEXT:   7: [B1.6] (ImplicitCastExpr, LValueToRValue, A *)125// CHECK-NEXT:   8: [B1.7]->~A() (Implicit destructor)126// CHECK-NEXT:   9: delete [] [B1.7]127// CHECK-NEXT:   Preds (1): B2128// CHECK-NEXT:   Succs (1): B0129// CHECK: [B0 (EXIT)]130// CHECK-NEXT:   Preds (1): B1131void test_deleteArraydtor() {132  A *a = new A[5];133  delete[] a;134}135 136 137namespace NoReturnSingleSuccessor {138  struct A {139    A();140    ~A();141  };142 143  struct B : public A {144    B();145    ~B() __attribute__((noreturn));146  };147 148// CHECK-LABEL: int test1(int *x)149// CHECK: 1: 1150// CHECK-NEXT: 2: return151// CHECK-NEXT: ~B() (Implicit destructor)152// CHECK-NEXT: Preds (1)153// CHECK-NEXT: Succs (1): B0154  int test1(int *x) {155    B b;156    if (x)157      return 1;158  }159 160// CHECK-LABEL: int test2(int *x)161// CHECK: 1: 1162// CHECK-NEXT: 2: return163// CHECK-NEXT: destructor164// CHECK-NEXT: Preds (1)165// CHECK-NEXT: Succs (1): B0166  int test2(int *x) {167    const A& a = B();168    if (x)169      return 1;170  }171}172 173// Test CFG support for "extending" an enum.174// CHECK-LABEL: int test_enum_with_extension(enum MyEnum value)175// CHECK:  [B7 (ENTRY)]176// CHECK-NEXT:    Succs (1): B2177// CHECK:  [B1]178// CHECK-NEXT:    1: x179// CHECK-NEXT:    2: [B1.1] (ImplicitCastExpr, LValueToRValue, int)180// CHECK-NEXT:    3: return [B1.2];181// CHECK-NEXT:    Preds (5): B3 B4 B5 B6 B2(Unreachable)182// CHECK-NEXT:    Succs (1): B0183// CHECK:  [B2]184// CHECK-NEXT:    1: 0185// CHECK-NEXT:    2: int x = 0;186// CHECK-NEXT:    3: value187// CHECK-NEXT:    4: [B2.3] (ImplicitCastExpr, LValueToRValue, enum MyEnum)188// CHECK-NEXT:    5: [B2.4] (ImplicitCastExpr, IntegralCast, int)189// CHECK-NEXT:    T: switch [B2.5]190// CHECK-NEXT:    Preds (1): B7191// CHECK-NEXT:    Succs (5): B3 B4 B5 B6 B1(Unreachable)192// CHECK:  [B3]193// CHECK-NEXT:   case D:194// CHECK-NEXT:    1: 4195// CHECK-NEXT:    2: x196// CHECK-NEXT:    3: [B3.2] = [B3.1]197// CHECK-NEXT:    T: break;198// CHECK-NEXT:    Preds (1): B2199// CHECK-NEXT:    Succs (1): B1200// CHECK:  [B4]201// CHECK-NEXT:   case C:202// CHECK-NEXT:    1: 3203// CHECK-NEXT:    2: x204// CHECK-NEXT:    3: [B4.2] = [B4.1]205// CHECK-NEXT:    T: break;206// CHECK-NEXT:    Preds (1): B2207// CHECK-NEXT:    Succs (1): B1208// CHECK:  [B5]209// CHECK-NEXT:   case B:210// CHECK-NEXT:    1: 2211// CHECK-NEXT:    2: x212// CHECK-NEXT:    3: [B5.2] = [B5.1]213// CHECK-NEXT:    T: break;214// CHECK-NEXT:    Preds (1): B2215// CHECK-NEXT:    Succs (1): B1216// CHECK:  [B6]217// CHECK-NEXT:   case A:218// CHECK-NEXT:    1: 1219// CHECK-NEXT:    2: x220// CHECK-NEXT:    3: [B6.2] = [B6.1]221// CHECK-NEXT:    T: break;222// CHECK-NEXT:    Preds (1): B2223// CHECK-NEXT:    Succs (1): B1224// CHECK:  [B0 (EXIT)]225// CHECK-NEXT:    Preds (1): B1226enum MyEnum : int { A, B, C };227static const enum MyEnum D = (enum MyEnum) 32;228 229int test_enum_with_extension(enum MyEnum value) {230  int x = 0;231  switch (value) {232    case A: x = 1; break;233    case B: x = 2; break;234    case C: x = 3; break;235    case D: x = 4; break;236  }237  return x;238}239 240// CHECK-LABEL: int test_enum_with_extension_default(enum MyEnum value)241// CHECK:  [B7 (ENTRY)]242// CHECK-NEXT:    Succs (1): B2243// CHECK:  [B1]244// CHECK-NEXT:    1: x245// CHECK-NEXT:    2: [B1.1] (ImplicitCastExpr, LValueToRValue, int)246// CHECK-NEXT:    3: return [B1.2];247// CHECK-NEXT:    Preds (4): B3 B4 B5 B6248// CHECK-NEXT:    Succs (1): B0249// CHECK:  [B2]250// CHECK-NEXT:    1: 0251// CHECK-NEXT:    2: int x = 0;252// CHECK-NEXT:    3: value253// CHECK-NEXT:    4: [B2.3] (ImplicitCastExpr, LValueToRValue, enum MyEnum)254// CHECK-NEXT:    5: [B2.4] (ImplicitCastExpr, IntegralCast, int)255// CHECK-NEXT:    T: switch [B2.5]256// CHECK-NEXT:    Preds (1): B7257// CHECK-NEXT:    Succs (4): B4 B5 B6 B3(Unreachable)258// CHECK:  [B3]259// CHECK-NEXT:   default:260// CHECK-NEXT:    1: 4261// CHECK-NEXT:    2: x262// CHECK-NEXT:    3: [B3.2] = [B3.1]263// CHECK-NEXT:    T: break;264// CHECK-NEXT:    Preds (1): B2(Unreachable)265// CHECK-NEXT:    Succs (1): B1266// CHECK:  [B4]267// CHECK-NEXT:   case C:268// CHECK-NEXT:    1: 3269// CHECK-NEXT:    2: x270// CHECK-NEXT:    3: [B4.2] = [B4.1]271// CHECK-NEXT:    T: break;272// CHECK-NEXT:    Preds (1): B2273// CHECK-NEXT:    Succs (1): B1274// CHECK:  [B5]275// CHECK-NEXT:   case B:276// CHECK-NEXT:    1: 2277// CHECK-NEXT:    2: x278// CHECK-NEXT:    3: [B5.2] = [B5.1]279// CHECK-NEXT:    T: break;280// CHECK-NEXT:    Preds (1): B2281// CHECK-NEXT:    Succs (1): B1282// CHECK:  [B6]283// CHECK-NEXT:   case A:284// CHECK-NEXT:    1: 1285// CHECK-NEXT:    2: x286// CHECK-NEXT:    3: [B6.2] = [B6.1]287// CHECK-NEXT:    T: break;288// CHECK-NEXT:    Preds (1): B2289// CHECK-NEXT:    Succs (1): B1290// CHECK:  [B0 (EXIT)]291// CHECK-NEXT:    Preds (1): B1292int test_enum_with_extension_default(enum MyEnum value) {293  int x = 0;294  switch (value) {295    case A: x = 1; break;296    case B: x = 2; break;297    case C: x = 3; break;298    default: x = 4; break;299  }300  return x;301}302 303// CHECK-LABEL: void test_placement_new()304// CHECK:  [B2 (ENTRY)]305// CHECK-NEXT:  Succs (1): B1306// CHECK:  [B1]307// CHECK-NEXT:  1: int buffer[16];308// CHECK-NEXT:  2: buffer309// CHECK-NEXT:  3: [B1.2] (ImplicitCastExpr, ArrayToPointerDecay, int *)310// CHECK-NEXT:  4: [B1.3] (ImplicitCastExpr, BitCast, void *)311// CHECK-NEXT:  5: CFGNewAllocator(MyClass *)312// WARNINGS-NEXT:  6:  (CXXConstructExpr, MyClass)313// ANALYZER-NEXT:  6:  (CXXConstructExpr, [B1.7], MyClass)314// CHECK-NEXT:  7: new ([B1.4]) MyClass([B1.6])315// CHECK-NEXT:  8: MyClass *obj = new (buffer) MyClass();316// CHECK-NEXT:  Preds (1): B2317// CHECK-NEXT:  Succs (1): B0318// CHECK: [B0 (EXIT)]319// CHECK-NEXT:  Preds (1): B1320 321extern void* operator new (unsigned long sz, void* v);322extern void* operator new[] (unsigned long sz, void* ptr);323 324class MyClass {325public:326  MyClass() {}327  ~MyClass() {}328};329 330void test_placement_new() {331  int buffer[16];332  MyClass* obj = new (buffer) MyClass();333}334 335// CHECK-LABEL: void test_placement_new_array()336// CHECK:  [B2 (ENTRY)]337// CHECK-NEXT:  Succs (1): B1338// CHECK: [B1]339// CHECK-NEXT:  1: int buffer[16];340// CHECK-NEXT:  2: buffer341// CHECK-NEXT:  3: [B1.2] (ImplicitCastExpr, ArrayToPointerDecay, int *)342// CHECK-NEXT:  4: [B1.3] (ImplicitCastExpr, BitCast, void *)343// CHECK-NEXT:  5: 5344// CHECK-NEXT:  6: CFGNewAllocator(MyClass *)345// WARNINGS-NEXT:  7:  (CXXConstructExpr, MyClass[5])346// ANALYZER-NEXT:  7:  (CXXConstructExpr, [B1.8], MyClass[5])347// CHECK-NEXT:  8: new ([B1.4]) MyClass {{\[\[}}B1.5]]348// CHECK-NEXT:  9: MyClass *obj = new (buffer) MyClass [5];349// CHECK-NEXT:  Preds (1): B2350// CHECK-NEXT:  Succs (1): B0351// CHECK: [B0 (EXIT)]352// CHECK-NEXT:  Preds (1): B1353 354void test_placement_new_array() {355  int buffer[16];356  MyClass* obj = new (buffer) MyClass[5];357}358 359 360// CHECK-LABEL: void test_lifetime_extended_temporaries()361// CHECK: [B1]362struct LifetimeExtend { LifetimeExtend(int); ~LifetimeExtend(); };363struct Aggregate { const LifetimeExtend a; const LifetimeExtend b; };364struct AggregateRef { const LifetimeExtend &a; const LifetimeExtend &b; };365void test_lifetime_extended_temporaries() {366  // CHECK: LifetimeExtend(1);367  // CHECK-NEXT: : 1368  // CHECK-NEXT: ~LifetimeExtend()369  // CHECK-NOT: ~LifetimeExtend()370  {371    const LifetimeExtend &l = LifetimeExtend(1);372    1;373  }374  // CHECK: LifetimeExtend(2)375  // CHECK-NEXT: ~LifetimeExtend()376  // CHECK-NEXT: : 2377  // CHECK-NOT: ~LifetimeExtend()378  {379    // No life-time extension.380    const int &l = (LifetimeExtend(2), 2);381    2;382  }383  // CHECK: LifetimeExtend(3)384  // CHECK-NEXT: : 3385  // CHECK-NEXT: ~LifetimeExtend()386  // CHECK-NOT: ~LifetimeExtend()387  {388    // The last one is lifetime extended.389    const LifetimeExtend &l = (3, LifetimeExtend(3));390    3;391  }392  // CHECK: LifetimeExtend(4)393  // CHECK-NEXT: ~LifetimeExtend()394  // CHECK-NEXT: ~LifetimeExtend()395  // CHECK-NEXT: : 4396  // CHECK-NOT: ~LifetimeExtend()397  {398    Aggregate a{LifetimeExtend(4), LifetimeExtend(4)};399    4;400  }401  // CHECK: LifetimeExtend(5)402  // CHECK-NEXT: : 5403  // FIXME: We want to emit the destructors of the lifetime404  // extended variables here.405  // CHECK-NOT: ~LifetimeExtend()406  {407    AggregateRef a{LifetimeExtend(5), LifetimeExtend(5)};408    5;409  }410  // FIXME: Add tests for lifetime extension via subobject411  // references (LifetimeExtend().some_member).412}413 414 415// FIXME: The destructor for 'a' shouldn't be there because it's deleted416// in the union.417// CHECK-LABEL: void foo()418// CHECK:  [B2 (ENTRY)]419// CHECK-NEXT:    Succs (1): B1420// CHECK:  [B1]421// WARNINGS-NEXT:    1:  (CXXConstructExpr, A)422// ANALYZER-NEXT:    1:  (CXXConstructExpr, [B1.2], A)423// CHECK-NEXT:    2: A a;424// CHECK-NEXT:    3: [B1.2].~A() (Implicit destructor)425// CHECK-NEXT:    Preds (1): B2426// CHECK-NEXT:    Succs (1): B0427// CHECK:  [B0 (EXIT)]428// CHECK-NEXT:    Preds (1): B1429 430namespace pr37688_deleted_union_destructor {431struct S { ~S(); };432struct A {433  ~A() noexcept {}434  union {435    struct {436      S s;437    } ss;438  };439};440void foo() {441  A a;442}443} // end namespace pr37688_deleted_union_destructor444 445 446namespace return_statement_expression {447int unknown();448 449// CHECK-LABEL: int foo()450// CHECK:       [B6 (ENTRY)]451// CHECK-NEXT:    Succs (1): B5452// CHECK:       [B1]453// CHECK-NEXT:    1: 0454// CHECK-NEXT:    2: return [B1.1];455// CHECK-NEXT:    Preds (1): B5456// CHECK-NEXT:    Succs (1): B0457// CHECK:       [B2]458// CHECK-NEXT:    1: 0459// CHECK-NEXT:    2: ({ ... ; [B2.1] })460// CHECK-NEXT:    3: return [B2.2];461// CHECK-NEXT:    Preds (1): B4462// CHECK-NEXT:    Succs (1): B0463// FIXME: Why do we have [B3] at all?464// CHECK:       [B3]465// CHECK-NEXT:    Succs (1): B4466// CHECK:       [B4]467// CHECK-NEXT:    1: 0468// CHECK-NEXT:    2: [B4.1] (ImplicitCastExpr, IntegralToBoolean, _Bool)469// CHECK-NEXT:    T: while [B4.2]470// CHECK-NEXT:    Preds (2): B3 B5471// CHECK-NEXT:    Succs (2): NULL B2472// CHECK:       [B5]473// CHECK-NEXT:    1: unknown474// CHECK-NEXT:    2: [B5.1] (ImplicitCastExpr, FunctionToPointerDecay, int (*)(void))475// CHECK-NEXT:    3: [B5.2]()476// CHECK-NEXT:    4: [B5.3] (ImplicitCastExpr, IntegralToBoolean, _Bool)477// CHECK-NEXT:    T: if [B5.4]478// CHECK-NEXT:    Preds (1): B6479// CHECK-NEXT:    Succs (2): B4 B1480// CHECK:       [B0 (EXIT)]481// CHECK-NEXT:    Preds (2): B1 B2482int foo() {483  if (unknown())484    return ({485      while (0)486        ;487      0;488    });489  else490    return 0;491}492} // namespace statement_expression_in_return493 494// CHECK-LABEL: void vla_simple(int x)495// CHECK: [B1]496// CHECK-NEXT:   1: x497// CHECK-NEXT:   2: [B1.1] (ImplicitCastExpr, LValueToRValue, int)498// CHECK-NEXT:   3: int vla[x];499void vla_simple(int x) {500  int vla[x];501}502 503// CHECK-LABEL: void vla_typedef(int x)504// CHECK: [B1]505// CHECK-NEXT:   1: x506// CHECK-NEXT:   2: [B1.1] (ImplicitCastExpr, LValueToRValue, int)507// CHECK-NEXT:   3: typedef int VLA[x];508void vla_typedef(int x) {509  typedef int VLA[x];510}511 512// CHECK-LABEL: void vla_typealias(int x)513// CHECK: [B1]514// CHECK-NEXT:   1: x515// CHECK-NEXT:   2: [B1.1] (ImplicitCastExpr, LValueToRValue, int)516// CHECK-NEXT:   3: using VLA = int[x];517void vla_typealias(int x) {518  using VLA = int[x];519}520 521// CHECK-LABEL: void vla_typedef_multi(int x, int y)522// CHECK:  [B1]523// CHECK-NEXT:   1: y524// CHECK-NEXT:   2: [B1.1] (ImplicitCastExpr, LValueToRValue, int)525// CHECK-NEXT:   3: x526// CHECK-NEXT:   4: [B1.3] (ImplicitCastExpr, LValueToRValue, int)527// CHECK-NEXT:   5: typedef int VLA[x][y];528void vla_typedef_multi(int x, int y) {529  typedef int VLA[x][y];530}531 532// CHECK-LABEL: void vla_typedefname_multi(int x, int y)533// CHECK:  [B1]534// CHECK-NEXT:   1: x535// CHECK-NEXT:   2: [B1.1] (ImplicitCastExpr, LValueToRValue, int)536// CHECK-NEXT:   3: typedef int VLA[x];537// CHECK-NEXT:   4: y538// CHECK-NEXT:   5: [B1.4] (ImplicitCastExpr, LValueToRValue, int)539// CHECK-NEXT:   6: typedef VLA VLA1[y];540// CHECK-NEXT:   7: 3541// CHECK-NEXT:   8: using VLA2 = VLA1[3];542// CHECK-NEXT:   9: 4543// CHECK-NEXT:  10: VLA2 vla[4];544void vla_typedefname_multi(int x, int y) {545  typedef int VLA[x];546  typedef VLA VLA1[y];547  using VLA2 = VLA1[3];548  VLA2 vla[4];549}550 551// CHECK-LABEL: int vla_evaluate(int x)552// CHECK:  [B1]553// CHECK-NEXT:   1: x554// CHECK-NEXT:   2: ++[B1.1]555// CHECK-NEXT:   3: [B1.2] (ImplicitCastExpr, LValueToRValue, int)556// CHECK-NEXT:   4: typedef int VLA[++x];557// CHECK-NEXT:   5: x558// CHECK-NEXT:   6: ++[B1.5]559// CHECK-NEXT:   7: [B1.6] (ImplicitCastExpr, LValueToRValue, int)560// CHECK-NEXT:   8: sizeof(int[++x])561// CHECK-NEXT:   9: alignof(int[++x])562// CHECK-NEXT:  10: 0563// CHECK-NEXT:  11: x564// CHECK-NEXT:  12: [B1.11] (ImplicitCastExpr, LValueToRValue, int)565// CHECK-NEXT:  13: return [B1.12];566int vla_evaluate(int x) {567  // Evaluates the ++x568  typedef int VLA[++x];569  sizeof(int[++x]);570 571  // Do not evaluate the ++x572  _Alignof(int[++x]);573  _Generic((int(*)[++x])0, default : 0);574 575  return x;576}577 578// CHECK-LABEL: void CommaTemp::f()579// CHECK:       [B1]580// CHECK-NEXT:    1: A() (CXXConstructExpr,581// CHECK-NEXT:    2: [B1.1] (BindTemporary)582// CHECK-NEXT:    3: B() (CXXConstructExpr,583// CHECK-NEXT:    4: [B1.3] (BindTemporary)584// CHECK-NEXT:    5: ... , [B1.4]585// CHECK-NEXT:    6: ~B() (Temporary object destructor)586// CHECK-NEXT:    7: ~A() (Temporary object destructor)587namespace CommaTemp {588  struct A { ~A(); };589  struct B { ~B(); };590  void f();591}592void CommaTemp::f() {593  A(), B();594}595 596// CHECK-LABEL: int crash_with_thread_local(char *p, int *q)597// CHECK:       [B7 (ENTRY)]598// CHECK-NEXT:    Succs (1): B6599// CHECK:       [B1]600// CHECK-NEXT:   bail:601// CHECK-NEXT:    1: 0602// CHECK-NEXT:    2: return [B1.1];603// CHECK-NEXT:    Preds (2): B2 B5604// CHECK-NEXT:    Succs (1): B0605// CHECK:       [B2]606// CHECK-NEXT:    1: 0607// CHECK-NEXT:    2: q608// CHECK-NEXT:    3: [B2.2] (ImplicitCastExpr, LValueToRValue, int *)609// CHECK-NEXT:    4: *[B2.3]610// CHECK-NEXT:    5: [B2.4] = [B2.1]611// CHECK-NEXT:    Preds (2): B3 B4612// CHECK-NEXT:    Succs (1): B1613// CHECK:       [B3]614// WARNINGS-NEXT: 1:  (CXXConstructExpr, ClassWithDtor)615// ANALYZER-NEXT: 1:  (CXXConstructExpr, [B3.2], ClassWithDtor)616// CHECK-NEXT:    2: thread_local ClassWithDtor a;617// CHECK-NEXT:    Preds (1): B4618// CHECK-NEXT:    Succs (1): B2619// CHECK:       [B4]620// CHECK-NEXT:    T: static init a621// CHECK-NEXT:    Preds (1): B6622// CHECK-NEXT:    Succs (2): B2 B3623// CHECK:       [B5]624// CHECK-NEXT:    T: goto bail;625// CHECK-NEXT:    Preds (1): B6626// CHECK-NEXT:    Succs (1): B1627// CHECK:       [B6]628// CHECK-NEXT:    1: p629// CHECK-NEXT:    2: [B6.1] (ImplicitCastExpr, LValueToRValue, char *)630// CHECK-NEXT:    3: 0631// CHECK-NEXT:    4: [B6.3] (ImplicitCastExpr, NullToPointer, char *)632// CHECK-NEXT:    5: [B6.2] != [B6.4]633// CHECK-NEXT:    T: if [B6.5]634// CHECK-NEXT:    Preds (1): B7635// CHECK-NEXT:    Succs (2): B5 B4636// CHECK:       [B0 (EXIT)]637// CHECK-NEXT:    Preds (1): B1638 639struct ClassWithDtor {640  ~ClassWithDtor() {}641};642 643int crash_with_thread_local(char *p, int *q) {644  if (p != 0) {645    goto bail;646  }647  thread_local ClassWithDtor a;648  *q = 0;649bail:650  return 0;651}652 653// CHECK-LABEL: void DecompositionDecl()654// CHECK:       [B1]655// CHECK-NEXT:    1: int arr[2];656// CHECK-NEXT:    2: arr657// CHECK-NEXT:    3: [B1.2] (ImplicitCastExpr, ArrayToPointerDecay, int *)658// CHECK-NEXT:    4: *659// CHECK-NEXT:    5: [B1.3]{{\[\[}}B1.4]]660// CHECK-NEXT:    6: [B1.5] (ImplicitCastExpr, LValueToRValue, int)661// CHECK-NEXT:    7: {{\{}}[B1.6]{{(\})}}662// CHECK-NEXT:    8: auto = {{\{}}arr[*]{{(\})}};663void DecompositionDecl() {664  int arr[2];665 666  auto [a, b] = arr;667}668 669// CHECK-LABEL: template<> int *PR18472<int>()670// CHECK: [B2 (ENTRY)]671// CHECK-NEXT:   Succs (1): B1672// CHECK: [B1]673// CHECK-NEXT:   1: 0674// CHECK-NEXT:   2: [B1.1] (ImplicitCastExpr, NullToPointer, PR18472_t)675// CHECK-NEXT:   3: (PR18472_t)[B1.2] (CStyleCastExpr, NoOp, PR18472_t)676// CHECK-NEXT:   4: CFGNewAllocator(int *)677// CHECK-NEXT:   5: new (([B1.3])) int678// CHECK-NEXT:   6: return [B1.5];679// CHECK-NEXT:   Preds (1): B2680// CHECK-NEXT:   Succs (1): B0681// CHECK: [B0 (EXIT)]682// CHECK-NEXT:   Preds (1): B1683 684extern "C" typedef int *PR18472_t;685void *operator new (unsigned long, PR18472_t);686template <class T> T *PR18472() {687  return new (((PR18472_t) 0)) T;688}689void PR18472_helper() {690  PR18472<int>();691}692