[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