diff options
Diffstat (limited to 'test/Analysis/cfg.cpp')
-rw-r--r-- | test/Analysis/cfg.cpp | 256 |
1 files changed, 238 insertions, 18 deletions
diff --git a/test/Analysis/cfg.cpp b/test/Analysis/cfg.cpp index 660d1f264694..65060b168744 100644 --- a/test/Analysis/cfg.cpp +++ b/test/Analysis/cfg.cpp @@ -1,5 +1,7 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -std=c++11 %s 2>&1 | FileCheck %s +// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -std=c++11 %s > %t 2>&1 +// RUN: FileCheck --input-file=%t %s +// CHECK-LABEL: void checkWrap(int i) // CHECK: ENTRY // CHECK-NEXT: Succs (1): B1 // CHECK: [B1] @@ -35,6 +37,7 @@ void checkWrap(int i) { } } +// CHECK-LABEL: void checkDeclStmts() // CHECK: ENTRY // CHECK-NEXT: Succs (1): B1 // CHECK: [B1] @@ -48,7 +51,7 @@ void checkWrap(int i) { // CHECK-NEXT: CXXConstructExpr // CHECK-NEXT: 9: struct standalone myStandalone; // CHECK-NEXT: CXXConstructExpr -// CHECK-NEXT: 11: struct <anonymous struct at {{.*}}> myAnon; +// CHECK-NEXT: 11: struct (anonymous struct at {{.*}}) myAnon; // CHECK-NEXT: CXXConstructExpr // CHECK-NEXT: 13: struct named myNamed; // CHECK-NEXT: Preds (1): B2 @@ -67,6 +70,7 @@ void checkDeclStmts() { static_assert(1, "abc"); } +// CHECK-LABEL: void F(EmptyE e) // CHECK: ENTRY // CHECK-NEXT: Succs (1): B1 // CHECK: [B1] @@ -83,6 +87,7 @@ void F(EmptyE e) { switch (e) {} } +// CHECK-LABEL: void testBuiltinSize() // CHECK: ENTRY // CHECK-NEXT: Succs (1): B1 // CHECK: [B1] @@ -106,16 +111,18 @@ public: ~A() {} }; +// CHECK-LABEL: void test_deletedtor() // CHECK: [B2 (ENTRY)] // CHECK-NEXT: Succs (1): B1 // CHECK: [B1] -// CHECK-NEXT: 1: (CXXConstructExpr, class A) -// CHECK-NEXT: 2: new A([B1.1]) -// CHECK-NEXT: 3: A *a = new A(); -// CHECK-NEXT: 4: a -// CHECK-NEXT: 5: [B1.4] (ImplicitCastExpr, LValueToRValue, class A *) -// CHECK-NEXT: 6: [B1.5]->~A() (Implicit destructor) -// CHECK-NEXT: 7: delete [B1.5] +// CHECK-NEXT: 1: CFGNewAllocator(A *) +// CHECK-NEXT: 2: (CXXConstructExpr, class A) +// CHECK-NEXT: 3: new A([B1.2]) +// CHECK-NEXT: 4: A *a = new A(); +// CHECK-NEXT: 5: a +// CHECK-NEXT: 6: [B1.5] (ImplicitCastExpr, LValueToRValue, class A *) +// CHECK-NEXT: 7: [B1.6]->~A() (Implicit destructor) +// CHECK-NEXT: 8: delete [B1.6] // CHECK-NEXT: Preds (1): B2 // CHECK-NEXT: Succs (1): B0 // CHECK: [B0 (EXIT)] @@ -125,17 +132,19 @@ void test_deletedtor() { delete a; } +// CHECK-LABEL: void test_deleteArraydtor() // CHECK: [B2 (ENTRY)] // CHECK-NEXT: Succs (1): B1 // CHECK: [B1] // CHECK-NEXT: 1: 5 -// CHECK-NEXT: 2: (CXXConstructExpr, class A) -// CHECK-NEXT: 3: new A {{\[\[}}B1.1]] -// CHECK-NEXT: 4: A *a = new A [5]; -// CHECK-NEXT: 5: a -// CHECK-NEXT: 6: [B1.5] (ImplicitCastExpr, LValueToRValue, class A *) -// CHECK-NEXT: 7: [B1.6]->~A() (Implicit destructor) -// CHECK-NEXT: 8: delete [] [B1.6] +// CHECK-NEXT: 2: CFGNewAllocator(A *) +// CHECK-NEXT: 3: (CXXConstructExpr, class A) +// CHECK-NEXT: 4: new A {{\[\[}}B1.1]] +// CHECK-NEXT: 5: A *a = new A [5]; +// CHECK-NEXT: 6: a +// CHECK-NEXT: 7: [B1.6] (ImplicitCastExpr, LValueToRValue, class A *) +// CHECK-NEXT: 8: [B1.7]->~A() (Implicit destructor) +// CHECK-NEXT: 9: delete [] [B1.7] // CHECK-NEXT: Preds (1): B2 // CHECK-NEXT: Succs (1): B0 // CHECK: [B0 (EXIT)] @@ -157,7 +166,7 @@ namespace NoReturnSingleSuccessor { ~B() __attribute__((noreturn)); }; -// CHECK: ENTRY +// CHECK-LABEL: int test1(int *x) // CHECK: 1: 1 // CHECK-NEXT: 2: return // CHECK-NEXT: ~B() (Implicit destructor) @@ -169,7 +178,7 @@ namespace NoReturnSingleSuccessor { return 1; } -// CHECK: ENTRY +// CHECK-LABEL: int test2(int *x) // CHECK: 1: 1 // CHECK-NEXT: 2: return // CHECK-NEXT: destructor @@ -181,3 +190,214 @@ namespace NoReturnSingleSuccessor { return 1; } } + +// Test CFG support for "extending" an enum. +// CHECK-LABEL: int test_enum_with_extension(enum MyEnum value) +// CHECK: [B7 (ENTRY)] +// CHECK-NEXT: Succs (1): B2 +// CHECK: [B1] +// CHECK-NEXT: 1: x +// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, LValueToRValue, int) +// CHECK-NEXT: 3: return [B1.2]; +// CHECK-NEXT: Preds (5): B3 B4 B5 B6 B2(Unreachable) +// CHECK-NEXT: Succs (1): B0 +// CHECK: [B2] +// CHECK-NEXT: 1: 0 +// CHECK-NEXT: 2: int x = 0; +// CHECK-NEXT: 3: value +// CHECK-NEXT: 4: [B2.3] (ImplicitCastExpr, LValueToRValue, enum MyEnum) +// CHECK-NEXT: 5: [B2.4] (ImplicitCastExpr, IntegralCast, int) +// CHECK-NEXT: T: switch [B2.5] +// CHECK-NEXT: Preds (1): B7 +// CHECK-NEXT: Succs (5): B3 B4 B5 B6 B1(Unreachable) +// CHECK: [B3] +// CHECK-NEXT: case D: +// CHECK-NEXT: 1: 4 +// CHECK-NEXT: 2: x +// CHECK-NEXT: 3: [B3.2] = [B3.1] +// CHECK-NEXT: T: break; +// CHECK-NEXT: Preds (1): B2 +// CHECK-NEXT: Succs (1): B1 +// CHECK: [B4] +// CHECK-NEXT: case C: +// CHECK-NEXT: 1: 3 +// CHECK-NEXT: 2: x +// CHECK-NEXT: 3: [B4.2] = [B4.1] +// CHECK-NEXT: T: break; +// CHECK-NEXT: Preds (1): B2 +// CHECK-NEXT: Succs (1): B1 +// CHECK: [B5] +// CHECK-NEXT: case B: +// CHECK-NEXT: 1: 2 +// CHECK-NEXT: 2: x +// CHECK-NEXT: 3: [B5.2] = [B5.1] +// CHECK-NEXT: T: break; +// CHECK-NEXT: Preds (1): B2 +// CHECK-NEXT: Succs (1): B1 +// CHECK: [B6] +// CHECK-NEXT: case A: +// CHECK-NEXT: 1: 1 +// CHECK-NEXT: 2: x +// CHECK-NEXT: 3: [B6.2] = [B6.1] +// CHECK-NEXT: T: break; +// CHECK-NEXT: Preds (1): B2 +// CHECK-NEXT: Succs (1): B1 +// CHECK: [B0 (EXIT)] +// CHECK-NEXT: Preds (1): B1 +enum MyEnum { A, B, C }; +static const enum MyEnum D = (enum MyEnum) 32; + +int test_enum_with_extension(enum MyEnum value) { + int x = 0; + switch (value) { + case A: x = 1; break; + case B: x = 2; break; + case C: x = 3; break; + case D: x = 4; break; + } + return x; +} + +// CHECK-LABEL: int test_enum_with_extension_default(enum MyEnum value) +// CHECK: [B7 (ENTRY)] +// CHECK-NEXT: Succs (1): B2 +// CHECK: [B1] +// CHECK-NEXT: 1: x +// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, LValueToRValue, int) +// CHECK-NEXT: 3: return [B1.2]; +// CHECK-NEXT: Preds (4): B3 B4 B5 B6 +// CHECK-NEXT: Succs (1): B0 +// CHECK: [B2] +// CHECK-NEXT: 1: 0 +// CHECK-NEXT: 2: int x = 0; +// CHECK-NEXT: 3: value +// CHECK-NEXT: 4: [B2.3] (ImplicitCastExpr, LValueToRValue, enum MyEnum) +// CHECK-NEXT: 5: [B2.4] (ImplicitCastExpr, IntegralCast, int) +// CHECK-NEXT: T: switch [B2.5] +// CHECK-NEXT: Preds (1): B7 +// CHECK-NEXT: Succs (4): B4 B5 B6 B3(Unreachable) +// CHECK: [B3] +// CHECK-NEXT: default: +// CHECK-NEXT: 1: 4 +// CHECK-NEXT: 2: x +// CHECK-NEXT: 3: [B3.2] = [B3.1] +// CHECK-NEXT: T: break; +// CHECK-NEXT: Preds (1): B2(Unreachable) +// CHECK-NEXT: Succs (1): B1 +// CHECK: [B4] +// CHECK-NEXT: case C: +// CHECK-NEXT: 1: 3 +// CHECK-NEXT: 2: x +// CHECK-NEXT: 3: [B4.2] = [B4.1] +// CHECK-NEXT: T: break; +// CHECK-NEXT: Preds (1): B2 +// CHECK-NEXT: Succs (1): B1 +// CHECK: [B5] +// CHECK-NEXT: case B: +// CHECK-NEXT: 1: 2 +// CHECK-NEXT: 2: x +// CHECK-NEXT: 3: [B5.2] = [B5.1] +// CHECK-NEXT: T: break; +// CHECK-NEXT: Preds (1): B2 +// CHECK-NEXT: Succs (1): B1 +// CHECK: [B6] +// CHECK-NEXT: case A: +// CHECK-NEXT: 1: 1 +// CHECK-NEXT: 2: x +// CHECK-NEXT: 3: [B6.2] = [B6.1] +// CHECK-NEXT: T: break; +// CHECK-NEXT: Preds (1): B2 +// CHECK-NEXT: Succs (1): B1 +// CHECK: [B0 (EXIT)] +// CHECK-NEXT: Preds (1): B1 +int test_enum_with_extension_default(enum MyEnum value) { + int x = 0; + switch (value) { + case A: x = 1; break; + case B: x = 2; break; + case C: x = 3; break; + default: x = 4; break; + } + return x; +} + + +// CHECK-LABEL: void test_placement_new() +// CHECK: [B2 (ENTRY)] +// CHECK-NEXT: Succs (1): B1 +// CHECK: [B1] +// CHECK-NEXT: 1: int buffer[16]; +// CHECK-NEXT: 2: buffer +// CHECK-NEXT: 3: [B1.2] (ImplicitCastExpr, ArrayToPointerDecay, int *) +// CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, BitCast, void *) +// CHECK-NEXT: 5: CFGNewAllocator(MyClass *) +// CHECK-NEXT: 6: (CXXConstructExpr, class MyClass) +// CHECK-NEXT: 7: new ([B1.4]) MyClass([B1.6]) +// CHECK-NEXT: 8: MyClass *obj = new (buffer) MyClass(); +// CHECK-NEXT: Preds (1): B2 +// CHECK-NEXT: Succs (1): B0 +// CHECK: [B0 (EXIT)] +// CHECK-NEXT: Preds (1): B1 + +extern void* operator new (unsigned long sz, void* v); +extern void* operator new[] (unsigned long sz, void* ptr); + +class MyClass { +public: + MyClass() {} + ~MyClass() {} +}; + +void test_placement_new() { + int buffer[16]; + MyClass* obj = new (buffer) MyClass(); +} + +// CHECK-LABEL: void test_placement_new_array() +// CHECK: [B2 (ENTRY)] +// CHECK-NEXT: Succs (1): B1 +// CHECK: [B1] +// CHECK-NEXT: 1: int buffer[16]; +// CHECK-NEXT: 2: buffer +// CHECK-NEXT: 3: [B1.2] (ImplicitCastExpr, ArrayToPointerDecay, int *) +// CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, BitCast, void *) +// CHECK-NEXT: 5: 5 +// CHECK-NEXT: 6: CFGNewAllocator(MyClass *) +// CHECK-NEXT: 7: (CXXConstructExpr, class MyClass) +// CHECK-NEXT: 8: new ([B1.4]) MyClass {{\[\[}}B1.5]] +// CHECK-NEXT: 9: MyClass *obj = new (buffer) MyClass [5]; +// CHECK-NEXT: Preds (1): B2 +// CHECK-NEXT: Succs (1): B0 +// CHECK: [B0 (EXIT)] +// CHECK-NEXT: Preds (1): B1 + +void test_placement_new_array() { + int buffer[16]; + MyClass* obj = new (buffer) MyClass[5]; +} + + +// CHECK-LABEL: int *PR18472() +// CHECK: [B2 (ENTRY)] +// CHECK-NEXT: Succs (1): B1 +// CHECK: [B1] +// CHECK-NEXT: 1: 0 +// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, NullToPointer, PR18472_t) +// CHECK-NEXT: 3: (PR18472_t)[B1.2] (CStyleCastExpr, NoOp, PR18472_t) +// CHECK-NEXT: 4: CFGNewAllocator(int *) +// CHECK-NEXT: 5: new (([B1.3])) int +// CHECK-NEXT: 6: return [B1.5]; +// CHECK-NEXT: Preds (1): B2 +// CHECK-NEXT: Succs (1): B0 +// CHECK: [B0 (EXIT)] +// CHECK-NEXT: Preds (1): B1 + +extern "C" typedef int *PR18472_t; +void *operator new (unsigned long, PR18472_t); +template <class T> T *PR18472() { + return new (((PR18472_t) 0)) T; +} +void PR18472_helper() { + PR18472<int>(); +} + |