forked from OSchip/llvm-project
Check local static variables for self reference on initialization.
llvm-svn: 161909
This commit is contained in:
parent
a078a5e405
commit
b7ed89eb94
|
@ -6313,7 +6313,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
|
||||||
// by a dataflow analysis.
|
// by a dataflow analysis.
|
||||||
// Record types initialized by initializer list are handled here.
|
// Record types initialized by initializer list are handled here.
|
||||||
// Initialization by constructors are handled in TryConstructorInitialization.
|
// Initialization by constructors are handled in TryConstructorInitialization.
|
||||||
if (!VDecl->hasLocalStorage() && !VDecl->isStaticLocal() &&
|
if (!VDecl->hasLocalStorage() &&
|
||||||
(isa<InitListExpr>(Init) || !VDecl->getType()->isRecordType()))
|
(isa<InitListExpr>(Init) || !VDecl->getType()->isRecordType()))
|
||||||
CheckSelfReference(RealDecl, Init);
|
CheckSelfReference(RealDecl, Init);
|
||||||
|
|
||||||
|
|
|
@ -316,3 +316,65 @@ namespace {
|
||||||
G(char (*)[8]) : f3(new F(f3->*ptr)) {} // expected-warning {{field is uninitialized when used here}}
|
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<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}}
|
||||||
|
|
||||||
|
// 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<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}}
|
||||||
|
|
||||||
|
// 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<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}}
|
||||||
|
|
||||||
|
// 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}}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue