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.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@157511 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/Analysis/uninit-sometimes.cpp b/test/Analysis/uninit-sometimes.cpp
index 0c77f89..9667e2a 100644
--- a/test/Analysis/uninit-sometimes.cpp
+++ b/test/Analysis/uninit-sometimes.cpp
@@ -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"