[cfe-commits] r157511 - in /cfe/trunk: docs/ReleaseNotes.html include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/AnalysisBasedWarnings.cpp test/Analysis/uninit-sometimes.cpp test/Sema/uninit-variables.c

Richard Smith richard-llvm at metafoo.co.uk
Fri May 25 23:20:46 PDT 2012


Author: rsmith
Date: Sat May 26 01:20:46 2012
New Revision: 157511

URL: http://llvm.org/viewvc/llvm-project?rev=157511&view=rev
Log:
In response to some discussions on IRC, tweak the wording of the new
-Wsometimes-uninitialized diagnostics to make it clearer that the cause
of the issue may be a condition which must always evaluate to true or
false, rather than an uninitialized variable.

To emphasize this, add a new note with a fixit which removes the
impossible condition or replaces it with a constant.

Also, downgrade the diagnostic from -Wsometimes-uninitialized to
-Wconditional-uninitialized when it applies to a range-based for loop,
since the condition is not written explicitly in the code in that case.

Modified:
    cfe/trunk/docs/ReleaseNotes.html
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp
    cfe/trunk/test/Analysis/uninit-sometimes.cpp
    cfe/trunk/test/Sema/uninit-variables.c

Modified: cfe/trunk/docs/ReleaseNotes.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/ReleaseNotes.html?rev=157511&r1=157510&r2=157511&view=diff
==============================================================================
--- cfe/trunk/docs/ReleaseNotes.html (original)
+++ cfe/trunk/docs/ReleaseNotes.html Sat May 26 01:20:46 2012
@@ -102,12 +102,15 @@
   return n;
 }
 
-<b>sometimes-uninit.cpp:5:10: <span class="warning">warning:</span> variable 'n' is sometimes uninitialized when used here [-Wsometimes-uninitialized]</b>
+<b>sometimes-uninit.cpp:3:7: <span class="warning">warning:</span> variable 'n' is used uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized]</b>
+  if (b)
+      <span class="caret">^</span>
+<b>sometimes-uninit.cpp:5:10: <span class="note">note:</span></b> uninitialized use occurs here
   return n;
          <span class="caret">^</span>
-<b>sometimes-uninit.cpp:3:7: <span class="note">note:</span></b> uninitialized use occurs whenever 'if' condition is false
+<b>sometimes-uninit.cpp:3:3: <span class="note">note:</span></b> remove the 'if' if its condition is always true
   if (b)
-      <span class="caret">^</span>
+  <span class="caret">^~~~~~</span>
 <b>sometimes-uninit.cpp:2:8: <span class="note">note:</span></b> initialize the variable 'n' to silence this warning
   int n;
        <span class="caret">^</span>

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=157511&r1=157510&r2=157511&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sat May 26 01:20:46 2012
@@ -1178,38 +1178,31 @@
   "variable %0 is uninitialized when used within its own initialization">,
   InGroup<Uninitialized>;
 def warn_uninit_var : Warning<
-  "variable %0 is uninitialized when used here">,
+  "variable %0 is uninitialized when %select{used here|captured by block}1">,
   InGroup<Uninitialized>, DefaultIgnore;
 def warn_sometimes_uninit_var : Warning<
-  "variable %0 is sometimes uninitialized when used here">,
-  InGroup<UninitializedSometimes>, DefaultIgnore;
-def warn_maybe_uninit_var :
-  Warning<"variable %0 may be uninitialized when used here">,
-    InGroup<UninitializedMaybe>, DefaultIgnore;
-def note_uninit_var_def : Note<
-  "variable %0 is declared here">;
-def warn_uninit_var_captured_by_block : Warning<
-  "variable %0 is uninitialized when captured by block">,
-  InGroup<Uninitialized>, DefaultIgnore;
-def warn_sometimes_uninit_var_captured_by_block : Warning<
-  "variable %0 is sometimes uninitialized when captured by block">,
-  InGroup<UninitializedSometimes>, DefaultIgnore;
-def warn_maybe_uninit_var_captured_by_block : Warning<
-  "variable %0 may be uninitialized when captured by block">,
+  "variable %0 is %select{used|captured}1 uninitialized whenever "
+  "%select{'%3' condition is %select{true|false}4|"
+  "'%3' loop %select{is entered|exits because its condition is false}4|"
+  "'%3' loop %select{condition is true|exits because its condition is false}4|"
+  "switch %3 is taken}2">, InGroup<UninitializedSometimes>, DefaultIgnore;
+def warn_maybe_uninit_var : Warning<
+  "variable %0 may be uninitialized when "
+  "%select{used here|captured by block}1">,
   InGroup<UninitializedMaybe>, DefaultIgnore;
