summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2011-04-05 21:36:30 +0000
committerChandler Carruth <chandlerc@gmail.com>2011-04-05 21:36:30 +0000
commit78c7e344859f0ebc213550fdf55838a2bf38aaeb (patch)
tree21b9111ecd2585199b18be61a37536fcdb694467
parentd4e20eacf010ab04f6f53dfdee6bf9842edd261e (diff)
downloadbcm5719-llvm-78c7e344859f0ebc213550fdf55838a2bf38aaeb.tar.gz
bcm5719-llvm-78c7e344859f0ebc213550fdf55838a2bf38aaeb.zip
Commit a bit of a hack to fully handle the situation where variables are
marked explicitly as uninitialized through direct self initialization: int x = x; With r128894 we prevented warnings about this code, and this patch teaches the analysis engine to continue analyzing subsequent uses of 'x'. This should wrap up PR9624. There is still an open question of whether we should suppress the maybe-uninitialized warnings resulting from variables initialized in this fashion. The definitely-uninitialized uses should always be warned. llvm-svn: 128932
-rw-r--r--clang/lib/Analysis/UninitializedValues.cpp20
-rw-r--r--clang/test/Sema/uninit-variables.c6
2 files changed, 20 insertions, 6 deletions
diff --git a/clang/lib/Analysis/UninitializedValues.cpp b/clang/lib/Analysis/UninitializedValues.cpp
index 3dde41f2272..062857d86ee 100644
--- a/clang/lib/Analysis/UninitializedValues.cpp
+++ b/clang/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);
}
}
diff --git a/clang/test/Sema/uninit-variables.c b/clang/test/Sema/uninit-variables.c
index ee3e88a49c8..f09d44ca44f 100644
--- a/clang/test/Sema/uninit-variables.c
+++ b/clang/test/Sema/uninit-variables.c
@@ -91,8 +91,10 @@ void test14() {
for (;;) {}
}
-void test15() {
- int x = x; // no-warning: signals intended lack of initialization.
+int test15() {
+ int x = x; // no-warning: signals intended lack of initialization. \
+ // expected-note{{variable 'x' is declared here}}
+ return x; // expected-warning{{variable 'x' is possibly uninitialized when used here}}
}
// Don't warn in the following example; shows dataflow confluence.
OpenPOWER on IntegriCloud