aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Trieu <rtrieu@google.com>2012-08-06 21:09:23 +0000
committerRichard Trieu <rtrieu@google.com>2012-08-06 21:09:23 +0000
commite27a08aa814cb2fe9367163edd612c90aad57789 (patch)
tree12b69984d38e052f88542c250f6a0f84a3ca6b75
parentcbea860417eea485be5bc34e6a61f267cf180a56 (diff)
For global record types, the self reference checker was called twice, resulting
in duplicate -Wuninitialized warnings. Change so that only the check in TryConstructorInitialization() will be used and a single warning be emitted. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@161345 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaDecl.cpp5
-rw-r--r--test/SemaCXX/uninitialized.cpp23
2 files changed, 27 insertions, 1 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index c1086fbe14..a512c0364c 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -6310,7 +6310,10 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
// Check for self-references within variable initializers.
// Variables declared within a function/method body are handled
// by a dataflow analysis.
- if (!VDecl->hasLocalStorage() && !VDecl->isStaticLocal())
+ // Record types initialized by initializer list are handled here.
+ // Initialization by constructors are handled in TryConstructorInitialization.
+ if (!VDecl->hasLocalStorage() && !VDecl->isStaticLocal() &&
+ (isa<InitListExpr>(Init) || !VDecl->getType()->isRecordType()))
CheckSelfReference(RealDecl, Init);
ParenListExpr *CXXDirectInit = dyn_cast<ParenListExpr>(Init);
diff --git a/test/SemaCXX/uninitialized.cpp b/test/SemaCXX/uninitialized.cpp
index e827236231..13d287bf1a 100644
--- a/test/SemaCXX/uninitialized.cpp
+++ b/test/SemaCXX/uninitialized.cpp
@@ -116,6 +116,29 @@ void setupA(bool x) {
A a19 = getA(x ? a19 : a17); // expected-warning {{variable 'a19' is uninitialized when used within its own initialization}}
}
+bool x;
+
+A a1;
+A a2(a1.get());
+A a3(a1);
+A a4(&a4);
+A a5(a5.zero());
+A a6(a6.ONE);
+A a7 = getA();
+A a8 = getA(a8.TWO);
+A a9 = getA(&a9);
+A a10(a10.count);
+
+A a11(a11); // expected-warning {{variable 'a11' is uninitialized when used within its own initialization}}
+A a12(a12.get()); // expected-warning {{variable 'a12' is uninitialized when used within its own initialization}}
+A a13(a13.num); // expected-warning {{variable 'a13' is uninitialized when used within its own initialization}}
+A a14 = A(a14); // expected-warning {{variable 'a14' is uninitialized when used within its own initialization}}
+A a15 = getA(a15.num); // expected-warning {{variable 'a15' is uninitialized when used within its own initialization}}
+A a16(&a16.num); // expected-warning {{variable 'a16' is uninitialized when used within its own initialization}}
+A a17(a17.get2()); // expected-warning {{variable 'a17' is uninitialized when used within its own initialization}}
+A a18 = x ? a18 : a17; // expected-warning {{variable 'a18' is uninitialized when used within its own initialization}}
+A a19 = getA(x ? a19 : a17); // expected-warning {{variable 'a19' is uninitialized when used within its own initialization}}
+
struct B {
// POD struct.
int x;