]> granicus.if.org Git - clang/commitdiff
Show either a location or a fixit note, not both, for uninitialized variable warnings.
authorDavid Blaikie <dblaikie@gmail.com>
Sat, 10 Sep 2011 05:35:08 +0000 (05:35 +0000)
committerDavid Blaikie <dblaikie@gmail.com>
Sat, 10 Sep 2011 05:35:08 +0000 (05:35 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@139463 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/AnalysisBasedWarnings.cpp
test/Sema/uninit-variables.c
test/SemaCXX/uninit-variables-conditional.cpp
test/SemaCXX/uninit-variables.cpp
test/SemaObjC/uninit-variables.m

index 58bfbcfd28ade2f0b3f967a3daa04ca22021dc4d..b67f7aec7e98c74682ede64ae76f7a48722a9b9b 100644 (file)
@@ -1032,7 +1032,7 @@ def warn_maybe_uninit_var_captured_by_block : Warning<
   "variable %0 may be uninitialized when captured by block">,
   InGroup<UninitializedMaybe>, DefaultIgnore;
 def note_var_fixit_add_initialization : Note<
-  "add initialization to silence this warning">;
+  "initialize the variable %0 to silence this warning">;
 def err_init_incomplete_type : Error<"initialization of incomplete type %0">;
 
 def err_temp_copy_no_viable : Error<
index 30b6b0c8e326eeed8f8fa55c56e1ce4ff1690485..6a7c5d3dc3a980cc8e6529acde6d46bebfb12c51 100644 (file)
@@ -433,6 +433,50 @@ public:
 };
 }
 
+static bool SuggestInitializationFixit(Sema &S, const VarDecl *VD) {
+  // Don't issue a fixit if there is already an initializer.
+  if (VD->getInit())
+    return false;
+
+  // Suggest possible initialization (if any).
+  const char *initialization = 0;
+  QualType VariableTy = VD->getType().getCanonicalType();
+
+  if (VariableTy->isObjCObjectPointerType() ||
+      VariableTy->isBlockPointerType()) {
+    // Check if 'nil' is defined.
+    if (S.PP.getMacroInfo(&S.getASTContext().Idents.get("nil")))
+      initialization = " = nil";
+    else
+      initialization = " = 0";
+  }
+  else if (VariableTy->isRealFloatingType())
+    initialization = " = 0.0";
+  else if (VariableTy->isBooleanType() && S.Context.getLangOptions().CPlusPlus)
+    initialization = " = false";
+  else if (VariableTy->isEnumeralType())
+    return false;
+  else if (VariableTy->isPointerType() || VariableTy->isMemberPointerType()) {
+    if (S.Context.getLangOptions().CPlusPlus0x)
+      initialization = " = nullptr";
+    // Check if 'NULL' is defined.
+    else if (S.PP.getMacroInfo(&S.getASTContext().Idents.get("NULL")))
+      initialization = " = NULL";
+    else
+      initialization = " = 0";
+  }
+  else if (VariableTy->isScalarType())
+    initialization = " = 0";
+
+  if (initialization) {
+    SourceLocation loc = S.PP.getLocForEndOfToken(VD->getLocEnd());
+    S.Diag(loc, diag::note_var_fixit_add_initialization) << VD->getDeclName()
+      << FixItHint::CreateInsertion(loc, initialization);
+    return true;
+  }
+  return false;
+}
+
 /// DiagnoseUninitializedUse -- Helper function for diagnosing uses of an
 /// uninitialized variable. This manages the different forms of diagnostic
 /// emitted for particular types of uses. Returns true if the use was diagnosed
@@ -487,56 +531,15 @@ static bool DiagnoseUninitializedUse(Sema &S, const VarDecl *VD,
   }
 
   // Report where the variable was declared when the use wasn't within
-  // the initializer of that declaration.
-  if (!isSelfInit)
+  // the initializer of that declaration & we didn't already suggest
+  // an initialization fixit.
+  if (!isSelfInit && !SuggestInitializationFixit(S, VD))
     S.Diag(VD->getLocStart(), diag::note_uninit_var_def)
       << VD->getDeclName();
 
   return true;
 }
 
