aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/UninitializedValues.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Analysis/UninitializedValues.cpp')
-rw-r--r--lib/Analysis/UninitializedValues.cpp20
1 files changed, 16 insertions, 4 deletions
diff --git a/lib/Analysis/UninitializedValues.cpp b/lib/Analysis/UninitializedValues.cpp
index 3dde41f227..062857d86e 100644
--- a/lib/Analysis/UninitializedValues.cpp
+++ b/lib/Analysis/UninitializedValues.cpp
@@ -472,12 +472,24 @@ void TransferFunctions::VisitDeclStmt(DeclStmt *ds) {
DI != DE; ++DI) {
if (VarDecl *vd = dyn_cast<VarDecl>(*DI)) {
if (isTrackedVar(vd)) {
- if (Stmt *init = vd->getInit()) {
+ if (Expr *init = vd->getInit()) {
Visit(init);
- vals[vd] = Initialized;
+
+ // If the initializer consists solely of a reference to itself, we
+ // explicitly mark the variable as uninitialized. This allows code
+ // like the following:
+ //
+ // int x = x;
+ //
+ // to deliberately leave a variable uninitialized. Different analysis
+ // clients can detect this pattern and adjust their reporting
+ // appropriately, but we need to continue to analyze subsequent uses
+ // of the variable.
+ DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(init->IgnoreParenImpCasts());
+ vals[vd] = (DRE && DRE->getDecl() == vd) ? Uninitialized
+ : Initialized;
}
- }
- else if (Stmt *init = vd->getInit()) {
+ } else if (Stmt *init = vd->getInit()) {
Visit(init);
}
}