+def note_uninit_var_def : Note<"variable %0 is declared here">;
+def note_uninit_var_use : Note<
+  "%select{uninitialized use occurs|variable is captured by block}0 here">;
 def warn_uninit_byref_blockvar_captured_by_block : Warning<
   "block pointer variable %0 is uninitialized when captured by block">,
   InGroup<Uninitialized>, DefaultIgnore;
-def note_sometimes_uninit_var_branch : Note<
-  "uninitialized use occurs whenever "
-  "%select{'%1' condition is %select{true|false}2|"
-  "'%1' loop %select{is entered|exits because its condition is false}2|"
-  "'%1' loop %select{condition is true|exits because its condition is false}2|"
-  "switch %1 is taken}0">;
 def note_block_var_fixit_add_initialization : Note<
   "maybe you meant to use __block %0">;
 def note_var_fixit_add_initialization : Note<
   "initialize the variable %0 to silence this warning">;
+def note_uninit_fixit_remove_cond : Note<
+  "remove the %select{'%1' if its condition|condition if it}0 "
+  "is always %select{false|true}2">;
 def err_init_incomplete_type : Error<"initialization of incomplete type %0">;
 
 def err_temp_copy_no_viable : Error<

Modified: cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp?rev=157511&r1=157510&r2=157511&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp (original)
+++ cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp Sat May 26 01:20:46 2012
@@ -19,6 +19,7 @@
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/Lexer.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/ExprObjC.h"
@@ -456,31 +457,92 @@
   return true;
 }
 
