diff options
| author | Ted Kremenek <kremenek@apple.com> | 2011-08-08 21:43:08 +0000 |
|---|---|---|
| committer | Ted Kremenek <kremenek@apple.com> | 2011-08-08 21:43:08 +0000 |
| commit | a0cdf58b0c348bb0515db384855dd2c9d59a492d (patch) | |
| tree | 46c12b1a40e52035f8e42148f51e830c241284a0 | |
| parent | c96953c12aeead73ff37a7d346b101bdec3ffc25 (diff) | |
| download | bcm5719-llvm-a0cdf58b0c348bb0515db384855dd2c9d59a492d.tar.gz bcm5719-llvm-a0cdf58b0c348bb0515db384855dd2c9d59a492d.zip | |
Fix another -Wuninitialized assertion failure (this one involving bit casts) resulting from the recent -Wuninitialized changes.
llvm-svn: 137068
| -rw-r--r-- | clang/lib/Analysis/UninitializedValues.cpp | 31 | ||||
| -rw-r--r-- | clang/test/SemaCXX/uninit-variables.cpp | 11 |
2 files changed, 34 insertions, 8 deletions
diff --git a/clang/lib/Analysis/UninitializedValues.cpp b/clang/lib/Analysis/UninitializedValues.cpp index 009922ae92c..8bc9506c850 100644 --- a/clang/lib/Analysis/UninitializedValues.cpp +++ b/clang/lib/Analysis/UninitializedValues.cpp @@ -389,6 +389,20 @@ public: }; } +static const Expr *stripCasts(ASTContext &C, const Expr *Ex) { + while (Ex) { + Ex = Ex->IgnoreParenNoopCasts(C); + if (const CastExpr *CE = dyn_cast<CastExpr>(Ex)) { + if (CE->getCastKind() == CK_LValueBitCast) { + Ex = CE->getSubExpr(); + continue; + } + } + break; + } + return Ex; +} + void TransferFunctions::reportUninit(const DeclRefExpr *ex, const VarDecl *vd, bool isAlwaysUnit) { if (handler) handler->handleUseOfUninitVariable(ex, vd, isAlwaysUnit); @@ -470,9 +484,9 @@ void TransferFunctions::VisitDeclStmt(DeclStmt *ds) { // appropriately, but we need to continue to analyze subsequent uses // of the variable. if (init == lastLoad) { - DeclRefExpr *DR - = cast<DeclRefExpr>(lastLoad-> - getSubExpr()->IgnoreParenNoopCasts(ac.getASTContext())); + const DeclRefExpr *DR + = cast<DeclRefExpr>(stripCasts(ac.getASTContext(), + lastLoad->getSubExpr())); if (DR->getDecl() == vd) { // int x = x; // Propagate uninitialized value, but don't immediately report @@ -544,7 +558,8 @@ void TransferFunctions::VisitCastExpr(clang::CastExpr *ce) { } } } - else if (ce->getCastKind() == CK_NoOp) { + else if (ce->getCastKind() == CK_NoOp || + ce->getCastKind() == CK_LValueBitCast) { skipProcessUses = true; } else if (CStyleCastExpr *cse = dyn_cast<CStyleCastExpr>(ce)) { @@ -580,10 +595,10 @@ void TransferFunctions::ProcessUses(Stmt *s) { // If we reach here, we have seen a load of an uninitialized value // and it hasn't been casted to void or otherwise handled. In this // situation, report the incident. - DeclRefExpr *DR = - cast<DeclRefExpr>(lastLoad->getSubExpr()-> - IgnoreParenNoopCasts(ac.getASTContext())); - VarDecl *VD = cast<VarDecl>(DR->getDecl()); + const DeclRefExpr *DR = + cast<DeclRefExpr>(stripCasts(ac.getASTContext(), + lastLoad->getSubExpr())); + const VarDecl *VD = cast<VarDecl>(DR->getDecl()); reportUninit(DR, VD, isAlwaysUninit(vals[VD])); lastLoad = 0; diff --git a/clang/test/SemaCXX/uninit-variables.cpp b/clang/test/SemaCXX/uninit-variables.cpp index 6c5d0068a43..9abccf07510 100644 --- a/clang/test/SemaCXX/uninit-variables.cpp +++ b/clang/test/SemaCXX/uninit-variables.cpp @@ -130,3 +130,14 @@ void test_noop_cast2() { int y = (int&)x; // expected-warning {{uninitialized when used here}} } +// Test handling of bit casts. +void test_bitcasts() { + int x = 1; + int y = (float &)x; // no-warning +} + +void test_bitcasts_2() { + int x; // expected-note {{declared here}} expected-note {{add initialization}} + int y = (float &)x; // expected-warning {{uninitialized when used here}} +} + |

