summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2011-04-04 23:29:12 +0000
committerTed Kremenek <kremenek@apple.com>2011-04-04 23:29:12 +0000
commit378819342eb448477a8666ad96adbe67408f4705 (patch)
tree611438b3c2bfa11fb1e013ea4ac31c55802c86d0 /clang
parent44927690c3a460ee5f5499998255947161e9ca4f (diff)
downloadbcm5719-llvm-378819342eb448477a8666ad96adbe67408f4705.tar.gz
bcm5719-llvm-378819342eb448477a8666ad96adbe67408f4705.zip
Fix PR 9626 (duplicated self-init warnings under -Wuninitialized) with numerous CFG and UninitializedValues analysis changes:
1) Change the CFG to include the DeclStmt for conditional variables, instead of using the condition itself as a faux DeclStmt. 2) Update ExprEngine (the static analyzer) to understand (1), so not to regress. 3) Update UninitializedValues.cpp to initialize all tracked variables to Uninitialized at the start of the function/method. 4) Only use the SelfReferenceChecker (SemaDecl.cpp) on global variables, leaving the dataflow analysis to handle other cases. The combination of (1) and (3) allows the dataflow-based -Wuninitialized to find self-init problems when the initializer contained control-flow. llvm-svn: 128858
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/AST/Stmt.h24
-rw-r--r--clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h5
-rw-r--r--clang/lib/Analysis/CFG.cpp12
-rw-r--r--clang/lib/Analysis/UninitializedValues.cpp19
-rw-r--r--clang/lib/Sema/AnalysisBasedWarnings.cpp30
-rw-r--r--clang/lib/Sema/SemaDecl.cpp11
-rw-r--r--clang/lib/StaticAnalyzer/Core/ExprEngine.cpp55
-rw-r--r--clang/test/Analysis/auto-obj-dtors-cfg-output.cpp148
-rw-r--r--clang/test/Sema/uninit-variables.c2
-rw-r--r--clang/test/SemaCXX/uninitialized.cpp2
10 files changed, 145 insertions, 163 deletions
diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h
index 6428594c8e8..97dbce045f9 100644
--- a/clang/include/clang/AST/Stmt.h
+++ b/clang/include/clang/AST/Stmt.h
@@ -691,6 +691,12 @@ public:
VarDecl *getConditionVariable() const;
void setConditionVariable(ASTContext &C, VarDecl *V);
+ /// If this IfStmt has a condition variable, return the faux DeclStmt
+ /// associated with the creation of that condition variable.
+ const DeclStmt *getConditionVariableDeclStmt() const {
+ return reinterpret_cast<DeclStmt*>(SubExprs[VAR]);
+ }
+
const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); }
const Stmt *getThen() const { return SubExprs[THEN]; }
@@ -757,6 +763,12 @@ public:
/// \endcode
VarDecl *getConditionVariable() const;
void setConditionVariable(ASTContext &C, VarDecl *V);
+
+ /// If this SwitchStmt has a condition variable, return the faux DeclStmt
+ /// associated with the creation of that condition variable.
+ const DeclStmt *getConditionVariableDeclStmt() const {
+ return reinterpret_cast<DeclStmt*>(SubExprs[VAR]);
+ }
const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
const Stmt *getBody() const { return SubExprs[BODY]; }
@@ -838,6 +850,12 @@ public:
VarDecl *getConditionVariable() const;
void setConditionVariable(ASTContext &C, VarDecl *V);
+ /// If this WhileStmt has a condition variable, return the faux DeclStmt
+ /// associated with the creation of that condition variable.
+ const DeclStmt *getConditionVariableDeclStmt() const {
+ return reinterpret_cast<DeclStmt*>(SubExprs[VAR]);
+ }
+
Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
@@ -942,6 +960,12 @@ public:
VarDecl *getConditionVariable() const;
void setConditionVariable(ASTContext &C, VarDecl *V);
+ /// If this ForStmt has a condition variable, return the faux DeclStmt
+ /// associated with the creation of that condition variable.
+ const DeclStmt *getConditionVariableDeclStmt() const {
+ return reinterpret_cast<DeclStmt*>(SubExprs[CONDVAR]);
+ }
+
Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
Expr *getInc() { return reinterpret_cast<Expr*>(SubExprs[INC]); }
Stmt *getBody() { return SubExprs[BODY]; }
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
index ab8e4bcdde6..8cd743f68f5 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
@@ -284,11 +284,6 @@ public:
/// VisitGuardedExpr - Transfer function logic for ?, __builtin_choose
void VisitGuardedExpr(const Expr* Ex, const Expr* L, const Expr* R,
ExplodedNode* Pred, ExplodedNodeSet& Dst);
-
- /// VisitCondInit - Transfer function for handling the initialization
- /// of a condition variable in an IfStmt, SwitchStmt, etc.
- void VisitCondInit(const VarDecl *VD, const Stmt *S, ExplodedNode *Pred,
- ExplodedNodeSet& Dst);
void VisitInitListExpr(const InitListExpr* E, ExplodedNode* Pred,
ExplodedNodeSet& Dst);
diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp
index e91de0366c6..b5930cdccf4 100644
--- a/clang/lib/Analysis/CFG.cpp
+++ b/clang/lib/Analysis/CFG.cpp
@@ -393,11 +393,11 @@ private:
void addLocalScopeAndDtors(Stmt* S);
// Interface to CFGBlock - adding CFGElements.
- void appendStmt(CFGBlock *B, Stmt *S) {
+ void appendStmt(CFGBlock *B, const Stmt *S) {
if (alwaysAdd(S))
cachedEntry->second = B;
- B->appendStmt(S, cfg->getBumpVectorContext());
+ B->appendStmt(const_cast<Stmt*>(S), cfg->getBumpVectorContext());
}
void appendInitializer(CFGBlock *B, CXXCtorInitializer *I) {
B->appendInitializer(I, cfg->getBumpVectorContext());
@@ -1495,7 +1495,7 @@ CFGBlock* CFGBuilder::VisitIfStmt(IfStmt* I) {
if (VarDecl *VD = I->getConditionVariable()) {
if (Expr *Init = VD->getInit()) {
autoCreateBlock();
- appendStmt(Block, I);
+ appendStmt(Block, I->getConditionVariableDeclStmt());
addStmt(Init);
}
}
@@ -1633,7 +1633,7 @@ CFGBlock* CFGBuilder::VisitForStmt(ForStmt* F) {
if (VarDecl *VD = F->getConditionVariable()) {
if (Expr *Init = VD->getInit()) {
autoCreateBlock();
- appendStmt(Block, F);
+ appendStmt(Block, F->getConditionVariableDeclStmt());
EntryConditionBlock = addStmt(Init);
assert(Block == EntryConditionBlock);
}
@@ -1917,7 +1917,7 @@ CFGBlock* CFGBuilder::VisitWhileStmt(WhileStmt* W) {
if (VarDecl *VD = W->getConditionVariable()) {
if (Expr *Init = VD->getInit()) {
autoCreateBlock();
- appendStmt(Block, W);
+ appendStmt(Block, W->getConditionVariableDeclStmt());
EntryConditionBlock = addStmt(Init);
assert(Block == EntryConditionBlock);
}
@@ -2279,7 +2279,7 @@ CFGBlock* CFGBuilder::VisitSwitchStmt(SwitchStmt* Terminator) {
if (VarDecl *VD = Terminator->getConditionVariable()) {
if (Expr *Init = VD->getInit()) {
autoCreateBlock();
- appendStmt(Block, Terminator);
+ appendStmt(Block, Terminator->getConditionVariableDeclStmt());
addStmt(Init);
}
}
diff --git a/clang/lib/Analysis/UninitializedValues.cpp b/clang/lib/Analysis/UninitializedValues.cpp
index f775cc5b500..3dde41f2272 100644
--- a/clang/lib/Analysis/UninitializedValues.cpp
+++ b/clang/lib/Analysis/UninitializedValues.cpp
@@ -138,6 +138,8 @@ public:
CFGBlockValues(const CFG &cfg);
~CFGBlockValues();
+ unsigned getNumEntries() const { return declToIndex.size(); }
+
void computeSetOfDeclarations(const DeclContext &dc);
ValueVector &getValueVector(const CFGBlock *block,
const CFGBlock *dstBlock);
@@ -470,7 +472,6 @@ void TransferFunctions::VisitDeclStmt(DeclStmt *ds) {
DI != DE; ++DI) {
if (VarDecl *vd = dyn_cast<VarDecl>(*DI)) {
if (isTrackedVar(vd)) {
- vals[vd] = Uninitialized;
if (Stmt *init = vd->getInit()) {
Visit(init);
vals[vd] = Initialized;
@@ -669,9 +670,23 @@ void clang::runUninitializedVariablesAnalysis(const DeclContext &dc,
vals.computeSetOfDeclarations(dc);
if (vals.hasNoDeclarations())
return;
+
+ // Mark all variables uninitialized at the entry.
+ const CFGBlock &entry = cfg.getEntry();
+ for (CFGBlock::const_succ_iterator i = entry.succ_begin(),
+ e = entry.succ_end(); i != e; ++i) {
+ if (const CFGBlock *succ = *i) {
+ ValueVector &vec = vals.getValueVector(&entry, succ);
+ const unsigned n = vals.getNumEntries();
+ for (unsigned j = 0; j < n ; ++j) {
+ vec[j] = Uninitialized;
+ }
+ }
+ }
+
+ // Proceed with the workist.
DataflowWorklist worklist(cfg);
llvm::BitVector previouslyVisited(cfg.getNumBlockIDs());
-
worklist.enqueueSuccessors(&cfg.getEntry());
llvm::BitVector wasAnalyzed(cfg.getNumBlockIDs(), false);
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index 3467dae4ba6..ecfa8213584 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -470,14 +470,25 @@ public:
for (UsesVec::iterator vi = vec->begin(), ve = vec->end(); vi != ve; ++vi)
{
const bool isAlwaysUninit = vi->second;
+ bool showDefinition = true;
+
if (const DeclRefExpr *dr = dyn_cast<DeclRefExpr>(vi->first)) {
- S.Diag(dr->getLocStart(),
- isAlwaysUninit ?
- (isSelfInit(S.Context, vd, dr)
- ? diag::warn_uninit_self_reference_in_init
- : diag::warn_uninit_var)
- : diag::warn_maybe_uninit_var)
- << vd->getDeclName() << dr->getSourceRange();
+ if (isAlwaysUninit) {
+ if (isSelfInit(S.Context, vd, dr)) {
+ S.Diag(dr->getLocStart(),
+ diag::warn_uninit_self_reference_in_init)
+ << vd->getDeclName() << vd->getLocation() << dr->getSourceRange();
+ showDefinition = false;
+ }
+ else {
+ S.Diag(dr->getLocStart(), diag::warn_uninit_var)
+ << vd->getDeclName() << dr->getSourceRange();
+ }
+ }
+ else {
+ S.Diag(dr->getLocStart(), diag::warn_maybe_uninit_var)
+ << vd->getDeclName() << dr->getSourceRange();
+ }
}
else {
const BlockExpr *be = cast<BlockExpr>(vi->first);
@@ -488,8 +499,9 @@ public:
}
// Report where the variable was declared.
- S.Diag(vd->getLocStart(), diag::note_uninit_var_def)
- << vd->getDeclName();
+ if (showDefinition)
+ S.Diag(vd->getLocStart(), diag::note_uninit_var_def)
+ << vd->getDeclName();
// Only report the fixit once.
if (fixitIssued)
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index e52082bbbfc..8bf6c84c0b3 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -4715,7 +4715,16 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
if (RealDecl == 0 || RealDecl->isInvalidDecl())
return;
- SelfReferenceChecker(*this, RealDecl).VisitExpr(Init);
+ // Check for self-references within variable initializers.
+ if (VarDecl *vd = dyn_cast<VarDecl>(RealDecl)) {
+ // Variables declared within a function/method body are handled
+ // by a dataflow analysis.
+ if (!vd->hasLocalStorage() && !vd->isStaticLocal())
+ SelfReferenceChecker(*this, RealDecl).VisitExpr(Init);
+ }
+ else {
+ SelfReferenceChecker(*this, RealDecl).VisitExpr(Init);
+ }
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(RealDecl)) {
// With declarators parsed the way they are, the parser cannot
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 3826a122260..a422428b1bf 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -459,11 +459,15 @@ void ExprEngine::Visit(const Stmt* S, ExplodedNode* Pred,
case Stmt::ContinueStmtClass:
case Stmt::DefaultStmtClass:
case Stmt::DoStmtClass:
+ case Stmt::ForStmtClass:
case Stmt::GotoStmtClass:
+ case Stmt::IfStmtClass:
case Stmt::IndirectGotoStmtClass:
case Stmt::LabelStmtClass:
case Stmt::NoStmtClass:
case Stmt::NullStmtClass:
+ case Stmt::SwitchStmtClass:
+ case Stmt::WhileStmtClass:
llvm_unreachable("Stmt should not be in analyzer evaluation loop");
break;
@@ -620,12 +624,6 @@ void ExprEngine::Visit(const Stmt* S, ExplodedNode* Pred,
VisitDeclStmt(cast<DeclStmt>(S), Pred, Dst);
break;
- case Stmt::ForStmtClass:
- // This case isn't for branch processing, but for handling the
- // initialization of a condition variable.
- VisitCondInit(cast<ForStmt>(S)->getConditionVariable(), S, Pred, Dst);
- break;
-
case Stmt::ImplicitCastExprClass:
case Stmt::CStyleCastExprClass:
case Stmt::CXXStaticCastExprClass:
@@ -638,12 +636,6 @@ void ExprEngine::Visit(const Stmt* S, ExplodedNode* Pred,
break;
}
- case Stmt::IfStmtClass:
- // This case isn't for branch processing, but for handling the
- // initialization of a condition variable.
- VisitCondInit(cast<IfStmt>(S)->getConditionVariable(), S, Pred, Dst);
- break;
-
case Stmt::InitListExprClass:
VisitInitListExpr(cast<InitListExpr>(S), Pred, Dst);
break;
@@ -713,12 +705,6 @@ void ExprEngine::Visit(const Stmt* S, ExplodedNode* Pred,
return;
}
- case Stmt::SwitchStmtClass:
- // This case isn't for branch processing, but for handling the
- // initialization of a condition variable.
- VisitCondInit(cast<SwitchStmt>(S)->getConditionVariable(), S, Pred, Dst);
- break;
-
case Stmt::UnaryOperatorClass: {
const UnaryOperator *U = cast<UnaryOperator>(S);
if (AMgr.shouldEagerlyAssume()&&(U->getOpcode() == UO_LNot)) {
@@ -730,12 +716,6 @@ void ExprEngine::Visit(const Stmt* S, ExplodedNode* Pred,
VisitUnaryOperator(U, Pred, Dst);
break;
}
-
- case Stmt::WhileStmtClass:
- // This case isn't for branch processing, but for handling the
- // initialization of a condition variable.
- VisitCondInit(cast<WhileStmt>(S)->getConditionVariable(), S, Pred, Dst);
- break;
}
}
@@ -2308,33 +2288,6 @@ void ExprEngine::VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred,
}
}
-void ExprEngine::VisitCondInit(const VarDecl *VD, const Stmt *S,
- ExplodedNode *Pred, ExplodedNodeSet& Dst) {
-
- const Expr* InitEx = VD->getInit();
- ExplodedNodeSet Tmp;
- Visit(InitEx, Pred, Tmp);
-
- for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
- ExplodedNode *N = *I;
- const GRState *state = GetState(N);
-
- const LocationContext *LC = N->getLocationContext();
- SVal InitVal = state->getSVal(InitEx);
-
- // Recover some path-sensitivity if a scalar value evaluated to
- // UnknownVal.
- if (InitVal.isUnknown() ||
- !getConstraintManager().canReasonAbout(InitVal)) {
- InitVal = svalBuilder.getConjuredSymbolVal(NULL, InitEx,
- Builder->getCurrentBlockCount());
- }
-
- evalBind(Dst, S, N, state,
- loc::MemRegionVal(state->getRegion(VD, LC)), InitVal, true);
- }
-}
-
namespace {
// This class is used by VisitInitListExpr as an item in a worklist
// for processing the values contained in an InitListExpr.
diff --git a/clang/test/Analysis/auto-obj-dtors-cfg-output.cpp b/clang/test/Analysis/auto-obj-dtors-cfg-output.cpp
index 6dccf9f846e..c877061eb6a 100644
--- a/clang/test/Analysis/auto-obj-dtors-cfg-output.cpp
+++ b/clang/test/Analysis/auto-obj-dtors-cfg-output.cpp
@@ -159,7 +159,7 @@ void test_catch_copy() {
// CHECK: Predecessors (0):
// CHECK: Successors (1): B1
// CHECK: [ B1 ]
-// CHECK: 1:
+// CHECK: 1:
// CHECK: 2: A a;
// CHECK: 3: const A &b = a;
// CHECK: 4: A()
@@ -175,9 +175,9 @@ void test_catch_copy() {
// CHECK: Predecessors (0):
// CHECK: Successors (1): B1
// CHECK: [ B1 ]
-// CHECK: 1:
+// CHECK: 1:
// CHECK: 2: A a[2];
-// CHECK: 3:
+// CHECK: 3:
// CHECK: 4: A b[0];
// CHECK: 5: [B1.2].~A() (Implicit destructor)
// CHECK: Predecessors (1): B2
@@ -189,15 +189,15 @@ void test_catch_copy() {
// CHECK: Predecessors (0):
// CHECK: Successors (1): B1
// CHECK: [ B1 ]
-// CHECK: 1:
+// CHECK: 1:
// CHECK: 2: A a;
-// CHECK: 3:
+// CHECK: 3:
// CHECK: 4: A c;
-// CHECK: 5:
+// CHECK: 5:
// CHECK: 6: A d;
// CHECK: 7: [B1.6].~A() (Implicit destructor)
// CHECK: 8: [B1.4].~A() (Implicit destructor)
-// CHECK: 9:
+// CHECK: 9:
// CHECK: 10: A b;
// CHECK: 11: [B1.10].~A() (Implicit destructor)
// CHECK: 12: [B1.2].~A() (Implicit destructor)
@@ -210,7 +210,7 @@ void test_catch_copy() {
// CHECK: Predecessors (0):
// CHECK: Successors (1): B3
// CHECK: [ B1 ]
-// CHECK: 1:
+// CHECK: 1:
// CHECK: 2: A c;
// CHECK: 3: [B1.2].~A() (Implicit destructor)
// CHECK: 4: [B3.4].~A() (Implicit destructor)
@@ -224,9 +224,9 @@ void test_catch_copy() {
// CHECK: Predecessors (1): B3
// CHECK: Successors (1): B0
// CHECK: [ B3 ]
-// CHECK: 1:
+// CHECK: 1:
// CHECK: 2: A a;
-// CHECK: 3:
+// CHECK: 3:
// CHECK: 4: A b;
// CHECK: 5: UV
// CHECK: T: if [B3.5]
@@ -240,7 +240,7 @@ void test_catch_copy() {
// CHECK: Successors (1): B7
// CHECK: [ B1 ]
// CHECK: l1:
-// CHECK: 1:
+// CHECK: 1:
// CHECK: 2: A c;
// CHECK: 3: [B1.2].~A() (Implicit destructor)
// CHECK: 4: [B6.2].~A() (Implicit destructor)
@@ -248,7 +248,7 @@ void test_catch_copy() {
// CHECK: Predecessors (2): B2 B3
// CHECK: Successors (1): B0
// CHECK: [ B2 ]
-// CHECK: 1:
+// CHECK: 1:
// CHECK: 2: A b;
// CHECK: 3: [B2.2].~A() (Implicit destructor)
// CHECK: 4: [B6.4].~A() (Implicit destructor)
@@ -272,16 +272,16 @@ void test_catch_copy() {
// CHECK: Successors (1): B6
// CHECK: [ B6 ]
// CHECK: l0:
-// CHECK: 1:
+// CHECK: 1:
// CHECK: 2: A b;
-// CHECK: 3:
+// CHECK: 3:
// CHECK: 4: A a;
// CHECK: 5: UV
// CHECK: T: if [B6.5]
// CHECK: Predecessors (2): B7 B5
// CHECK: Successors (2): B5 B4
// CHECK: [ B7 ]
-// CHECK: 1:
+// CHECK: 1:
// CHECK: 2: A a;
// CHECK: Predecessors (1): B8
// CHECK: Successors (1): B6
@@ -297,24 +297,23 @@ void test_catch_copy() {
// CHECK: Predecessors (2): B2 B3
// CHECK: Successors (1): B0
// CHECK: [ B2 ]
-// CHECK: 1:
+// CHECK: 1:
// CHECK: 2: A c;
// CHECK: 3: [B2.2].~A() (Implicit destructor)
// CHECK: Predecessors (1): B4
// CHECK: Successors (1): B1
// CHECK: [ B3 ]
-// CHECK: 1:
+// CHECK: 1:
// CHECK: 2: A c;
// CHECK: 3: [B3.2].~A() (Implicit destructor)
// CHECK: Predecessors (1): B4
// CHECK: Successors (1): B1
// CHECK: [ B4 ]
-// CHECK: 1:
+// CHECK: 1:
// CHECK: 2: A a;
// CHECK: 3: a
-// CHECK: 4: if ([B4.6])
-// CHECK:[B3.2]else
-// CHECK:[B2.2] 5: b.operator int()
+// CHECK: 4: A b = a;
+// CHECK: 5: b.operator int()
// CHECK: 6: [B4.5]
// CHECK: T: if [B4.6]
// CHECK: Predecessors (1): B5
@@ -327,14 +326,14 @@ void test_catch_copy() {
// CHECK: Successors (1): B8
// CHECK: [ B1 ]
// CHECK: 1: [B8.4].~A() (Implicit destructor)
-// CHECK: 2:
+// CHECK: 2:
// CHECK: 3: A e;
// CHECK: 4: [B1.3].~A() (Implicit destructor)
// CHECK: 5: [B8.2].~A() (Implicit destructor)
// CHECK: Predecessors (2): B2 B5
// CHECK: Successors (1): B0
// CHECK: [ B2 ]
-// CHECK: 1:
+// CHECK: 1:
// CHECK: 2: A d;
// CHECK: 3: [B2.2].~A() (Implicit destructor)
// CHECK: 4: [B4.2].~A() (Implicit destructor)
@@ -348,14 +347,14 @@ void test_catch_copy() {
// CHECK: Predecessors (1): B4
// CHECK: Successors (1): B0
// CHECK: [ B4 ]
-// CHECK: 1:
+// CHECK: 1:
// CHECK: 2: A c;
// CHECK: 3: UV
// CHECK: T: if [B4.3]
// CHECK: Predecessors (1): B8
// CHECK: Successors (2): B3 B2
// CHECK: [ B5 ]
-// CHECK: 1:
+// CHECK: 1:
// CHECK: 2: A d;
// CHECK: 3: [B5.2].~A() (Implicit destructor)
// CHECK: 4: [B7.2].~A() (Implicit destructor)
@@ -369,21 +368,17 @@ void test_catch_copy() {
// CHECK: Predecessors (1): B7
// CHECK: Successors (1): B0
// CHECK: [ B7 ]
-// CHECK: 1:
+// CHECK: 1:
// CHECK: 2: A c;
// CHECK: 3: UV
// CHECK: T: if [B7.3]
// CHECK: Predecessors (1): B8
// CHECK: Successors (2): B6 B5
// CHECK: [ B8 ]
-// CHECK: 1:
+// CHECK: 1:
// CHECK: 2: A a;
// CHECK: 3: a
-// CHECK: 4: if ([B8.6]) {
-// CHECK:[B7.2] if ([B7.3])
-// CHECK:[B6.1][B5.2]} else {
-// CHECK:[B4.2] if ([B4.3])
-// CHECK:[B3.1][B2.2]}
+// CHECK: 4: A b = a;
// CHECK: 5: b.operator int()
// CHECK: 6: [B8.5]
// CHECK: T: if [B8.6]
@@ -402,8 +397,8 @@ void test_catch_copy() {
// CHECK: Successors (1): B0
// CHECK: [ B2 ]
// CHECK: 1: a
-// CHECK: 2: while ([B2.4])
-// CHECK:[B4.2] 3: b.operator int()
+// CHECK: 2: A b = a;
+// CHECK: 3: b.operator int()
// CHECK: 4: [B2.3]
// CHECK: T: while [B2.4]
// CHECK: Predecessors (2): B3 B5
@@ -412,14 +407,14 @@ void test_catch_copy() {
// CHECK: Predecessors (1): B4
// CHECK: Successors (1): B2
// CHECK: [ B4 ]
-// CHECK: 1:
+// CHECK: 1:
// CHECK: 2: A c;
// CHECK: 3: [B4.2].~A() (Implicit destructor)
// CHECK: 4: [B2.2].~A() (Implicit destructor)
// CHECK: Predecessors (1): B2
// CHECK: Successors (1): B3
// CHECK: [ B5 ]
-// CHECK: 1:
+// CHECK: 1:
// CHECK: 2: A a;
// CHECK: Predecessors (1): B6
// CHECK: Successors (1): B2
@@ -431,7 +426,7 @@ void test_catch_copy() {
// CHECK: Successors (1): B11
// CHECK: [ B1 ]
// CHECK: 1: [B2.2].~A() (Implicit destructor)
-// CHECK: 2:
+// CHECK: 2:
// CHECK: 3: A e;
// CHECK: 4: [B1.3].~A() (Implicit destructor)
// CHECK: 5: [B11.2].~A() (Implicit destructor)
@@ -439,14 +434,7 @@ void test_catch_copy() {
// CHECK: Successors (1): B0
// CHECK: [ B2 ]
// CHECK: 1: a
-// CHECK: 2: while ([B2.4])
-// CHECK: {
-// CHECK:[B10.2] if ([B10.3])
-// CHECK: break;
-// CHECK: if ([B8.1])
-// CHECK: continue;
-// CHECK: if ([B6.1])
-// CHECK:[B5.1][B4.2] }
+// CHECK: 2: A b = a;
// CHECK: 3: b.operator int()
// CHECK: 4: [B2.3]
// CHECK: T: while [B2.4]
@@ -456,7 +444,7 @@ void test_catch_copy() {
// CHECK: Predecessors (2): B4 B7
// CHECK: Successors (1): B2
// CHECK: [ B4 ]
-// CHECK: 1:
+// CHECK: 1:
// CHECK: 2: A d;
// CHECK: 3: [B4.2].~A() (Implicit destructor)
// CHECK: 4: [B10.2].~A() (Implicit destructor)
@@ -492,14 +480,14 @@ void test_catch_copy() {
// CHECK: Predecessors (1): B10
// CHECK: Successors (1): B1
// CHECK: [ B10 ]
-// CHECK: 1:
+// CHECK: 1:
// CHECK: 2: A c;
// CHECK: 3: UV
// CHECK: T: if [B10.3]
// CHECK: Predecessors (1): B2
// CHECK: Successors (2): B9 B8
// CHECK: [ B11 ]
-// CHECK: 1:
+// CHECK: 1:
// CHECK: 2: A a;
// CHECK: Predecessors (1): B12
// CHECK: Successors (1): B2
@@ -515,7 +503,7 @@ void test_catch_copy() {
// CHECK: Predecessors (1): B2
// CHECK: Successors (2): B3 B0
// CHECK: [ B2 ]
-// CHECK: 1:
+// CHECK: 1:
// CHECK: 2: A a;
// CHECK: 3: [B2.2].~A() (Implicit destructor)
// CHECK: Predecessors (2): B3 B4
@@ -530,7 +518,7 @@ void test_catch_copy() {
// CHECK: Predecessors (0):
// CHECK: Successors (1): B11
// CHECK: [ B1 ]
-// CHECK: 1:
+// CHECK: 1:
// CHECK: 2: A d;
// CHECK: 3: [B1.2].~A() (Implicit destructor)
// CHECK: 4: [B11.2].~A() (Implicit destructor)
@@ -542,7 +530,7 @@ void test_catch_copy() {
// CHECK: Predecessors (2): B3 B6
// CHECK: Successors (2): B10 B1
// CHECK: [ B3 ]
-// CHECK: 1:
+// CHECK: 1:
// CHECK: 2: A c;
// CHECK: 3: [B3.2].~A() (Implicit destructor)
// CHECK: 4: [B9.2].~A() (Implicit destructor)
@@ -575,7 +563,7 @@ void test_catch_copy() {
// CHECK: Predecessors (1): B9
// CHECK: Successors (1): B1
// CHECK: [ B9 ]
-// CHECK: 1:
+// CHECK: 1:
// CHECK: 2: A b;
// CHECK: 3: UV
// CHECK: T: if [B9.3]
@@ -585,7 +573,7 @@ void test_catch_copy() {
// CHECK: Predecessors (1): B2
// CHECK: Successors (1): B9
// CHECK: [ B11 ]
-// CHECK: 1:
+// CHECK: 1:
// CHECK: 2: A a;
// CHECK: Predecessors (1): B12
// CHECK: Successors (1): B9
@@ -601,16 +589,16 @@ void test_catch_copy() {
// CHECK: Predecessors (2): B3 B2
// CHECK: Successors (1): B0
// CHECK: [ B2 ]
-// CHECK: 1:
+// CHECK: 1:
// CHECK: 2: A a;
// CHECK: 3: a
-// CHECK: 4: switch ([B2.5])
-// CHECK:[B3.2] 5: b.operator int()
+// CHECK: 4: A b = a;
+// CHECK: 5: b.operator int()
// CHECK: T: switch [B2.5]
// CHECK: Predecessors (1): B4
// CHECK: Successors (1): B1
// CHECK: [ B3 ]
-// CHECK: 1:
+// CHECK: 1:
// CHECK: 2: A c;
// CHECK: 3: [B3.2].~A() (Implicit destructor)
// CHECK: Predecessors (0):
@@ -623,26 +611,17 @@ void test_catch_copy() {
// CHECK: Successors (1): B2
// CHECK: [ B1 ]
// CHECK: 1: [B2.4].~A() (Implicit destructor)
-// CHECK: 2:
+// CHECK: 2:
// CHECK: 3: A g;
// CHECK: 4: [B1.3].~A() (Implicit destructor)
// CHECK: 5: [B2.2].~A() (Implicit destructor)
// CHECK: Predecessors (3): B3 B7 B2
// CHECK: Successors (1): B0
// CHECK: [ B2 ]
-// CHECK: 1:
+// CHECK: 1:
// CHECK: 2: A a;
// CHECK: 3: a
-// CHECK: 4: switch ([B2.5]) {
-// CHECK: case 0:
-// CHECK: {
-// CHECK:[B8.2] if ([B8.3])
-// CHECK: break;
-// CHECK: if ([B6.1])
-// CHECK:[B5.1][B4.2] }
-// CHECK: case 1:
-// CHECK: break;
-// CHECK:}
+// CHECK: 4: A b = a;
// CHECK: 5: b.operator int()
// CHECK: T: switch [B2.5]
// CHECK: Predecessors (1): B9
@@ -654,7 +633,7 @@ void test_catch_copy() {
// CHECK: Predecessors (2): B2 B4
// CHECK: Successors (1): B1
// CHECK: [ B4 ]
-// CHECK: 1:
+// CHECK: 1:
// CHECK: 2: A f;
// CHECK: 3: [B4.2].~A() (Implicit destructor)
// CHECK: 4: [B8.2].~A() (Implicit destructor)
@@ -679,7 +658,7 @@ void test_catch_copy() {
// CHECK: Successors (1): B1
// CHECK: [ B8 ]
// CHECK: case 0:
-// CHECK: 1:
+// CHECK: 1:
// CHECK: 2: A c;
// CHECK: 3: UV
// CHECK: T: if [B8.3]
@@ -698,8 +677,8 @@ void test_catch_copy() {
// CHECK: Successors (1): B0
// CHECK: [ B2 ]
// CHECK: 1: a
-// CHECK: 2: for (A a; [B2.4];)
-// CHECK:[B4.2] 3: b.operator int()
+// CHECK: 2: A b = a;
+// CHECK: 3: b.operator int()
// CHECK: 4: [B2.3]
// CHECK: T: for (...; [B2.4]; )
// CHECK: Predecessors (2): B3 B5
@@ -709,13 +688,13 @@ void test_catch_copy() {
// CHECK: Predecessors (1): B4
// CHECK: Successors (1): B2
// CHECK: [ B4 ]
-// CHECK: 1:
+// CHECK: 1:
// CHECK: 2: A c;
// CHECK: 3: [B4.2].~A() (Implicit destructor)
// CHECK: Predecessors (1): B2
// CHECK: Successors (1): B3
// CHECK: [ B5 ]
-// CHECK: 1:
+// CHECK: 1:
// CHECK: 2: A a;
// CHECK: Predecessors (1): B6
// CHECK: Successors (1): B2
@@ -728,7 +707,7 @@ void test_catch_copy() {
// CHECK: [ B1 ]
// CHECK: 1: [B2.2].~A() (Implicit destructor)
// CHECK: 2: [B11.4].~A() (Implicit destructor)
-// CHECK: 3:
+// CHECK: 3:
// CHECK: 4: A f;
// CHECK: 5: [B1.4].~A() (Implicit destructor)
// CHECK: 6: [B11.2].~A() (Implicit destructor)
@@ -736,13 +715,7 @@ void test_catch_copy() {
// CHECK: Successors (1): B0
// CHECK: [ B2 ]
// CHECK: 1: b
-// CHECK: 2: for (A b; [B2.4];) {
-// CHECK:[B10.2] if ([B10.3])
-// CHECK: break;
-// CHECK: if ([B8.1])
-// CHECK: continue;
-// CHECK: if ([B6.1])
-// CHECK:[B5.1][B4.2]}
+// CHECK: 2: A c = b;
// CHECK: 3: c.operator int()
// CHECK: 4: [B2.3]
// CHECK: T: for (...; [B2.4]; )
@@ -753,7 +726,7 @@ void test_catch_copy() {
// CHECK: Predecessors (2): B4 B7
// CHECK: Successors (1): B2
// CHECK: [ B4 ]
-// CHECK: 1:
+// CHECK: 1:
// CHECK: 2: A e;
// CHECK: 3: [B4.2].~A() (Implicit destructor)
// CHECK: 4: [B10.2].~A() (Implicit destructor)
@@ -788,16 +761,16 @@ void test_catch_copy() {
// CHECK: Predecessors (1): B10
// CHECK: Successors (1): B1
// CHECK: [ B10 ]
-// CHECK: 1:
+// CHECK: 1:
// CHECK: 2: A d;
// CHECK: 3: UV
// CHECK: T: if [B10.3]
// CHECK: Predecessors (1): B2
// CHECK: Successors (2): B9 B8
// CHECK: [ B11 ]
-// CHECK: 1:
+// CHECK: 1:
// CHECK: 2: A a;
-// CHECK: 3:
+// CHECK: 3:
// CHECK: 4: A b;
// CHECK: Predecessors (1): B12
// CHECK: Successors (1): B2
@@ -833,3 +806,4 @@ void test_catch_copy() {
// CHECK: [ B0 (EXIT) ]
// CHECK: Predecessors (3): B2 B1 B3
// CHECK: Successors (0):
+
diff --git a/clang/test/Sema/uninit-variables.c b/clang/test/Sema/uninit-variables.c
index e0558ccc78c..330444bb5c4 100644
--- a/clang/test/Sema/uninit-variables.c
+++ b/clang/test/Sema/uninit-variables.c
@@ -92,7 +92,7 @@ void test14() {
}
void test15() {
- int x = x; // expected-warning{{variable 'x' is uninitialized when used within its own initialization}} expected-note{{variable 'x' is declared here}}
+ int x = x; // expected-warning{{variable 'x' is uninitialized when used within its own initialization}}
}
// Don't warn in the following example; shows dataflow confluence.
diff --git a/clang/test/SemaCXX/uninitialized.cpp b/clang/test/SemaCXX/uninitialized.cpp
index 13ea9688efe..cf75187ab8e 100644
--- a/clang/test/SemaCXX/uninitialized.cpp
+++ b/clang/test/SemaCXX/uninitialized.cpp
@@ -11,7 +11,7 @@ int a = a; // FIXME: This doesn't warn!? Seems it doesn't cast 'a' to an RValue.
int b = b + 1; // expected-warning {{variable 'b' is uninitialized when used within its own initialization}}
int c = (c + c); // expected-warning 2 {{variable 'c' is uninitialized when used within its own initialization}}
void test() {
- int d = ({ d + d ;}); // expected-warning 2 {{variable 'd' is uninitialized when used within its own initialization}}
+ int d = ({ d + d ;}); // expected-warning {{variable 'd' is uninitialized when used within its own initialization}}
}
int e = static_cast<long>(e) + 1; // expected-warning {{variable 'e' is uninitialized when used within its own initialization}}
int f = foo(f); // expected-warning {{variable 'f' is uninitialized when used within its own initialization}}
OpenPOWER on IntegriCloud