-/// NoteUninitBranches -- Helper function to produce notes for branches which
-/// inevitably lead to an uninitialized variable use.
-static void NoteUninitBranches(Sema &S, const UninitUse &Use) {
+/// Create a fixit to remove an if-like statement, on the assumption that its
+/// condition is CondVal.
+static void CreateIfFixit(Sema &S, const Stmt *If, const Stmt *Then,
+                          const Stmt *Else, bool CondVal,
+                          FixItHint &Fixit1, FixItHint &Fixit2) {
+  if (CondVal) {
+    // If condition is always true, remove all but the 'then'.
+    Fixit1 = FixItHint::CreateRemoval(
+        CharSourceRange::getCharRange(If->getLocStart(),
+                                      Then->getLocStart()));
+    if (Else) {
+      SourceLocation ElseKwLoc = Lexer::getLocForEndOfToken(
+          Then->getLocEnd(), 0, S.getSourceManager(), S.getLangOpts());
+      Fixit2 = FixItHint::CreateRemoval(
+          SourceRange(ElseKwLoc, Else->getLocEnd()));
+    }
+  } else {
+    // If condition is always false, remove all but the 'else'.
+    if (Else)
+      Fixit1 = FixItHint::CreateRemoval(
+          CharSourceRange::getCharRange(If->getLocStart(),
+                                        Else->getLocStart()));
+    else
+      Fixit1 = FixItHint::CreateRemoval(If->getSourceRange());
+  }
+}
+
+/// DiagUninitUse -- Helper function to produce a diagnostic for an
+/// uninitialized use of a variable.
+static void DiagUninitUse(Sema &S, const VarDecl *VD, const UninitUse &Use,
+                          bool IsCapturedByBlock) {
+  bool Diagnosed = false;
+
+  // Diagnose each branch which leads to a sometimes-uninitialized use.
   for (UninitUse::branch_iterator I = Use.branch_begin(), E = Use.branch_end();
        I != E; ++I) {
+    assert(Use.getKind() == UninitUse::Sometimes);
+
+    const Expr *User = Use.getUser();
     const Stmt *Term = I->Terminator;
+
+    // Information used when building the diagnostic.
     unsigned DiagKind;
-    SourceRange Range;
     const char *Str;
+    SourceRange Range;
+
+    // FixIts to suppress the diagnosic by removing the dead condition.
+    // For all binary terminators, branch 0 is taken if the condition is true,
+    // and branch 1 is taken if the condition is false.
+    int RemoveDiagKind = -1;
+    const char *FixitStr =
+        S.getLangOpts().CPlusPlus ? (I->Output ? "true" : "false")
+                                  : (I->Output ? "1" : "0");
+    FixItHint Fixit1, Fixit2;
+
     switch (Term->getStmtClass()) {
     default:
-      // Don't know how to report this.
+      // Don't know how to report this. Just fall back to 'may be used
+      // uninitialized'. This happens for range-based for, which the user
+      // can't explicitly fix.
+      // FIXME: This also happens if the first use of a variable is always
+      // uninitialized, eg "for (int n; n < 10; ++n)". We should report that
+      // with the 'is uninitialized' diagnostic.
       continue;
 
     // "condition is true / condition is false".
-    case Stmt::IfStmtClass:
+    case Stmt::IfStmtClass: {
+      const IfStmt *IS = cast<IfStmt>(Term);
       DiagKind = 0;
       Str = "if";
-      Range = cast<IfStmt>(Term)->getCond()->getSourceRange();
+      Range = IS->getCond()->getSourceRange();
+      RemoveDiagKind = 0;
+      CreateIfFixit(S, IS, IS->getThen(), IS->getElse(),
+                    I->Output, Fixit1, Fixit2);
       break;
-    case Stmt::ConditionalOperatorClass:
+    }
+    case Stmt::ConditionalOperatorClass: {
+      const ConditionalOperator *CO = cast<ConditionalOperator>(Term);
       DiagKind = 0;
       Str = "?:";
-      Range = cast<ConditionalOperator>(Term)->getCond()->getSourceRange();
+      Range = CO->getCond()->getSourceRange();
+      RemoveDiagKind = 0;
+      CreateIfFixit(S, CO, CO->getTrueExpr(), CO->getFalseExpr(),
+                    I->Output, Fixit1, Fixit2);
       break;
+    }
     case Stmt::BinaryOperatorClass: {
       const BinaryOperator *BO = cast<BinaryOperator>(Term);
       if (!BO->isLogicalOp())
@@ -488,6 +550,15 @@
       DiagKind = 0;
       Str = BO->getOpcodeStr();
       Range = BO->getLHS()->getSourceRange();
+      RemoveDiagKind = 0;
+      if ((BO->getOpcode() == BO_LAnd && I->Output) ||
+          (BO->getOpcode() == BO_LOr && !I->Output))
+        // true && y -> y, false || y -> y.
+        Fixit1 = FixItHint::CreateRemoval(SourceRange(BO->getLocStart(),
+                                                      BO->getOperatorLoc()));
+      else
+        // false && y -> false, true || y -> true.
+        Fixit1 = FixItHint::CreateReplacement(BO->getSourceRange(), FixitStr);
       break;
     }
 
@@ -496,16 +567,18 @@
       DiagKind = 1;
       Str = "while";
       Range = cast<WhileStmt>(Term)->getCond()->getSourceRange();
+      RemoveDiagKind = 1;
+      Fixit1 = FixItHint::CreateReplacement(Range, FixitStr);
       break;
     case Stmt::ForStmtClass:
       DiagKind = 1;
       Str = "for";
       Range = cast<ForStmt>(Term)->getCond()->getSourceRange();
-      break;
-    case Stmt::CXXForRangeStmtClass:
-      DiagKind = 1;
-      Str = "for";
-      Range = cast<CXXForRangeStmt>(Term)->getCond()->getSourceRange();
+      RemoveDiagKind = 1;
+      if (I->Output)
+        Fixit1 = FixItHint::CreateRemoval(Range);
+      else
+        Fixit1 = FixItHint::CreateReplacement(Range, FixitStr);
       break;
 
     // "condition is true / loop is exited".
@@ -513,6 +586,8 @@
       DiagKind = 2;
       Str = "do";
       Range = cast<DoStmt>(Term)->getCond()->getSourceRange();
+      RemoveDiagKind = 1;
+      Fixit1 = FixItHint::CreateReplacement(Range, FixitStr);
       break;
 
     // "switch case is taken".
@@ -528,9 +603,24 @@
       break;
     }
 
-    S.Diag(Range.getBegin(), diag::note_sometimes_uninit_var_branch)
-      << DiagKind << Str << I->Output << Range;
-  }
+    S.Diag(Range.getBegin(), diag::warn_sometimes_uninit_var)
+      << VD->getDeclName() << IsCapturedByBlock << DiagKind
+      << Str << I->Output << Range;
+    S.Diag(User->getLocStart(), diag::note_uninit_var_use)
+      << IsCapturedByBlock << User->getSourceRange();
+    if (RemoveDiagKind != -1)
+      S.Diag(Fixit1.RemoveRange.getBegin(), diag::note_uninit_fixit_remove_cond)
+        << RemoveDiagKind << Str << I->Output << Fixit1 << Fixit2;
+
+    Diagnosed = true;
+  }
+
+  if (!Diagnosed)
+    S.Diag(Use.getUser()->getLocStart(),
+           Use.getKind() == UninitUse::Always ? diag::warn_uninit_var
+                                              : diag::warn_maybe_uninit_var)
+        << VD->getDeclName() << IsCapturedByBlock
+        << Use.getUser()->getSourceRange();
 }
 
 /// DiagnoseUninitializedUse -- Helper function for diagnosing uses of an
@@ -568,37 +658,15 @@
       }
     }
 
-    unsigned DiagID = 0;
-    switch (Use.getKind()) {
-    case UninitUse::Always: DiagID = diag::warn_uninit_var; break;
-    case UninitUse::Sometimes: DiagID = diag::warn_sometimes_uninit_var; break;
-    case UninitUse::Maybe: DiagID = diag::warn_maybe_uninit_var; break;
-    }
-    S.Diag(DRE->getLocStart(), DiagID)
-      << VD->getDeclName() << DRE->getSourceRange();
-    NoteUninitBranches(S, Use);
+    DiagUninitUse(S, VD, Use, false);
   } else {
     const BlockExpr *BE = cast<BlockExpr>(Use.getUser());
-    if (VD->getType()->isBlockPointerType() &&
-        !VD->hasAttr<BlocksAttr>())
-      S.Diag(BE->getLocStart(), diag::warn_uninit_byref_blockvar_captured_by_block)
+    if (VD->getType()->isBlockPointerType() && !VD->hasAttr<BlocksAttr>())
+      S.Diag(BE->getLocStart(),
+             diag::warn_uninit_byref_blockvar_captured_by_block)
         << VD->getDeclName();
-    else {
-      unsigned DiagID = 0;
-      switch (Use.getKind()) {
-      case UninitUse::Always:
-        DiagID = diag::warn_uninit_var_captured_by_block;
-        break;
-      case UninitUse::Sometimes:
-        DiagID = diag::warn_sometimes_uninit_var_captured_by_block;
-        break;
-      case UninitUse::Maybe:
-        DiagID = diag::warn_maybe_uninit_var_captured_by_block;
-        break;
-      }
-      S.Diag(BE->getLocStart(), DiagID) << VD->getDeclName();
-      NoteUninitBranches(S, Use);
-    }
+    else
+      DiagUninitUse(S, VD, Use, true);
   }
 
   // Report where the variable was declared when the use wasn't within

