From: Mike Stump Date: Wed, 22 Jul 2009 22:56:04 +0000 (+0000) Subject: Improve CFG support for C++ throw expressions. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0979d80615df97c675423de631c1b884819f4712;p=clang Improve CFG support for C++ throw expressions. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76814 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp index 4c2ecb92f6..f43631c4d0 100644 --- a/lib/Analysis/CFG.cpp +++ b/lib/Analysis/CFG.cpp @@ -99,6 +99,7 @@ private: CFGBlock *VisitCompoundStmt(CompoundStmt *C); CFGBlock *VisitConditionalOperator(ConditionalOperator *C); CFGBlock *VisitContinueStmt(ContinueStmt *C); + CFGBlock *VisitCXXThrowExpr(CXXThrowExpr *T); CFGBlock *VisitDeclStmt(DeclStmt *DS); CFGBlock *VisitDeclSubExpr(Decl* D); CFGBlock *VisitDefaultStmt(DefaultStmt *D); @@ -319,6 +320,9 @@ tryAgain: case Stmt::ObjCAtCatchStmtClass: return VisitObjCAtCatchStmt(cast(S)); + case Stmt::CXXThrowExprClass: + return VisitCXXThrowExpr(cast(S)); + case Stmt::ObjCAtSynchronizedStmtClass: return VisitObjCAtSynchronizedStmt(cast(S)); @@ -1262,6 +1266,23 @@ CFGBlock* CFGBuilder::VisitObjCAtThrowStmt(ObjCAtThrowStmt* S) { return VisitStmt(S, true); } +CFGBlock* CFGBuilder::VisitCXXThrowExpr(CXXThrowExpr* T) { + // If we were in the middle of a block we stop processing that block and + // reverse its statements. + if (Block && !FinishBlock(Block)) + return 0; + + // Create the new block. + Block = createBlock(false); + + // The Exit block is the only successor. + Block->addSuccessor(&cfg->getExit()); + + // Add the statement to the block. This may create new blocks if S contains + // control-flow (short-circuit operations). + return VisitStmt(T, true); +} + CFGBlock *CFGBuilder::VisitDoStmt(DoStmt* D) { // See if this is a known constant. bool KnownTrue = false; diff --git a/test/Analysis/dead-stores.cpp b/test/Analysis/dead-stores.cpp new file mode 100644 index 0000000000..ec7aebbc5b --- /dev/null +++ b/test/Analysis/dead-stores.cpp @@ -0,0 +1,21 @@ +// RUN: clang-cc -analyze -warn-dead-stores -verify %s && +// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -analyzer-constraints=basic -warn-dead-stores -verify %s && +// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic-old-cast -analyzer-constraints=basic -warn-dead-stores -verify %s && +// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -analyzer-constraints=range -warn-dead-stores -verify %s && +// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic-old-cast -analyzer-constraints=range -warn-dead-stores -verify %s && +// RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -analyzer-constraints=basic -warn-dead-stores -verify %s && +// RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -analyzer-constraints=range -warn-dead-stores -verify %s + +int j; +void f1() { + int x = 4; + + ++x; // expected-warning{{never read}} + + switch (j) { + case 1: + throw 1; + (void)x; + break; + } +}