]> granicus.if.org Git - clang/commitdiff
Have -Wuninitialized catch uninitalized use in overloaded operator arguments.
authorRichard Trieu <rtrieu@google.com>
Fri, 31 Oct 2014 21:10:22 +0000 (21:10 +0000)
committerRichard Trieu <rtrieu@google.com>
Fri, 31 Oct 2014 21:10:22 +0000 (21:10 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@221000 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDecl.cpp
lib/Sema/SemaDeclCXX.cpp
test/SemaCXX/uninitialized.cpp

index 3d0ebf277d00092aae724157fa2efdce63798bc8..734a01e2e30c0b09c0be550dbd0fff3cd7d786cb 100644 (file)
@@ -8434,11 +8434,14 @@ namespace {
     }
 
     void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
-      if (E->getNumArgs() > 0)
-        if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->getArg(0)))
-          HandleDeclRefExpr(DRE);
+      Expr *Callee = E->getCallee();
+
+      if (isa<UnresolvedLookupExpr>(Callee))
+        return Inherited::VisitCXXOperatorCallExpr(E);
 
-      Inherited::VisitCXXOperatorCallExpr(E);
+      Visit(Callee);
+      for (auto Arg: E->arguments())
+        HandleValue(Arg->IgnoreParenImpCasts());
     }
 
     void VisitUnaryOperator(UnaryOperator *E) {
index adbcafe4339d36e07388c09a72ca1f93bc7cee19..233ab615a52fde02acb1d7e680ffb49d5c060f28 100644 (file)
@@ -2494,6 +2494,17 @@ namespace {
       Inherited::VisitCallExpr(E);
     }
 
+    void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
+      Expr *Callee = E->getCallee();
+
+      if (isa<UnresolvedLookupExpr>(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.
index 61dabb2d0010d636b8dc5e4f6d6c7d5dd54a9ac1..d9fb9eebc2e9e807381568ab746b6b77fcb0a2a9 100644 (file)
@@ -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 {