]> granicus.if.org Git - clang/commitdiff
Commit a bit of a hack to fully handle the situation where variables are
authorChandler Carruth <chandlerc@gmail.com>
Tue, 5 Apr 2011 21:36:30 +0000 (21:36 +0000)
committerChandler Carruth <chandlerc@gmail.com>
Tue, 5 Apr 2011 21:36:30 +0000 (21:36 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@128932 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/UninitializedValues.cpp
test/Sema/uninit-variables.c

index 3dde41f2272ee5bac3a5939737ac2d57f2da7fc0..062857d86eedde61e6e33f20b06fc5f4a054b273 100644 (file)
@@ -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);
       }
     }
index ee3e88a49c8b92244339c94bd30fb520f9a03a70..f09d44ca44fb715cde9bda2637d29ebe62fd9297 100644 (file)
@@ -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.