Fix CFG bug where the 'isTemporaryDtorsBranch' bit was silently lost for terminators.
authorTed Kremenek <kremenek@apple.com>
Sat, 8 Mar 2014 02:22:29 +0000 (02:22 +0000)
committerTed Kremenek <kremenek@apple.com>
Sat, 8 Mar 2014 02:22:29 +0000 (02:22 +0000)
llvm-svn: 203335

clang/include/clang/Analysis/CFG.h
clang/lib/Analysis/CFG.cpp
clang/test/Analysis/temp-obj-dtors-cfg-output.cpp

index 56ad6af..d4e1b8a 100644 (file)
@@ -615,7 +615,7 @@ public:
 
   // Manipulation of block contents
 
-  void setTerminator(Stmt *Statement) { Terminator = Statement; }
+  void setTerminator(CFGTerminator Term) { Terminator = Term; }
   void setLabel(Stmt *Statement) { Label = Statement; }
   void setLoopTarget(const Stmt *loopTarget) { LoopTarget = loopTarget; }
   void setHasNoReturnElement() { HasNoReturnElement = true; }
index a2fa621..d9be743 100644 (file)
@@ -3405,6 +3405,7 @@ CFGBlock *CFGBuilder::VisitConditionalOperatorForTemporaryDtors(
 
   Block = createBlock(false);
   Block->setTerminator(CFGTerminator(E, true));
+  assert(Block->getTerminator().isTemporaryDtorsBranch());
 
   // See if this is a known constant.
   const TryResult &KnownVal = tryEvaluateBool(E->getCond());
@@ -3766,6 +3767,13 @@ public:
   void VisitExpr(Expr *E) {
     E->printPretty(OS, Helper, Policy);
   }
+
+public:
+  void print(CFGTerminator T) {
+    if (T.isTemporaryDtorsBranch())
+      OS << "(Temp Dtor) ";
+    Visit(T.getStmt());
+  }
 };
 } // end anonymous namespace
 
@@ -3969,7 +3977,7 @@ static void print_block(raw_ostream &OS, const CFG* cfg,
 
     PrintingPolicy PP(Helper.getLangOpts());
     CFGBlockTerminatorPrint TPrinter(OS, &Helper, PP);
-    TPrinter.Visit(const_cast<Stmt*>(B.getTerminator().getStmt()));
+    TPrinter.print(B.getTerminator());
     OS << '\n';
     
     if (ShowColors)
@@ -4107,7 +4115,7 @@ void CFGBlock::print(raw_ostream &OS, const CFG* cfg,
 void CFGBlock::printTerminator(raw_ostream &OS,
                                const LangOptions &LO) const {
   CFGBlockTerminatorPrint TPrinter(OS, NULL, PrintingPolicy(LO));
-  TPrinter.Visit(const_cast<Stmt*>(getTerminator().getStmt()));
+  TPrinter.print(getTerminator());
 }
 
 Stmt *CFGBlock::getTerminatorCondition() {
index 328b8d2..9c460ed 100644 (file)
@@ -261,7 +261,7 @@ void test_noreturn2() {
 // CHECK:   [B3]
 // CHECK:     1: [B5.8] && [B4.5]
 // CHECK:     2: [B5.3]([B3.1])
-// CHECK:     T: [B5.8] && ...
+// CHECK:     T: (Temp Dtor) [B5.8] && ...
 // CHECK:     Preds (2): B4 B5
 // CHECK:     Succs (2): B2 B1
 // CHECK:   [B4]
@@ -291,7 +291,7 @@ void test_noreturn2() {
 // CHECK:   [B7]
 // CHECK:     1: [B9.5] && [B8.5]
 // CHECK:     2: bool a = A() && B();
-// CHECK:     T: [B9.5] && ...
+// CHECK:     T: (Temp Dtor) [B9.5] && ...
 // CHECK:     Preds (2): B8 B9
 // CHECK:     Succs (2): B6 B5
 // CHECK:   [B8]
@@ -327,7 +327,7 @@ void test_noreturn2() {
 // CHECK:   [B3]
 // CHECK:     1: [B5.8] || [B4.5]
 // CHECK:     2: [B5.3]([B3.1])
-// CHECK:     T: [B5.8] || ...
+// CHECK:     T: (Temp Dtor) [B5.8] || ...
 // CHECK:     Preds (2): B4 B5
 // CHECK:     Succs (2): B1 B2
 // CHECK:   [B4]
@@ -357,7 +357,7 @@ void test_noreturn2() {
 // CHECK:   [B7]
 // CHECK:     1: [B9.5] || [B8.5]
 // CHECK:     2: bool a = A() || B();
-// CHECK:     T: [B9.5] || ...
+// CHECK:     T: (Temp Dtor) [B9.5] || ...
 // CHECK:     Preds (2): B8 B9
 // CHECK:     Succs (2): B5 B6
 // CHECK:   [B8]
@@ -429,7 +429,7 @@ void test_noreturn2() {
 // CHECK:     3: [B7.2]
 // CHECK:     4: [B7.3] (CXXConstructExpr, class A)
 // CHECK:     5: A a = B() ? A() : A(B());
-// CHECK:     T: [B10.5] ? ... : ...
+// CHECK:     T: (Temp Dtor) [B10.5] ? ... : ...
 // CHECK:     Preds (2): B8 B9
 // CHECK:     Succs (2): B5 B6
 // CHECK:   [B8]
@@ -495,7 +495,7 @@ void test_noreturn2() {
 // CHECK:     2: [B4.1] (ImplicitCastExpr, NoOp, const class A)
 // CHECK:     3: [B4.2]
 // CHECK:     4: [B7.3]([B4.3])
-// CHECK:     T: [B7.8] ? ... : ...
+// CHECK:     T: (Temp Dtor) [B7.8] ? ... : ...
 // CHECK:     Preds (2): B5 B6
 // CHECK:     Succs (2): B2 B3
 // CHECK:   [B5]
@@ -552,7 +552,7 @@ void test_noreturn2() {
 // CHECK:     2: [B10.1] (ImplicitCastExpr, NoOp, const class A)
 // CHECK:     3: [B10.2]
 // CHECK:     4: const A &a = B() ? A() : A(B());
-// CHECK:     T: [B13.5] ? ... : ...
+// CHECK:     T: (Temp Dtor) [B13.5] ? ... : ...
 // CHECK:     Preds (2): B11 B12
 // CHECK:     Succs (2): B8 B9
 // CHECK:   [B11]
@@ -616,7 +616,7 @@ void test_noreturn2() {
 // CHECK:     3: [B4.2]
 // CHECK:     4: [B4.3] (CXXConstructExpr, class A)
 // CHECK:     5: A a = A() ?: A();
-// CHECK:     T: [B7.5] ? ... : ...
+// CHECK:     T: (Temp Dtor) [B7.5] ? ... : ...
 // CHECK:     Preds (2): B5 B6
 // CHECK:     Succs (2): B2 B3
 // CHECK:   [B5]
@@ -668,7 +668,7 @@ void test_noreturn2() {
 // CHECK:     2: [B4.1] (ImplicitCastExpr, NoOp, const class A)
 // CHECK:     3: [B4.2]
 // CHECK:     4: [B7.3]([B4.3])
-// CHECK:     T: [B7.8] ? ... : ...
+// CHECK:     T: (Temp Dtor) [B7.8] ? ... : ...
 // CHECK:     Preds (2): B5 B6
 // CHECK:     Succs (2): B2 B3
 // CHECK:   [B5]
@@ -708,7 +708,7 @@ void test_noreturn2() {
 // CHECK:     2: [B9.1] (ImplicitCastExpr, NoOp, const class A)
 // CHECK:     3: [B9.2]
 // CHECK:     4: const A &a = A() ?: A();
-// CHECK:     T: [B12.5] ? ... : ...
+// CHECK:     T: (Temp Dtor) [B12.5] ? ... : ...
 // CHECK:     Preds (2): B10 B11
 // CHECK:     Succs (2): B7 B8
 // CHECK:   [B10]