Reapply r172878 with test case.
authorTed Kremenek <kremenek@apple.com>
Sat, 19 Jan 2013 04:33:14 +0000 (04:33 +0000)
committerTed Kremenek <kremenek@apple.com>
Sat, 19 Jan 2013 04:33:14 +0000 (04:33 +0000)
llvm-svn: 172888

clang/include/clang/Basic/DiagnosticGroups.td
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Sema/SemaDecl.cpp
clang/test/SemaCXX/uninitialized.cpp

index 24c4ef3..8a2d596 100644 (file)
@@ -259,7 +259,9 @@ def UndefinedReinterpretCast : DiagGroup<"undefined-reinterpret-cast">;
 def Unicode  : DiagGroup<"unicode">;
 def UninitializedMaybe : DiagGroup<"conditional-uninitialized">;
 def UninitializedSometimes : DiagGroup<"sometimes-uninitialized">;
-def Uninitialized  : DiagGroup<"uninitialized", [UninitializedSometimes]>;
+def UninitializedStaticSelfInit : DiagGroup<"static-self-init">;
+def Uninitialized  : DiagGroup<"uninitialized", [UninitializedSometimes,
+                                                 UninitializedStaticSelfInit]>;
 def UnknownPragmas : DiagGroup<"unknown-pragmas">;
 def UnknownWarningOption : DiagGroup<"unknown-warning-option">;
 def NSobjectAttribute : DiagGroup<"NSObject-attribute">;
index c23d9ee..c3f034a 100644 (file)
@@ -1292,6 +1292,9 @@ def warn_field_is_uninit : Warning<"field %0 is uninitialized when used here">,
 def warn_reference_field_is_uninit : Warning<
   "reference %0 is not yet bound to a value when used here">,
   InGroup<Uninitialized>;
+def warn_static_self_reference_in_init : Warning<
+  "static variable %0 is suspiciously used within its own initialization">,
+  InGroup<UninitializedStaticSelfInit>;
 def warn_uninit_self_reference_in_init : Warning<
   "variable %0 is uninitialized when used within its own initialization">,
   InGroup<Uninitialized>;
index 29d3176..dbdbc3d 100644 (file)
@@ -6685,9 +6685,15 @@ namespace {
     void HandleDeclRefExpr(DeclRefExpr *DRE) {
       Decl* ReferenceDecl = DRE->getDecl();
       if (OrigDecl != ReferenceDecl) return;
-      unsigned diag = isReferenceType
-          ? diag::warn_uninit_self_reference_in_reference_init
-          : diag::warn_uninit_self_reference_in_init;
+      unsigned diag;
+      if (isReferenceType) {
+        diag = diag::warn_uninit_self_reference_in_reference_init;
+      } else if (cast<VarDecl>(OrigDecl)->isStaticLocal()) {
+        diag = diag::warn_static_self_reference_in_init;
+      } else {
+        diag = diag::warn_uninit_self_reference_in_init;
+      }
+
       S.DiagRuntimeBehavior(DRE->getLocStart(), DRE,
                             S.PDiag(diag)
                               << DRE->getNameInfo().getName()
index 6d7d548..3a41114 100644 (file)
@@ -406,11 +406,11 @@ namespace statics {
 
   void test() {
     static int a = a; // no-warning: used to signal intended lack of initialization.
-    static int b = b + 1; // expected-warning {{variable 'b' is uninitialized when used within its own initialization}}
-    static int c = (c + c); // expected-warning 2{{variable 'c' is uninitialized when used within its own initialization}}
-    static int d = ({ d + d ;}); // expected-warning 2{{variable 'd' is uninitialized when used within its own initialization}}
-    static int e = static_cast<long>(e) + 1; // expected-warning {{variable 'e' is uninitialized when used within its own initialization}}
-    static int f = foo(f); // expected-warning {{variable 'f' is uninitialized when used within its own initialization}}
+    static int b = b + 1; // expected-warning {{static variable 'b' is suspiciously used within its own initialization}}
+    static int c = (c + c); // expected-warning 2{{static variable 'c' is suspiciously used within its own initialization}}
+    static int d = ({ d + d ;}); // expected-warning 2{{static variable 'd' is suspiciously used within its own initialization}}
+    static int e = static_cast<long>(e) + 1; // expected-warning {{static variable 'e' is suspiciously used within its own initialization}}
+    static int f = foo(f); // expected-warning {{static variable 'f' is suspiciously used within its own initialization}}
 
     // Thes don't warn as they don't require the value.
     static int g = sizeof(g);
@@ -420,16 +420,16 @@ namespace statics {
     static int j = far(j);
     static int k = __alignof__(k);
 
-    static int l = k ? l : l;  // expected-warning 2{{variable 'l' is uninitialized when used within its own initialization}}
-    static int m = 1 + (k ? m : m);  // expected-warning 2{{variable 'm' is uninitialized when used within its own initialization}}
-    static int n = -n;  // expected-warning {{variable 'n' is uninitialized when used within its own initialization}}
+    static int l = k ? l : l;  // expected-warning 2{{static variable 'l' is suspiciously used within its own initialization}}
+    static int m = 1 + (k ? m : m);  // expected-warning 2{{static variable 'm' is suspiciously used within its own initialization}}
+    static int n = -n;  // expected-warning {{static variable 'n' is suspiciously used within its own initialization}}
    for (;;) {
       static int a = a; // no-warning: used to signal intended lack of initialization.
-      static int b = b + 1; // expected-warning {{variable 'b' is uninitialized when used within its own initialization}}
-      static int c = (c + c); // expected-warning 2{{variable 'c' is uninitialized when used within its own initialization}}
-      static int d = ({ d + d ;}); // expected-warning 2{{variable 'd' is uninitialized when used within its own initialization}}
-      static int e = static_cast<long>(e) + 1; // expected-warning {{variable 'e' is uninitialized when used within its own initialization}}
-      static int f = foo(f); // expected-warning {{variable 'f' is uninitialized when used within its own initialization}}
+      static int b = b + 1; // expected-warning {{static variable 'b' is suspiciously used within its own initialization}}
+      static int c = (c + c); // expected-warning 2{{static variable 'c' is suspiciously used within its own initialization}}
+      static int d = ({ d + d ;}); // expected-warning 2{{static variable 'd' is suspiciously used within its own initialization}}
+      static int e = static_cast<long>(e) + 1; // expected-warning {{static variable 'e' is suspiciously used within its own initialization}}
+      static int f = foo(f); // expected-warning {{static variable 'f' is suspiciously used within its own initialization}}
 
       // Thes don't warn as they don't require the value.
       static int g = sizeof(g);
@@ -439,9 +439,9 @@ namespace statics {
       static int j = far(j);
       static int k = __alignof__(k);
 
-      static int l = k ? l : l;  // expected-warning 2{{variable 'l' is uninitialized when used within its own initialization}}
-      static int m = 1 + (k ? m : m); // expected-warning 2{{variable 'm' is uninitialized when used within its own initialization}}
-      static int n = -n;  // expected-warning {{variable 'n' is uninitialized when used within its own initialization}}
+      static int l = k ? l : l;  // expected-warning 2{{static variable 'l' is suspiciously used within its own initialization}}
+      static int m = 1 + (k ? m : m); // expected-warning 2{{static variable 'm' is suspiciously used within its own initialization}}
+      static int n = -n;  // expected-warning {{static variable 'n' is suspiciously used within its own initialization}}
     }
   }
 }