aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Analysis/UninitializedValues.cpp31
-rw-r--r--test/SemaCXX/uninit-variables.cpp11
2 files changed, 34 insertions, 8 deletions
diff --git a/lib/Analysis/UninitializedValues.cpp b/lib/Analysis/UninitializedValues.cpp
index 009922ae92..8bc9506c85 100644
--- a/lib/Analysis/UninitializedValues.cpp
+++ b/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/test/SemaCXX/uninit-variables.cpp b/test/SemaCXX/uninit-variables.cpp
index 6c5d0068a4..9abccf0751 100644
--- a/test/SemaCXX/uninit-variables.cpp
+++ b/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}}
+}
+