From: Richard Trieu Date: Fri, 31 Oct 2014 21:10:22 +0000 (+0000) Subject: Have -Wuninitialized catch uninitalized use in overloaded operator arguments. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0ca36e7c00579da9845602f1f981a8cecebffe01;p=clang Have -Wuninitialized catch uninitalized use in overloaded operator arguments. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@221000 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 3d0ebf277d..734a01e2e3 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -8434,11 +8434,14 @@ namespace { } void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) { - if (E->getNumArgs() > 0) - if (DeclRefExpr *DRE = dyn_cast(E->getArg(0))) - HandleDeclRefExpr(DRE); + Expr *Callee = E->getCallee(); + + if (isa(Callee)) + return Inherited::VisitCXXOperatorCallExpr(E); - Inherited::VisitCXXOperatorCallExpr(E); + Visit(Callee); + for (auto Arg: E->arguments()) + HandleValue(Arg->IgnoreParenImpCasts()); } void VisitUnaryOperator(UnaryOperator *E) { diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index adbcafe433..233ab615a5 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -2494,6 +2494,17 @@ namespace { Inherited::VisitCallExpr(E); } + void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) { + Expr *Callee = E->getCallee(); + + if (isa(Callee)) + return Inherited::VisitCXXOperatorCallExpr(E); + + Visit(Callee); + for (auto Arg : E->arguments()) + HandleValue(Arg->IgnoreParenImpCasts(), false /*AddressOf*/); + } + void VisitBinaryOperator(BinaryOperator *E) { // If a field assignment is detected, remove the field from the // uninitiailized field set. diff --git a/test/SemaCXX/uninitialized.cpp b/test/SemaCXX/uninitialized.cpp index 61dabb2d00..d9fb9eebc2 100644 --- a/test/SemaCXX/uninitialized.cpp +++ b/test/SemaCXX/uninitialized.cpp @@ -183,8 +183,12 @@ class A { A(A *a) {} A(A &&a) {} ~A(); + bool operator!(); + bool operator!=(const A&); }; +bool operator!=(int, const A&); + A getA() { return A(); } A getA(int x) { return A(); } A getA(A* a) { return A(); } @@ -243,6 +247,13 @@ void setupA(bool x) { A a38({a38}); // expected-warning {{variable 'a38' is uninitialized when used within its own initialization}} A a39 = {a39}; // expected-warning {{variable 'a39' is uninitialized when used within its own initialization}} A a40 = A({a40}); // expected-warning {{variable 'a40' is uninitialized when used within its own initialization}} + + A a41 = !a41; // expected-warning {{variable 'a41' is uninitialized when used within its own initialization}} + A a42 = !(a42); // expected-warning {{variable 'a42' is uninitialized when used within its own initialization}} + A a43 = a43 != a42; // expected-warning {{variable 'a43' is uninitialized when used within its own initialization}} + A a44 = a43 != a44; // expected-warning {{variable 'a44' is uninitialized when used within its own initialization}} + A a45 = a45 != a45; // expected-warning 2{{variable 'a45' is uninitialized when used within its own initialization}} + A a46 = 0 != a46; // expected-warning {{variable 'a46' is uninitialized when used within its own initialization}} } bool cond; @@ -295,6 +306,14 @@ A a38({a38}); // expected-warning {{variable 'a38' is uninitialized when used w A a39 = {a39}; // expected-warning {{variable 'a39' is uninitialized when used within its own initialization}} A a40 = A({a40}); // expected-warning {{variable 'a40' is uninitialized when used within its own initialization}} +A a41 = !a41; // expected-warning {{variable 'a41' is uninitialized when used within its own initialization}} +A a42 = !(a42); // expected-warning {{variable 'a42' is uninitialized when used within its own initialization}} +A a43 = a43 != a42; // expected-warning {{variable 'a43' is uninitialized when used within its own initialization}} +A a44 = a43 != a44; // expected-warning {{variable 'a44' is uninitialized when used within its own initialization}} +A a45 = a45 != a45; // expected-warning 2{{variable 'a45' is uninitialized when used within its own initialization}} + +A a46 = 0 != a46; // expected-warning {{variable 'a46' is uninitialized when used within its own initialization}} + class T { A a, a2; const A c_a; @@ -348,6 +367,13 @@ class T { T(bool (*)[38]) : a({a}) {} // expected-warning {{field 'a' is uninitialized when used here}} T(bool (*)[39]) : a{a} {} // expected-warning {{field 'a' is uninitialized when used here}} T(bool (*)[40]) : a({a}) {} // expected-warning {{field 'a' is uninitialized when used here}} + + T(bool (*)[41]) : a(!a) {} // expected-warning {{field 'a' is uninitialized when used here}} + T(bool (*)[42]) : a(!(a)) {} // expected-warning {{field 'a' is uninitialized when used here}} + T(bool (*)[43]) : a(), a2(a2 != a) {} // expected-warning {{field 'a2' is uninitialized when used here}} + T(bool (*)[44]) : a(), a2(a != a2) {} // expected-warning {{field 'a2' is uninitialized when used here}} + T(bool (*)[45]) : a(a != a) {} // expected-warning 2{{field 'a' is uninitialized when used here}} + T(bool (*)[46]) : a(0 != a) {} // expected-warning {{field 'a' is uninitialized when used here}} }; struct B {