Modified: cfe/trunk/test/Analysis/uninit-sometimes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/uninit-sometimes.cpp?rev=157511&r1=157510&r2=157511&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/uninit-sometimes.cpp (original)
+++ cfe/trunk/test/Analysis/uninit-sometimes.cpp Sat May 26 01:20:46 2012
@@ -1,41 +1,63 @@
 // RUN: %clang_cc1 -std=gnu++11 -Wsometimes-uninitialized -verify %s
+// RUN: %clang_cc1 -std=gnu++11 -Wsometimes-uninitialized -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
 
 bool maybe();
 
 int test_if_false(bool b) {
   int x; // expected-note {{variable}}
-  if (b) x = 1; // expected-note {{whenever 'if' condition is false}}
-  return x; // expected-warning {{sometimes uninit}}
+  if (b) // expected-warning {{whenever 'if' condition is false}} \
+         // expected-note {{remove the 'if' if its condition is always true}}
+    x = 1;
+  return x; // expected-note {{uninitialized use}}
 }
 
+// CHECK: fix-it:"{{.*}}":{8:3-10:5}:""
+// CHECK: fix-it:"{{.*}}":{7:8-7:8}:" = 0"
+
+
 int test_if_true(bool b) {
   int x; // expected-note {{variable}}
-  if (b) {} // expected-note {{whenever 'if' condition is true}}
+  if (b) {} // expected-warning {{whenever 'if' condition is true}} \
+            // expected-note {{remove the 'if' if its condition is always false}}
   else x = 1;
-  return x; // expected-warning {{sometimes uninit}}
+  return x; // expected-note {{uninitialized use}}
 }
 
+// CHECK: fix-it:"{{.*}}":{20:3-22:8}:""
+// CHECK: fix-it:"{{.*}}":{19:8-19:8}:" = 0"
+
+
 int test_while_false(bool b) {
   int x; // expected-note {{variable}}
-  while (b) { // expected-note {{whenever 'while' loop exits because its condition is false}}
+  while (b) { // expected-warning {{whenever 'while' loop exits because its condition is false}} \
+              // expected-note {{remove the condition if it is always true}}
     if (maybe()) {
       x = 1;
       break;
     }
   };
-  return x; // expected-warning {{sometimes uninit}}
+  return x; // expected-note {{uninitialized use}}
 }
 
+// CHECK: fix-it:"{{.*}}":{32:10-32:11}:"true"
+// CHECK: fix-it:"{{.*}}":{31:8-31:8}:" = 0"
+
+
 int test_while_true(bool b) {
   int x; // expected-note {{variable}}
-  while (b) { // expected-note {{whenever 'while' loop is entered}}
+  while (b) { // expected-warning {{whenever 'while' loop is entered}} \
+              // expected-note {{remove the condition if it is always false}}
 label:
-    return x; // expected-warning {{sometimes uninit}}
+    return x; // expected-note {{uninitialized use}}
   }
   x = 0;
   goto label;
 }
 
+// CHECK: fix-it:"{{.*}}":{48:10-48:11}:"false"
+// CHECK: fix-it:"{{.*}}":{47:8-47:8}:" = 0"
+
+
 int test_do_while_false(bool b) {
   int x; // expected-note {{variable}}
   do {
@@ -43,131 +65,193 @@
       x = 1;
       break;
     }
-  } while (b); // expected-note {{whenever 'do' loop exits because its condition is false}}
-  return x; // expected-warning {{sometimes uninit}}
+  } while (b); // expected-warning {{whenever 'do' loop exits because its condition is false}} \
+               // expected-note {{remove the condition if it is always true}}
+  return x; // expected-note {{uninitialized use}}
 }
 
