[cfe-commits] r115493 - in /cfe/trunk: include/clang/Analysis/CFG.h lib/Analysis/CFG.cpp test/Analysis/initializers-cfg-output.cpp
Marcin Swiderski
marcin.sfider at gmail.com
Sun Oct 3 20:38:22 PDT 2010
Author: sfider
Date: Sun Oct 3 22:38:22 2010
New Revision: 115493
URL: http://llvm.org/viewvc/llvm-project?rev=115493&view=rev
Log:
Added support for C++ initializers in CFG.
Added:
cfe/trunk/test/Analysis/initializers-cfg-output.cpp
Modified:
cfe/trunk/include/clang/Analysis/CFG.h
cfe/trunk/lib/Analysis/CFG.cpp
Modified: cfe/trunk/include/clang/Analysis/CFG.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/CFG.h?rev=115493&r1=115492&r2=115493&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/CFG.h (original)
+++ cfe/trunk/include/clang/Analysis/CFG.h Sun Oct 3 22:38:22 2010
@@ -432,7 +432,11 @@
void appendStmt(Stmt* Statement, BumpVectorContext &C, bool asLValue) {
Elements.push_back(CFGStmt(Statement, asLValue), C);
}
-
+
+ void appendInitializer(CXXBaseOrMemberInitializer *I, BumpVectorContext& C) {
+ Elements.push_back(CFGInitializer(I), C);
+ }
+
// Destructors must be inserted in reversed order. So insertion is in two
// steps. First we prepare space for some number of elements, then we insert
// the elements beginning at the last position in prepared space.
Modified: cfe/trunk/lib/Analysis/CFG.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFG.cpp?rev=115493&r1=115492&r2=115493&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/CFG.cpp (original)
+++ cfe/trunk/lib/Analysis/CFG.cpp Sun Oct 3 22:38:22 2010
@@ -304,7 +304,7 @@
CFGBlock *addStmt(Stmt *S) {
return Visit(S, AddStmtChoice::AlwaysAdd);
}
-
+ CFGBlock *addInitializer(CXXBaseOrMemberInitializer *I);
void addAutomaticObjDtors(LocalScope::const_iterator B,
LocalScope::const_iterator E, Stmt* S);
@@ -322,6 +322,9 @@
AddStmtChoice asc = AddStmtChoice::AlwaysAdd) {
B->appendStmt(S, cfg->getBumpVectorContext(), asc.asLValue());
}
+ void appendInitializer(CFGBlock *B, CXXBaseOrMemberInitializer *I) {
+ B->appendInitializer(I, cfg->getBumpVectorContext());
+ }
void insertAutomaticObjDtors(CFGBlock* Blk, CFGBlock::iterator I,
LocalScope::const_iterator B, LocalScope::const_iterator E, Stmt* S);
@@ -410,14 +413,19 @@
if (badCFG)
return NULL;
- if (B)
- Succ = B;
-
+ // For C++ constructor add initializers to CFG.
if (const CXXConstructorDecl *CD = dyn_cast_or_null<CXXConstructorDecl>(D)) {
- // FIXME: Add code for base initializers and member initializers.
- (void)CD;
+ for (CXXConstructorDecl::init_const_reverse_iterator I = CD->init_rbegin(),
+ E = CD->init_rend(); I != E; ++I) {
+ B = addInitializer(*I);
+ if (badCFG)
+ return NULL;
+ }
}
+ if (B)
+ Succ = B;
+
// Backpatch the gotos whose label -> block mappings we didn't know when we
// encountered them.
for (BackpatchBlocksTy::iterator I = BackpatchBlocks.begin(),
@@ -466,6 +474,26 @@
return B;
}
+/// addInitializer - Add C++ base or member initializer element to CFG.
+CFGBlock *CFGBuilder::addInitializer(CXXBaseOrMemberInitializer *I) {
+ if (!BuildOpts.AddInitializers)
+ return Block;
+
+ autoCreateBlock();
+ appendInitializer(Block, I);
+
+ if (Expr *Init = I->getInit()) {
+ AddStmtChoice::Kind K = AddStmtChoice::NotAlwaysAdd;
+ if (FieldDecl *FD = I->getMember())
+ if (FD->getType()->isReferenceType())
+ K = AddStmtChoice::AsLValueNotAlwaysAdd;
+
+ return Visit(Init, AddStmtChoice(K));
+ }
+
+ return Block;
+}
+
/// addAutomaticObjDtors - Add to current block automatic objects destructors
/// for objects in range of local scope positions. Use S as trigger statement
/// for destructors.
Added: cfe/trunk/test/Analysis/initializers-cfg-output.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/initializers-cfg-output.cpp?rev=115493&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/initializers-cfg-output.cpp (added)
+++ cfe/trunk/test/Analysis/initializers-cfg-output.cpp Sun Oct 3 22:38:22 2010
@@ -0,0 +1,89 @@
+// RUN: %clang_cc1 -analyze -cfg-dump -cfg-add-initializers %s 2>&1 | FileCheck %s
+// XPASS: *
+
+class A {
+public:
+ A() {}
+ A(int i) {}
+};
+
+class B : public virtual A {
+public:
+ B() {}
+ B(int i) : A(i) {}
+};
+
+class C : public virtual A {
+public:
+ C() {}
+ C(int i) : A(i) {}
+};
+
+class TestOrder : public C, public B, public A {
+ int i;
+ int& r;
+public:
+ TestOrder();
+};
+
+TestOrder::TestOrder()
+ : r(i), B(), i(), C() {
+ A a;
+}
+
+class TestControlFlow {
+ int x, y, z;
+public:
+ TestControlFlow(bool b);
+};
+
+TestControlFlow::TestControlFlow(bool b)
+ : y(b ? 0 : 1)
+ , x(0)
+ , z(y) {
+ int v;
+}
+
+// CHECK: [ B2 (ENTRY) ]
+// CHECK: Predecessors (0):
+// CHECK: Successors (1): B1
+// CHECK: [ B1 ]
+// CHECK: 1: A() (Base initializer)
+// CHECK: 2: C() (Base initializer)
+// CHECK: 3: B() (Base initializer)
+// CHECK: 4: A() (Base initializer)
+// CHECK: 5: i(/*implicit*/int()) (Member initializer)
+// CHECK: 6: r(this->i) (Member initializer)
+// CHECK: 7: A a;
+// CHECK: Predecessors (1): B2
+// CHECK: Successors (1): B0
+// CHECK: [ B0 (EXIT) ]
+// CHECK: Predecessors (1): B1
+// CHECK: Successors (0):
+// CHECK: [ B5 (ENTRY) ]
+// CHECK: Predecessors (0):
+// CHECK: Successors (1): B4
+// CHECK: [ B1 ]
+// CHECK: 1: [B4.2] ? [B2.1] : [B3.1]
+// CHECK: 2: y([B1.1]) (Member initializer)
+// CHECK: 3: z(this->y) (Member initializer)
+// CHECK: 4: int v;
+// CHECK: Predecessors (2): B2 B3
+// CHECK: Successors (1): B0
+// CHECK: [ B2 ]
+// CHECK: 1: 0
+// CHECK: Predecessors (1): B4
+// CHECK: Successors (1): B1
+// CHECK: [ B3 ]
+// CHECK: 1: 1
+// CHECK: Predecessors (1): B4
+// CHECK: Successors (1): B1
+// CHECK: [ B4 ]
+// CHECK: 1: x(0) (Member initializer)
+// CHECK: 2: b
+// CHECK: T: [B4.2] ? ... : ...
+// CHECK: Predecessors (1): B5
+// CHECK: Successors (2): B2 B3
+// CHECK: [ B0 (EXIT) ]
+// CHECK: Predecessors (1): B1
+// CHECK: Successors (0):
More information about the cfe-commits
mailing list