summaryrefslogtreecommitdiff
path: root/test/Analysis/cfg.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/Analysis/cfg.cpp')
-rw-r--r--test/Analysis/cfg.cpp256
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>();
+}
+