+// CHECK: fix-it:"{{.*}}":{68:12-68:13}:"true"
+// CHECK: fix-it:"{{.*}}":{62:8-62:8}:" = 0"
+
+
 int test_do_while_true(bool b) {
   int x; // expected-note {{variable}}
 goto label2;
   do {
 label1:
-    return x; // expected-warning {{sometimes uninit}}
+    return x; // expected-note {{uninitialized use}}
 label2: ;
-  } while (b); // expected-note {{whenever 'do' loop condition is true}}
+  } while (b); // expected-warning {{whenever 'do' loop condition is true}} \
+               // expected-note {{remove the condition if it is always false}}
   x = 0;
   goto label1;
 }
 
+// CHECK: fix-it:"{{.*}}":{84:12-84:13}:"false"
+// CHECK: fix-it:"{{.*}}":{78:8-78:8}:" = 0"
+
+
 int test_for_false(int k) {
   int x; // expected-note {{variable}}
   for (int n = 0;
-       n < k; // expected-note {{whenever 'for' loop exits because its condition is false}}
+       n < k; // expected-warning {{whenever 'for' loop exits because its condition is false}} \
+              // expected-note {{remove the condition if it is always true}}
        ++n) {
     if (maybe()) {
       x = n;
       break;
     }
   }
-  return x; // expected-warning {{sometimes uninit}}
+  return x; // expected-note {{uninitialized use}}
 }
 
+// CHECK: fix-it:"{{.*}}":{97:8-97:13}:""
+// CHECK: fix-it:"{{.*}}":{95:8-95:8}:" = 0"
+
+
 int test_for_true(int k) {
   int x; // expected-note {{variable}}
   int n = 0;
   for (;
-       n < k; // expected-note {{whenever 'for' loop is entered}}
+       n < k; // expected-warning {{whenever 'for' loop is entered}} \
+              // expected-note {{remove the condition if it is always false}}
        ++n) {
 label:
-    return x; // expected-warning {{sometimes uninit}}
+    return x; // expected-note {{uninitialized use}}
   }
   x = 1;
   goto label;
 }
 
