diff options
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 9 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 18 | ||||
| -rw-r--r-- | clang/test/SemaCXX/uninitialized.cpp | 24 |
3 files changed, 43 insertions, 8 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 53a647149a8..9c0be3e76fb 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -8276,6 +8276,15 @@ namespace { void VisitObjCMessageExpr(ObjCMessageExpr *E) { return; } + void VisitCXXConstructExpr(CXXConstructExpr *E) { + if (E->getConstructor()->isCopyConstructor()) { + if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->getArg(0))) { + HandleDeclRefExpr(DRE); + } + } + Inherited::VisitCXXConstructExpr(E); + } + void HandleDeclRefExpr(DeclRefExpr *DRE) { Decl* ReferenceDecl = DRE->getDecl(); if (OrigDecl != ReferenceDecl) return; diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 77285edbc0a..e676466e4eb 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -2314,12 +2314,18 @@ namespace { } void VisitCXXConstructExpr(CXXConstructExpr *E) { - if (E->getConstructor()->isCopyConstructor()) - if (ImplicitCastExpr* ICE = dyn_cast<ImplicitCastExpr>(E->getArg(0))) - if (ICE->getCastKind() == CK_NoOp) - if (MemberExpr *ME = dyn_cast<MemberExpr>(ICE->getSubExpr())) - HandleMemberExpr(ME, false /*CheckReferenceOnly*/); - + if (E->getConstructor()->isCopyConstructor()) { + Expr *ArgExpr = E->getArg(0); + if (ImplicitCastExpr* ICE = dyn_cast<ImplicitCastExpr>(ArgExpr)) { + if (ICE->getCastKind() == CK_NoOp) { + ArgExpr = ICE->getSubExpr(); + } + } + + if (MemberExpr *ME = dyn_cast<MemberExpr>(ArgExpr)) { + HandleMemberExpr(ME, false /*CheckReferenceOnly*/); + } + } Inherited::VisitCXXConstructExpr(E); } diff --git a/clang/test/SemaCXX/uninitialized.cpp b/clang/test/SemaCXX/uninitialized.cpp index 677a141f3ec..7b89e5adc93 100644 --- a/clang/test/SemaCXX/uninitialized.cpp +++ b/clang/test/SemaCXX/uninitialized.cpp @@ -127,6 +127,9 @@ void setupA(bool x) { A *a26 = new A(a26->get()); // expected-warning {{variable 'a26' is uninitialized when used within its own initialization}} A *a27 = new A(a27->get2()); // expected-warning {{variable 'a27' is uninitialized when used within its own initialization}} A *a28 = new A(a28->num); // expected-warning {{variable 'a28' is uninitialized when used within its own initialization}} + + const A a29(a29); // expected-warning {{variable 'a29' is uninitialized when used within its own initialization}} + const A a30 = a30; // expected-warning {{variable 'a30' is uninitialized when used within its own initialization}} } bool x; @@ -163,6 +166,9 @@ A *a26 = new A(a26->get()); // expected-warning {{variable 'a26' is uninitial A *a27 = new A(a27->get2()); // expected-warning {{variable 'a27' is uninitialized when used within its own initialization}} A *a28 = new A(a28->num); // expected-warning {{variable 'a28' is uninitialized when used within its own initialization}} +const A a29(a29); // expected-warning {{variable 'a29' is uninitialized when used within its own initialization}} +const A a30 = a30; // expected-warning {{variable 'a30' is uninitialized when used within its own initialization}} + struct B { // POD struct. int x; @@ -209,6 +215,10 @@ void setupB() { B b17 = { b17.x = 5, b17.y = 0 }; B b18 = { b18.x + 1, b18.y }; // expected-warning 2{{variable 'b18' is uninitialized when used within its own initialization}} + + const B b19 = b19; // expected-warning {{variable 'b19' is uninitialized when used within its own initialization}} + const B b20(b20); // expected-warning {{variable 'b20' is uninitialized when used within its own initialization}} + } B b1; @@ -234,6 +244,8 @@ B* b16 = getPtrB(b16->y); // expected-warning {{variable 'b16' is uninitialized B b17 = { b17.x = 5, b17.y = 0 }; B b18 = { b18.x + 1, b18.y }; // expected-warning 2{{variable 'b18' is uninitialized when used within its own initialization}} +const B b19 = b19; // expected-warning {{variable 'b19' is uninitialized when used within its own initialization}} +const B b20(b20); // expected-warning {{variable 'b20' is uninitialized when used within its own initialization}} // Also test similar constructs in a field's initializer. struct S { @@ -385,6 +397,11 @@ namespace { G(char (*)[7]) : f3(f3->*f_ptr) {} // expected-warning {{field 'f3' is uninitialized when used here}} G(char (*)[8]) : f3(new F(f3->*ptr)) {} // expected-warning {{field 'f3' is uninitialized when used here}} }; + + struct H { + H() : a(a) {} // expected-warning {{field 'a' is uninitialized when used here}} + const A a; + }; } namespace statics { @@ -555,7 +572,7 @@ namespace record_fields { B(char (*)[9]) : a(normal(a)) {} // expected-warning {{uninitialized}} }; struct C { - C() {} // expected-note4{{in this constructor}} + C() {} // expected-note5{{in this constructor}} A a1 = a1; // expected-warning {{uninitialized}} A a2 = a2.get(); // expected-warning {{uninitialized}} A a3 = a3.num(); @@ -565,8 +582,9 @@ namespace record_fields { A a7 = const_ref(a7); A a8 = pointer(&a8); A a9 = normal(a9); // expected-warning {{uninitialized}} + const A a10 = a10; // expected-warning {{uninitialized}} }; - struct D { // expected-note4{{in the implicit default constructor}} + struct D { // expected-note5{{in the implicit default constructor}} A a1 = a1; // expected-warning {{uninitialized}} A a2 = a2.get(); // expected-warning {{uninitialized}} A a3 = a3.num(); @@ -576,6 +594,7 @@ namespace record_fields { A a7 = const_ref(a7); A a8 = pointer(&a8); A a9 = normal(a9); // expected-warning {{uninitialized}} + const A a10 = a10; // expected-warning {{uninitialized}} }; D d; struct E { @@ -588,6 +607,7 @@ namespace record_fields { A a7 = const_ref(a7); A a8 = pointer(&a8); A a9 = normal(a9); + const A a10 = a10; }; } |

