From b7ed89eb940da9bdfbbb3b1ee3c77a8ec2328aa8 Mon Sep 17 00:00:00 2001 From: Richard Trieu Date: Tue, 14 Aug 2012 23:50:52 +0000 Subject: [PATCH] Check local static variables for self reference on initialization. llvm-svn: 161909 --- clang/lib/Sema/SemaDecl.cpp | 2 +- clang/test/SemaCXX/uninitialized.cpp | 62 ++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index b014b4cd9fcd..6526d01e08b8 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -6313,7 +6313,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, // by a dataflow analysis. // Record types initialized by initializer list are handled here. // Initialization by constructors are handled in TryConstructorInitialization. - if (!VDecl->hasLocalStorage() && !VDecl->isStaticLocal() && + if (!VDecl->hasLocalStorage() && (isa(Init) || !VDecl->getType()->isRecordType())) CheckSelfReference(RealDecl, Init); diff --git a/clang/test/SemaCXX/uninitialized.cpp b/clang/test/SemaCXX/uninitialized.cpp index 13d287bf1af6..890f21293030 100644 --- a/clang/test/SemaCXX/uninitialized.cpp +++ b/clang/test/SemaCXX/uninitialized.cpp @@ -316,3 +316,65 @@ namespace { G(char (*)[8]) : f3(new F(f3->*ptr)) {} // expected-warning {{field is uninitialized when used here}} }; } + +namespace statics { + 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 e = static_cast(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}} + + // Thes don't warn as they don't require the value. + static int g = sizeof(g); + int gg = g; // Silence unneeded warning + static void* ptr = &ptr; + static int h = bar(&h); + static int i = boo(i); + 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}} + + 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(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}} + + // Thes don't warn as they don't require the value. + static int g = sizeof(g); + static void* ptr = &ptr; + static int h = bar(&h); + static int i = boo(i); + 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}} + 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(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}} + + // Thes don't warn as they don't require the value. + static int g = sizeof(g); + static void* ptr = &ptr; + static int h = bar(&h); + static int i = boo(i); + 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}} + } + } +}