+// CHECK: fix-it:"{{.*}}":{116:8-116:13}:"false"
+// CHECK: fix-it:"{{.*}}":{113:8-113:8}:" = 0"
+
+
 int test_for_range_false(int k) {
   int arr[3] = { 1, 2, 3 };
-  int x; // expected-note {{variable}}
-  for (int &a : arr) { // expected-note {{whenever 'for' loop exits because its condition is false}}
+  int x;
+  for (int &a : arr) { // no-warning, condition was not explicitly specified
     if (a == k) {
       x = &a - arr;
       break;
     }
   }
-  return x; // expected-warning {{sometimes uninit}}
+  return x;
 }
 
+
+
+
+
 int test_for_range_true(int k) {
   int arr[3] = { 1, 2, 3 };
-  int x; // expected-note {{variable}}
-  for (int &a : arr) { // expected-note {{whenever 'for' loop is entered}}
+  int x;
+  for (int &a : arr) { // no-warning
     goto label;
   }
   x = 0;
 label:
-  return x; // expected-warning {{sometimes uninit}}
+  return x;
 }
 
+
+
+
+
 int test_conditional_false(int k) {
   int x; // expected-note {{variable}}
   (void)(
-      maybe() // expected-note {{whenever '?:' condition is false}}
+      maybe() // expected-warning {{whenever '?:' condition is false}} \
+              // expected-note {{remove the '?:' if its condition is always true}}
       ? x = 1 : 0);
-  return x; // expected-warning {{sometimes uninit}}
+  return x; // expected-note {{uninitialized use}}
 }
 
+// CHECK: fix-it:"{{.*}}":{164:7-166:9}:""
+// CHECK: fix-it:"{{.*}}":{166:14-166:18}:""
+// CHECK: fix-it:"{{.*}}":{162:8-162:8}:" = 0"
+
 int test_conditional_true(int k) {
   int x; // expected-note {{variable}}
   (void)(
-      maybe() // expected-note {{whenever '?:' condition is true}}
+      maybe() // expected-warning {{whenever '?:' condition is true}} \
+              // expected-note {{remove the '?:' if its condition is always false}}
       ? 0 : x = 1);
-  return x; // expected-warning {{sometimes uninit}}
+  return x; // expected-note {{uninitialized use}}
 }
 
+// CHECK: fix-it:"{{.*}}":{177:7-179:13}:""
+// CHECK: fix-it:"{{.*}}":{175:8-175:8}:" = 0"
+
+
 int test_logical_and_false(int k) {
   int x; // expected-note {{variable}}
-  maybe() // expected-note {{whenever '&&' condition is false}}
+  maybe() // expected-warning {{whenever '&&' condition is false}} \
+          // expected-note {{remove the '&&' if its condition is always true}}
       && (x = 1);
-  return x; // expected-warning {{sometimes uninit}}
+  return x; // expected-note {{uninitialized use}}
 }
 
+// CHECK: fix-it:"{{.*}}":{189:3-191:9}:""
+// CHECK: fix-it:"{{.*}}":{188:8-188:8}:" = 0"
+
+
 int test_logical_and_true(int k) {
   int x; // expected-note {{variable}}
-  maybe() // expected-note {{whenever '&&' condition is true}}
+  maybe() // expected-warning {{whenever '&&' condition is true}} \
+          // expected-note {{remove the '&&' if its condition is always false}}
       && ({ goto skip_init; 0; });
   x = 1;
 skip_init:
-  return x; // expected-warning {{sometimes uninit}}
+  return x; // expected-note {{uninitialized use}}
 }
 
+// CHECK: fix-it:"{{.*}}":{201:3-203:34}:"false"
+// CHECK: fix-it:"{{.*}}":{200:8-200:8}:" = 0"
+
+
 int test_logical_or_false(int k) {
   int x; // expected-note {{variable}}
-  maybe() // expected-note {{whenever '||' condition is false}}
+  maybe() // expected-warning {{whenever '||' condition is false}} \
+          // expected-note {{remove the '||' if its condition is always true}}
       || ({ goto skip_init; 0; });
   x = 1;
 skip_init:
-  return x; // expected-warning {{sometimes uninit}}
+  return x; // expected-note {{uninitialized use}}
 }
 
+// CHECK: fix-it:"{{.*}}":{215:3-217:34}:"true"
+// CHECK: fix-it:"{{.*}}":{214:8-214:8}:" = 0"
+
+
 int test_logical_or_true(int k) {
   int x; // expected-note {{variable}}
-  maybe() // expected-note {{whenever '||' condition is true}}
+  maybe() // expected-warning {{whenever '||' condition is true}} \
+          // expected-note {{remove the '||' if its condition is always false}}
       || (x = 1);
-  return x; // expected-warning {{sometimes uninit}}
+  return x; // expected-note {{uninitialized use}}
 }
 
+// CHECK: fix-it:"{{.*}}":{229:3-231:9}:""
+// CHECK: fix-it:"{{.*}}":{228:8-228:8}:" = 0"
+
+
 int test_switch_case(int k) {
   int x; // expected-note {{variable}}
   switch (k) {
   case 0:
     x = 0;
     break;
-  case 1: // expected-note {{whenever switch case is taken}}
+  case 1: // expected-warning {{whenever switch case is taken}}
     break;
   }
-  return x; // expected-warning {{sometimes uninit}}
+  return x; // expected-note {{uninitialized use}}
 }
 
+// CHECK: fix-it:"{{.*}}":{240:8-240:8}:" = 0"
+
+
+
 int test_switch_default(int k) {
   int x; // expected-note {{variable}}
   switch (k) {
@@ -177,12 +261,16 @@
   case 1:
     x = 1;
     break;
-  default: // expected-note {{whenever switch default is taken}}
+  default: // expected-warning {{whenever switch default is taken}}
     break;
   }
-  return x; // expected-warning {{sometimes uninit}}
+  return x; // expected-note {{uninitialized use}}
 }
 
+// CHECK: fix-it:"{{.*}}":{256:8-256:8}:" = 0"
+
+
+
 int test_switch_suppress_1(int k) {
   int x;
   switch (k) {
@@ -196,6 +284,10 @@
   return x; // no-warning
 }
 
+
+
+
+
 int test_switch_suppress_2(int k) {
   int x;
   switch (k) {
@@ -214,22 +306,32 @@
   return x; // no-warning
 }
 
+
+
+
+
 int test_multiple_notes(int k) {
   int x; // expected-note {{variable}}
   if (k > 0) {
     if (k == 5)
       x = 1;
-    else if (k == 2) // expected-note {{whenever 'if' condition is false}}
+    else if (k == 2) // expected-warning {{whenever 'if' condition is false}} \
+                     // expected-note {{remove the 'if' if its condition is always true}}
       x = 2;
   } else {
     if (k == -5)
       x = 3;
-    else if (k == -2) // expected-note {{whenever 'if' condition is false}}
+    else if (k == -2) // expected-warning {{whenever 'if' condition is false}} \
+                      // expected-note {{remove the 'if' if its condition is always true}}
       x = 4;
   }
-  return x; // expected-warning {{sometimes uninit}}
+  return x; // expected-note 2{{uninitialized use}}
 }
 
+// CHECK: fix-it:"{{.*}}":{324:10-326:7}:""
+// CHECK: fix-it:"{{.*}}":{318:10-320:7}:""
+// CHECK: fix-it:"{{.*}}":{314:8-314:8}:" = 0"
+
 int test_no_false_positive_1(int k) {
   int x;
   if (k)
@@ -239,6 +341,10 @@
   return x;
 }
 
+
+
+
+
 int test_no_false_positive_2() {
   int x;
   bool b = false;
@@ -249,10 +355,17 @@
   return b ? x : 0;
 }
 
+
+
+
+
 void test_null_pred_succ() {
   int x; // expected-note {{variable}}
-  if (0) // expected-note {{whenever}}
+  if (0) // expected-warning {{whenever}} expected-note {{remove}}
     foo: x = 0;
-  if (x) // expected-warning {{sometimes uninit}}
+  if (x) // expected-note {{uninitialized use}}
     goto foo;
 }
+
+// CHECK: fix-it:"{{.*}}":{364:3-365:5}:""
+// CHECK: fix-it:"{{.*}}":{363:8-363:8}:" = 0"

Modified: cfe/trunk/test/Sema/uninit-variables.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/uninit-variables.c?rev=157511&r1=157510&r2=157511&view=diff
==============================================================================
--- cfe/trunk/test/Sema/uninit-variables.c (original)
+++ cfe/trunk/test/Sema/uninit-variables.c Sat May 26 01:20:46 2012
@@ -39,9 +39,10 @@
 
 int test7(int y) {
   int x; // expected-note{{initialize the variable 'x' to silence this warning}}
-  if (y) // expected-note{{uninitialized use occurs whenever 'if' condition is false}}
+  if (y) // expected-warning{{variable 'x' is used uninitialized whenever 'if' condition is false}} \
+         // expected-note{{remove the 'if' if its condition is always true}}
     x = 1;
-  return x; // expected-warning{{variable 'x' is sometimes uninitialized when used here}}
+  return x; // expected-note{{uninitialized use occurs here}}
 }
 
 int test7b(int y) {
@@ -294,8 +295,9 @@
 
 int test41(int x) {
   int y; // expected-note{{initialize the variable 'y' to silence this warning}}
-  if (x) y = 1; // expected-note{{uninitialized use occurs whenever 'if' condition is false}}
-  return y; // expected-warning {{variable 'y' is sometimes uninitialized when used here}}
+  if (x) y = 1; // expected-warning{{variable 'y' is used uninitialized whenever 'if' condition is false}} \
+                // expected-note{{remove the 'if' if its condition is always true}}
+  return y; // expected-note{{uninitialized use occurs here}}
 }
 
 void test42() {





More information about the cfe-commits mailing list