From 8ab397363b671a35798de8fd7e029c1a5170b4ec Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Sat, 8 Mar 2014 02:22:29 +0000 Subject: [PATCH] Fix CFG bug where the 'isTemporaryDtorsBranch' bit was silently lost for terminators. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@203335 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Analysis/CFG.h | 2 +- lib/Analysis/CFG.cpp | 12 ++++++++++-- test/Analysis/temp-obj-dtors-cfg-output.cpp | 20 ++++++++++---------- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/include/clang/Analysis/CFG.h b/include/clang/Analysis/CFG.h index 56ad6af913..d4e1b8a22d 100644 --- a/include/clang/Analysis/CFG.h +++ b/include/clang/Analysis/CFG.h @@ -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; } diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp index a2fa6216a0..d9be743365 100644 --- a/lib/Analysis/CFG.cpp +++ b/lib/Analysis/CFG.cpp @@ -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(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(getTerminator().getStmt())); + TPrinter.print(getTerminator()); } Stmt *CFGBlock::getTerminatorCondition() { diff --git a/test/Analysis/temp-obj-dtors-cfg-output.cpp b/test/Analysis/temp-obj-dtors-cfg-output.cpp index 328b8d2ff3..9c460ed08d 100644 --- a/test/Analysis/temp-obj-dtors-cfg-output.cpp +++ b/test/Analysis/temp-obj-dtors-cfg-output.cpp @@ -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] -- 2.40.0