summaryrefslogtreecommitdiffstats
path: root/clang/test/Analysis
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2014-01-13 17:59:19 +0000
committerJordan Rose <jordan_rose@apple.com>2014-01-13 17:59:19 +0000
commitc9176072e6aae5a7a1a1b17506fe9c35b3399787 (patch)
treecda6b2b334ed5debc521e3688289a26405731d3d /clang/test/Analysis
parent54f6bd59f57150234f5d99d564c57a5c628e7ed6 (diff)
downloadbcm5719-llvm-c9176072e6aae5a7a1a1b17506fe9c35b3399787.tar.gz
bcm5719-llvm-c9176072e6aae5a7a1a1b17506fe9c35b3399787.zip
[analyzer] Add a CFG node for the allocator call in a C++ 'new' expression.
In an expression like "new (a, b) Foo(x, y)", two things happen: - Memory is allocated by calling a function named 'operator new'. - The memory is initialized using the constructor for 'Foo'. Currently the analyzer only models the second event, though it has special cases for both the default and placement forms of operator new. This patch is the first step towards properly modeling both events: it changes the CFG so that the above expression now generates the following elements. 1. a 2. b 3. (CFGNewAllocator) 4. x 5. y 6. Foo::Foo The analyzer currently ignores the CFGNewAllocator element, but the next step is to treat that as a call like any other. The CFGNewAllocator element is not added to the CFG for analysis-based warnings, since none of them take advantage of it yet. llvm-svn: 199123
Diffstat (limited to 'clang/test/Analysis')
-rw-r--r--clang/test/Analysis/cfg.cpp93
1 files changed, 78 insertions, 15 deletions
diff --git a/clang/test/Analysis/cfg.cpp b/clang/test/Analysis/cfg.cpp
index 9da220e8c32..40bc3138b66 100644
--- a/clang/test/Analysis/cfg.cpp
+++ b/clang/test/Analysis/cfg.cpp
@@ -110,13 +110,14 @@ public:
// 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)]
@@ -130,13 +131,14 @@ void test_deletedtor() {
// 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)]
@@ -308,4 +310,65 @@ int test_enum_with_extension_default(enum MyEnum value) {
default: x = 4; break;
}
return x;
-} \ No newline at end of file
+}
+
+
+// CHECK: [B1 (ENTRY)]
+// CHECK-NEXT: Succs (1): B0
+// CHECK: [B0 (EXIT)]
+// CHECK-NEXT: Preds (1): B1
+// CHECK: [B1 (ENTRY)]
+// CHECK-NEXT: Succs (1): B0
+// CHECK: [B0 (EXIT)]
+// CHECK-NEXT: Preds (1): B1
+// 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: [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];
+}
OpenPOWER on IntegriCloud