summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/DiagnosticGroups.td4
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td3
-rw-r--r--clang/lib/Sema/SemaDecl.cpp12
-rw-r--r--clang/test/SemaCXX/uninitialized.cpp32
4 files changed, 31 insertions, 20 deletions
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 24c4ef3b40e..8a2d5965869 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -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">;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index c23d9eee482..c3f034a53a4 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -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>;
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 29d3176bfb5..dbdbc3d6a2c 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -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()
diff --git a/clang/test/SemaCXX/uninitialized.cpp b/clang/test/SemaCXX/uninitialized.cpp
index 6d7d548521b..3a41114e871 100644
--- a/clang/test/SemaCXX/uninitialized.cpp
+++ b/clang/test/SemaCXX/uninitialized.cpp
@@ -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}}
}
}
}
OpenPOWER on IntegriCloud