-static void SuggestInitializationFixit(Sema &S, const VarDecl *VD) {
-  // Don't issue a fixit if there is already an initializer.
-  if (VD->getInit())
-    return;
-
-  // Suggest possible initialization (if any).
-  const char *initialization = 0;
-  QualType VariableTy = VD->getType().getCanonicalType();
-
-  if (VariableTy->isObjCObjectPointerType() ||
-      VariableTy->isBlockPointerType()) {
-    // Check if 'nil' is defined.
-    if (S.PP.getMacroInfo(&S.getASTContext().Idents.get("nil")))
-      initialization = " = nil";
-    else
-      initialization = " = 0";
-  }
-  else if (VariableTy->isRealFloatingType())
-    initialization = " = 0.0";
-  else if (VariableTy->isBooleanType() && S.Context.getLangOptions().CPlusPlus)
-    initialization = " = false";
-  else if (VariableTy->isEnumeralType())
-    return;
-  else if (VariableTy->isPointerType() || VariableTy->isMemberPointerType()) {
-    if (S.Context.getLangOptions().CPlusPlus0x)
-      initialization = " = nullptr";
-    // Check if 'NULL' is defined.
-    else if (S.PP.getMacroInfo(&S.getASTContext().Idents.get("NULL")))
-      initialization = " = NULL";
-    else
-      initialization = " = 0";
-  }
-  else if (VariableTy->isScalarType())
-    initialization = " = 0";
-
-  if (initialization) {
-    SourceLocation loc = S.PP.getLocForEndOfToken(VD->getLocEnd());
-    S.Diag(loc, diag::note_var_fixit_add_initialization)
-      << FixItHint::CreateInsertion(loc, initialization);
-  }
-}
-
 typedef std::pair<const Expr*, bool> UninitUse;
 
 namespace {
@@ -587,15 +590,11 @@ public:
       
       for (UsesVec::iterator vi = vec->begin(), ve = vec->end(); vi != ve;
            ++vi) {
-        if (!DiagnoseUninitializedUse(S, vd, vi->first,
+        if (DiagnoseUninitializedUse(S, vd, vi->first,
                                       /*isAlwaysUninit=*/vi->second))
-          continue;
-
-        SuggestInitializationFixit(S, vd);
-
-        // Skip further diagnostics for this variable. We try to warn only on
-        // the first point at which a variable is used uninitialized.
-        break;
+          // Skip further diagnostics for this variable. We try to warn only on
+          // the first point at which a variable is used uninitialized.
+          break;
       }
 
       delete vec;
index dbde333d751db863ae84d7021c7353f5f41ebaf4..2398504347d2720f5767b8b0221af692a837f4cc 100644 (file)
@@ -4,7 +4,7 @@ typedef __typeof(sizeof(int)) size_t;
 void *malloc(size_t);
 
 int test1() {
-  int x; // expected-note{{variable 'x' is declared here}} expected-note{{add initialization to silence this warning}}
+  int x; // expected-note{{initialize the variable 'x' to silence this warning}}
   return x; // expected-warning{{variable 'x' is uninitialized when used here}}
 }
 
@@ -20,25 +20,25 @@ int test3() {
 }
 
 int test4() {
-  int x; // expected-note{{variable 'x' is declared here}} expected-note{{add initialization to silence this warning}}
+  int x; // expected-note{{initialize the variable 'x' to silence this warning}}
   ++x; // expected-warning{{variable 'x' is uninitialized when used here}}
   return x; 
 }
 
 int test5() {
-  int x, y; // expected-note{{variable 'y' is declared here}} expected-note{{add initialization to silence this warning}}
+  int x, y; // expected-note{{initialize the variable 'y' to silence this warning}}
   x = y; // expected-warning{{variable 'y' is uninitialized when used here}}
   return x;
 }
 
 int test6() {
-  int x; // expected-note{{variable 'x' is declared here}} expected-note{{add initialization to silence this warning}}
+  int x; // expected-note{{initialize the variable 'x' to silence this warning}}
   x += 2; // expected-warning{{variable 'x' is uninitialized when used here}}
   return x;
 }
 
 int test7(int y) {
-  int x; // expected-note{{variable 'x' is declared here}} expected-note{{add initialization to silence this warning}}
+  int x; // expected-note{{initialize the variable 'x' to silence this warning}}
   if (y)
     x = 1;
   return x; // expected-warning{{variable 'x' may be uninitialized when used here}}
@@ -54,7 +54,7 @@ int test8(int y) {
 }
 
 int test9(int n) {
-  int x; // expected-note{{variable 'x' is declared here}} expected-note{{add initialization to silence this warning}}
+  int x; // expected-note{{initialize the variable 'x' to silence this warning}}
   for (unsigned i = 0 ; i < n; ++i) {
     if (i == n - 1)
       break;
@@ -64,7 +64,7 @@ int test9(int n) {
 }
 
 int test10(unsigned n) {
-  int x; // expected-note{{variable 'x' is declared here}} expected-note{{add initialization to silence this warning}}
+  int x; // expected-note{{initialize the variable 'x' to silence this warning}}
   for (unsigned i = 0 ; i < n; ++i) {
     x = 1;
   }
@@ -72,7 +72,7 @@ int test10(unsigned n) {
 }
 
 int test11(unsigned n) {
-  int x; // expected-note{{variable 'x' is declared here}} expected-note{{add initialization to silence this warning}}
+  int x; // expected-note{{initialize the variable 'x' to silence this warning}}
   for (unsigned i = 0 ; i <= n; ++i) {
     x = 1;
   }
@@ -80,7 +80,7 @@ int test11(unsigned n) {
 }
 
 void test12(unsigned n) {
-  for (unsigned i ; n ; ++i) ; // expected-warning{{variable 'i' is uninitialized when used here}} expected-note{{variable 'i' is declared here}} expected-note{{add initialization to silence this warning}}
+  for (unsigned i ; n ; ++i) ; // expected-warning{{variable 'i' is uninitialized when used here}} expected-note{{initialize the variable 'i' to silence this warning}}
 }
 
 int test13() {
@@ -111,7 +111,7 @@ void test16() {
 void test17() {
   // Don't warn multiple times about the same uninitialized variable
   // along the same path.
-  int *x; // expected-note{{variable 'x' is declared here}} expected-note{{add initialization to silence this warning}}
+  int *x; // expected-note{{initialize the variable 'x' to silence this warning}}
   *x = 1; // expected-warning{{variable 'x' is uninitialized when used here}}
   *x = 1; // no-warning
 }
@@ -135,14 +135,14 @@ int test19() {
 }
 
 int test20() {
-  int z; // expected-note{{variable 'z' is declared here}} expected-note{{add initialization to silence this warning}}
+  int z; // expected-note{{initialize the variable 'z' to silence this warning}}
   if ((test19_aux1() + test19_aux2() && test19_aux1()) || test19_aux3(&z))
     return z; // expected-warning{{variable 'z' may be uninitialized when used here}}
   return 0;
 }
 
 int test21(int x, int y) {
-  int z; // expected-note{{variable 'z' is declared here}} expected-note{{add initialization to silence this warning}}
+  int z; // expected-note{{initialize the variable 'z' to silence this warning}}
   if ((x && y) || test19_aux3(&z) || test19_aux2())
     return z; // expected-warning{{variable 'z' may be uninitialized when used here}}
   return 0;
@@ -167,7 +167,7 @@ int test23() {
 // conditionals.  This possibly can be handled by making the CFG itself
 // represent such control-dependencies, but it is a niche case.
 int test24(int flag) {
-  unsigned val; // expected-note{{variable 'val' is declared here}} expected-note{{add initialization to silence this warning}}
+  unsigned val; // expected-note{{initialize the variable 'val' to silence this warning}}
   if (flag)
     val = 1;
   if (!flag)
@@ -176,13 +176,13 @@ int test24(int flag) {
 }
 
 float test25() {
-  float x; // expected-note{{variable 'x' is declared here}} expected-note{{add initialization to silence this warning}}
+  float x; // expected-note{{initialize the variable 'x' to silence this warning}}
   return x; // expected-warning{{variable 'x' is uninitialized when used here}}
 }
 
 typedef int MyInt;
 MyInt test26() {
-  MyInt x; // expected-note{{variable 'x' is declared here}} expected-note{{add initialization to silence this warning}}
+  MyInt x; // expected-note{{initialize the variable 'x' to silence this warning}}
   return x; // expected-warning{{variable 'x' is uninitialized when used here}}
 }
 
@@ -193,12 +193,12 @@ int test27() {
 }
 
 int test28() {
-  int len; // expected-note{{variable 'len' is declared here}} expected-note{{add initialization to silence this warning}}
+  int len; // expected-note{{initialize the variable 'len' to silence this warning}}
   return sizeof(int[len]); // expected-warning{{variable 'len' is uninitialized when used here}}
 }
 
 void test29() {
-  int x; // expected-note{{variable 'x' is declared here}} expected-note{{add initialization to silence this warning}}
+  int x; // expected-note{{initialize the variable 'x' to silence this warning}}
   (void) ^{ (void) x; }; // expected-warning{{variable 'x' is uninitialized when captured by block}}
 }
 
@@ -223,7 +223,7 @@ void test_33() {
 }
 
 int test_34() {
-  int x; // expected-note{{variable 'x' is declared here}} expected-note{{add initialization to silence this warning}}
+  int x; // expected-note{{initialize the variable 'x' to silence this warning}}
   (void) x;
   return x; // expected-warning{{variable 'x' is uninitialized when used here}}
 }
@@ -237,7 +237,7 @@ void test35(int x) {
 // Test handling of indirect goto.
 void test36()
 {
-  void **pc; // expected-note{{variable 'pc' is declared here}} expected-note{{add initialization to silence this warning}}
+  void **pc; // expected-note{{initialize the variable 'pc' to silence this warning}}
   void *dummy[] = { &&L1, &&L2 };
  L1:
     goto *pc; // expected-warning{{variable 'pc' is uninitialized when used here}}
@@ -266,19 +266,19 @@ int test38(int r, int x, int y)
 }
 
 int test39(int x) {
-  int y; // expected-note {{variable 'y' is declared here}} expected-note{{add initialization to silence this warning}}
+  int y; // expected-note{{initialize the variable 'y' to silence this warning}}
   int z = x + y; // expected-warning {{variable 'y' is uninitialized when used here}}
   return z;
 }
 
 
 int test40(int x) {
-  int y; // expected-note {{variable 'y' is declared here}} expected-note{{add initialization to silence this warning}}
+  int y; // expected-note{{initialize the variable 'y' to silence this warning}}
   return x ? 1 : y; // expected-warning {{variable 'y' is uninitialized when used here}}
 }
 
 int test41(int x) {
-  int y; // expected-note {{variable 'y' is declared here}} expected-note{{add initialization to silence this warning}}
+  int y; // expected-note{{initialize the variable 'y' to silence this warning}}
   if (x) y = 1; // no-warning
   return y; // expected-warning {{variable 'y' may be uninitialized when used here}}
 }
@@ -290,14 +290,14 @@ void test42() {
 
 void test43_aux(int x);
 void test43(int i) {
-  int x; // expected-note {{variable 'x' is declared here}} expected-note{{add initialization to silence this warning}}
+  int x; // expected-note{{initialize the variable 'x' to silence this warning}}
   for (i = 0 ; i < 10; i++)
     test43_aux(x++); // expected-warning {{variable 'x' is uninitialized when used here}}
 }
 
 void test44(int i) {
   int x = i;
-  int y; // expected-note {{variable 'y' is declared here}} expected-note{{add initialization to silence this warning}}
+  int y; // expected-note{{initialize the variable 'y' to silence this warning}}
   for (i = 0; i < 10; i++ ) {
     test43_aux(x++); // no-warning
     x += y; // expected-warning {{variable 'y' is uninitialized when used here}}
@@ -313,7 +313,7 @@ int test45(int j) {
 
 void test46()
 {
-  int i; // expected-note {{variable 'i' is declared here}} expected-note{{add initialization to silence this warning}}
+  int i; // expected-note{{initialize the variable 'i' to silence this warning}}
   int j = i ? : 1; // expected-warning {{variable 'i' is uninitialized when used here}}
 }
 
@@ -344,7 +344,7 @@ int test51(void)
 
 // FIXME: This is a false positive, but it tests logical operations in switch statements.
 int test52(int a, int b) {
-  int x;  // expected-note {{variable 'x' is declared here}} expected-note {{add initialization to silence this warning}}
+  int x;  // expected-note {{initialize the variable 'x' to silence this warning}}
   switch (a || b) { // expected-warning {{switch condition has boolean value}}
     case 0:
       x = 1;
@@ -357,14 +357,14 @@ int test52(int a, int b) {
 }
 
 void test53() {
-  int x; // expected-note {{variable 'x' is declared here}} expected-note {{add initialization to silence this warning}}
+  int x; // expected-note {{initialize the variable 'x' to silence this warning}}
   int y = (x);  // expected-warning {{variable 'x' is uninitialized when used here}}
 }
 
 // This CFG caused the uninitialized values warning to inf-loop.
 extern int PR10379_g();
 void PR10379_f(int *len) {
-  int new_len; // expected-note {{variable 'new_len' is declared here}} expected-note{{add initialization to silence this warning}}
+  int new_len; // expected-note{{initialize the variable 'new_len' to silence this warning}}
   for (int i = 0; i < 42 && PR10379_g() == 0; i++) {
     if (PR10379_g() == 1)
       continue;
index 3324215621bf8b8db9c58a90e87b7792d6ef8f66..3c44c7249d51ba3f301a13976ba0cf28a43f294f 100644 (file)
@@ -15,7 +15,7 @@ int init(double *);
 // the destructor in Foo fouls about the minor bit of path-sensitivity in
 // -Wuninitialized.
 double test() {
-  double x; // expected-note {{variable 'x' is declared here}} expected-note{{add initialization to silence this warning}}
+  double x; // expected-note{{initialize the variable 'x' to silence this warning}}
   if (bar() || baz() || Foo() || init(&x))
     return 1.0;
 
index 9abccf07510cb65764240fbfd0ac677b3c68239e..358a5723563fc8cf4558236eb14015ba6287d481 100644 (file)
@@ -26,7 +26,7 @@ void unevaluated_tests() {
 // Warn for glvalue arguments to typeid whose type is polymorphic.
 struct A { virtual ~A() {} };
 void polymorphic_test() {
-  A *a; // expected-note{{declared here}} expected-note{{add initialization}}
+  A *a; // expected-note{{initialize the variable 'a' to silence this warning}}
   (void)typeid(*a); // expected-warning{{variable 'a' is uninitialized when used here }}
 }
 
@@ -50,7 +50,7 @@ unsigned test3_b() {
   return x; // no-warning
 }
 unsigned test3_c() {
-  unsigned x; // expected-note{{declared here}} expected-note{{add initialization}}
+  unsigned x; // expected-note{{initialize the variable 'x' to silence this warning}}
   const bool flag = false;
   if (flag && (x = test3_aux()) == 0) {
     x = 1;
@@ -126,7 +126,7 @@ void test_noop_cast()
 }
 
 void test_noop_cast2() {
-    int x; // expected-note {{declared here}} expected-note {{add initialization}}
+    int x; // expected-note {{initialize the variable 'x' to silence this warning}}
     int y = (int&)x; // expected-warning {{uninitialized when used here}}
 }
 
@@ -137,7 +137,7 @@ void test_bitcasts() {
 }
 
 void test_bitcasts_2() {
-  int x;  // expected-note {{declared here}} expected-note {{add initialization}}
+  int x;  // expected-note {{initialize the variable 'x' to silence this warning}}
   int y = (float &)x; // expected-warning {{uninitialized when used here}}
 }
 
index b5c49184f4bcd1600e73f770c8fa602cff2b01f6..cad0f54b2dd3a1965a5299d96f0b6b57bd962fe6 100644 (file)
@@ -3,7 +3,7 @@
 // Duplicated from uninit-variables.c.
 // Test just to ensure the analysis is working.
 int test1() {
-  int x; // expected-note{{variable 'x' is declared here}} expected-note{{add initialization}}
+  int x; // expected-note{{initialize the variable 'x' to silence this warning}}
   return x; // expected-warning{{variable 'x' is uninitialized when used here}}
 }