summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2011-08-08 21:43:08 +0000
committerTed Kremenek <kremenek@apple.com>2011-08-08 21:43:08 +0000
commita0cdf58b0c348bb0515db384855dd2c9d59a492d (patch)
tree46c12b1a40e52035f8e42148f51e830c241284a0
parentc96953c12aeead73ff37a7d346b101bdec3ffc25 (diff)
downloadbcm5719-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.cpp31
-rw-r--r--clang/test/SemaCXX/uninit-variables.cpp11
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}}
+}
+
OpenPOWER on IntegriCloud