r216627 - More -Wuninitialized updates

Richard Trieu rtrieu at google.com
Wed Aug 27 15:15:11 PDT 2014


Author: rtrieu
Date: Wed Aug 27 17:15:10 2014
New Revision: 216627

URL: http://llvm.org/viewvc/llvm-project?rev=216627&view=rev
Log:
More -Wuninitialized updates

Fix r216438 to catch more complicated self-initialized in std::move.  For
instance, "Foo f = std::move(cond ? OtherFoo : (UNUSED_VALUE, f));"

Make sure that BinaryConditionalOperator, ConditionalOperator, BinaryOperator
with comma operator, and OpaqueValueExpr perform the correct usage forwarding
across the three uninitialized value checkers.


Modified:
    cfe/trunk/lib/Analysis/UninitializedValues.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/test/SemaCXX/uninitialized.cpp

Modified: cfe/trunk/lib/Analysis/UninitializedValues.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/UninitializedValues.cpp?rev=216627&r1=216626&r2=216627&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/UninitializedValues.cpp (original)
+++ cfe/trunk/lib/Analysis/UninitializedValues.cpp Wed Aug 27 17:15:10 2014
@@ -300,13 +300,28 @@ void ClassifyRefs::classify(const Expr *
   // The result of a ?: could also be an lvalue.
   E = E->IgnoreParens();
   if (const ConditionalOperator *CO = dyn_cast<ConditionalOperator>(E)) {
-    const Expr *TrueExpr = CO->getTrueExpr();
-    if (!isa<OpaqueValueExpr>(TrueExpr))
-      classify(TrueExpr, C);
+    classify(CO->getTrueExpr(), C);
     classify(CO->getFalseExpr(), C);
     return;
   }
 
+  if (const BinaryConditionalOperator *BCO =
+          dyn_cast<BinaryConditionalOperator>(E)) {
+    classify(BCO->getFalseExpr(), C);
+    return;
+  }
+
+  if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E)) {
+    classify(OVE->getSourceExpr(), C);
+    return;
+  }
+
+  if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
+    if (BO->getOpcode() == BO_Comma)
+      classify(BO->getRHS(), C);
+    return;
+  }
+
   FindVarResult Var = findVar(E, DC);
   if (const DeclRefExpr *DRE = Var.getDeclRefExpr())
     Classification[DRE] = std::max(Classification[DRE], C);

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=216627&r1=216626&r2=216627&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Aug 27 17:15:10 2014
@@ -8211,7 +8211,7 @@ namespace {
     void HandleValue(Expr *E) {
       if (isReferenceType)
         return;
-      E = E->IgnoreParenImpCasts();
+      E = E->IgnoreParens();
       if (DeclRefExpr* DRE = dyn_cast<DeclRefExpr>(E)) {
         HandleDeclRefExpr(DRE);
         return;
@@ -8223,6 +8223,23 @@ namespace {
         return;
       }
 
+      if (BinaryConditionalOperator *BCO =
+              dyn_cast<BinaryConditionalOperator>(E)) {
+        HandleValue(BCO->getFalseExpr());
+        return;
+      }
+
+      if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E)) {
+        HandleValue(OVE->getSourceExpr());
+        return;
+      }
+
+      if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
+        if (BO->getOpcode() == BO_Comma)
+          HandleValue(BO->getRHS());
+        return;
+      }
+
       if (isa<MemberExpr>(E)) {
         Expr *Base = E->IgnoreParenImpCasts();
         while (MemberExpr *ME = dyn_cast<MemberExpr>(Base)) {
@@ -8313,9 +8330,7 @@ namespace {
       if (E->getNumArgs() == 1) {
         if (FunctionDecl *FD = E->getDirectCallee()) {
           if (FD->getIdentifier() && FD->getIdentifier()->isStr("move")) {
-            if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->getArg(0))) {
-              HandleDeclRefExpr(DRE);
-            }
+            HandleValue(E->getArg(0));
           }
         }
       }

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=216627&r1=216626&r2=216627&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed Aug 27 17:15:10 2014
@@ -2279,11 +2279,15 @@ namespace {
 
       if (BinaryConditionalOperator *BCO =
               dyn_cast<BinaryConditionalOperator>(E)) {
-        HandleValue(BCO->getCommon());
         HandleValue(BCO->getFalseExpr());
         return;
       }
 
+      if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E)) {
+        HandleValue(OVE->getSourceExpr());
+        return;
+      }
+
       if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
         switch (BO->getOpcode()) {
         default:
@@ -2342,9 +2346,7 @@ namespace {
       if (E->getNumArgs() == 1) {
         if (FunctionDecl *FD = E->getDirectCallee()) {
           if (FD->getIdentifier() && FD->getIdentifier()->isStr("move")) {
-            if (MemberExpr *ME = dyn_cast<MemberExpr>(E->getArg(0))) {
-              HandleMemberExpr(ME, false /*CheckReferenceOnly*/);
-            }
+            HandleValue(E->getArg(0));
           }
         }
       }

Modified: cfe/trunk/test/SemaCXX/uninitialized.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/uninitialized.cpp?rev=216627&r1=216626&r2=216627&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/uninitialized.cpp (original)
+++ cfe/trunk/test/SemaCXX/uninitialized.cpp Wed Aug 27 17:15:10 2014
@@ -39,6 +39,9 @@ int n = -n;  // expected-warning {{varia
 int o = std::move(o); // expected-warning {{variable 'o' is uninitialized when used within its own initialization}}
 const int p = std::move(p); // expected-warning {{variable 'p' is uninitialized when used within its own initialization}}
 int q = moved(std::move(q)); // expected-warning {{variable 'q' is uninitialized when used within its own initialization}}
+int r = std::move((p ? q : (18, r))); // expected-warning {{variable 'r' is uninitialized when used within its own initialization}}
+int s = r ?: s; // expected-warning {{variable 's' is uninitialized when used within its own initialization}}
+int t = t ?: s; // expected-warning {{variable 't' is uninitialized when used within its own initialization}}
 
 void test_stuff () {
   int a = a; // no-warning: used to signal intended lack of initialization.
@@ -62,6 +65,9 @@ void test_stuff () {
   int o = std::move(o);  // expected-warning {{variable 'o' is uninitialized when used within its own initialization}}
   const int p = std::move(p);  // expected-warning {{variable 'p' is uninitialized when used within its own initialization}}
   int q = moved(std::move(q));  // expected-warning {{variable 'q' is uninitialized when used within its own initialization}}
+  int r = std::move((p ? q : (18, r))); // expected-warning {{variable 'r' is uninitialized when used within its own initialization}}
+  int s = r ?: s; // expected-warning {{variable 's' is uninitialized when used within its own initialization}}
+  int t = t ?: s; // expected-warning {{variable 't' is uninitialized when used within its own initialization}}
 
   for (;;) {
     int a = a; // no-warning: used to signal intended lack of initialization.
@@ -85,6 +91,9 @@ void test_stuff () {
     int o = std::move(o);  // expected-warning {{variable 'o' is uninitialized when used within its own initialization}}
     const int p = std::move(p);  // expected-warning {{variable 'p' is uninitialized when used within its own initialization}}
     int q = moved(std::move(q));  // expected-warning {{variable 'q' is uninitialized when used within its own initialization}}
+    int r = std::move((p ? q : (18, r))); // expected-warning {{variable 'r' is uninitialized when used within its own initialization}}
+    int s = r ?: s; // expected-warning {{variable 's' is uninitialized when used within its own initialization}}
+    int t = t ?: s; // expected-warning {{variable 't' is uninitialized when used within its own initialization}}
   }
 }
 
@@ -158,6 +167,7 @@ void setupA(bool x) {
   A a32 = moveA(std::move(a32));  // expected-warning {{variable 'a32' is uninitialized when used within its own initialization}}
   A a33 = A(std::move(a33));   // expected-warning {{variable 'a33' is uninitialized when used within its own initialization}}
   A a34(std::move(a34));   // expected-warning {{variable 'a34' is uninitialized when used within its own initialization}}
+  A a35 = std::move(x ? a34 : (37, a35));  // expected-warning {{variable 'a35' is uninitialized when used within its own initialization}}
 }
 
 bool x;
@@ -201,6 +211,7 @@ A a31 = std::move(a31);  // expected-war
 A a32 = moveA(std::move(a32));  // expected-warning {{variable 'a32' is uninitialized when used within its own initialization}}
 A a33 = A(std::move(a33));   // expected-warning {{variable 'a33' is uninitialized when used within its own initialization}}
 A a34(std::move(a34));   // expected-warning {{variable 'a34' is uninitialized when used within its own initialization}}
+A a35 = std::move(x ? a34 : (37, a35));  // expected-warning {{variable 'a35' is uninitialized when used within its own initialization}}
 struct B {
   // POD struct.
   int x;
@@ -218,7 +229,7 @@ B* getPtrB(int x) { return 0; };
 B* getPtrB(int *x) { return 0; };
 B* getPtrB(B **b) { return 0; };
 
-void setupB() {
+void setupB(bool x) {
   B b1;
   B b2(b1);
   B b3 = { 5, &b3.x };
@@ -255,6 +266,7 @@ void setupB() {
   B b21 = std::move(b21);  // expected-warning {{variable 'b21' is uninitialized when used within its own initialization}}
   B b22 = moveB(std::move(b22));  // expected-warning {{variable 'b22' is uninitialized when used within its own initialization}}
   B b23 = B(std::move(b23));   // expected-warning {{variable 'b23' is uninitialized when used within its own initialization}}
+  B b24 = std::move(x ? b23 : (18, b24));  // expected-warning {{variable 'b24' is uninitialized when used within its own initialization}}
 }
 
 B b1;
@@ -286,6 +298,7 @@ const B b20(b20);  // expected-warning {
 B b21 = std::move(b21);  // expected-warning {{variable 'b21' is uninitialized when used within its own initialization}}
 B b22 = moveB(std::move(b22));  // expected-warning {{variable 'b22' is uninitialized when used within its own initialization}}
 B b23 = B(std::move(b23));   // expected-warning {{variable 'b23' is uninitialized when used within its own initialization}}
+B b24 = std::move(x ? b23 : (18, b24));  // expected-warning {{variable 'b24' is uninitialized when used within its own initialization}}
 
 // Also test similar constructs in a field's initializer.
 struct S {
@@ -412,6 +425,8 @@ namespace {
     E(char (*)[12]) : a((b + c, c, a)) {} // expected-warning {{field 'a' is uninitialized when used here}}
     E(char (*)[13]) : a((a, a, a, a)) {} // expected-warning {{field 'a' is uninitialized when used here}}
     E(char (*)[14]) : a((b, c, c)) {}
+    E(char (*)[15]) : a(b ?: a) {} // expected-warning {{field 'a' is uninitialized when used here}}
+    E(char (*)[16]) : a(a ?: b) {} // expected-warning {{field 'a' is uninitialized when used here}}
   };
 
   struct F {
@@ -463,6 +478,12 @@ namespace statics {
   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}}
+  static int o = std::move(o); // expected-warning {{variable 'o' is uninitialized when used within its own initialization}}
+  static const int p = std::move(p); // expected-warning {{variable 'p' is uninitialized when used within its own initialization}}
+  static int q = moved(std::move(q)); // expected-warning {{variable 'q' is uninitialized when used within its own initialization}}
+  static int r = std::move((p ? q : (18, r))); // expected-warning {{variable 'r' is uninitialized when used within its own initialization}}
+  static int s = r ?: s; // expected-warning {{variable 's' is uninitialized when used within its own initialization}}
+  static int t = t ?: s; // expected-warning {{variable 't' is uninitialized when used within its own initialization}}
 
   void test() {
     static int a = a; // no-warning: used to signal intended lack of initialization.
@@ -483,6 +504,12 @@ namespace statics {
     static int l = k ? l : l;  // expected-warning 2{{static variable 'l' is suspiciously used within its own initialization}}
     static int m = 1 + (k ? m : m);  // expected-warning 2{{static variable 'm' is suspiciously used within its own initialization}}
     static int n = -n;  // expected-warning {{static variable 'n' is suspiciously used within its own initialization}}
+    static int o = std::move(o);  // expected-warning {{static variable 'o' is suspiciously used within its own initialization}}
+    static const int p = std::move(p);  // expected-warning {{static variable 'p' is suspiciously used within its own initialization}}
+    static int q = moved(std::move(q));  // expected-warning {{static variable 'q' is suspiciously used within its own initialization}}
+    static int r = std::move((p ? q : (18, r)));  // expected-warning {{static variable 'r' is suspiciously used within its own initialization}}
+    static int s = r ?: s;  // expected-warning {{static variable 's' is suspiciously used within its own initialization}}
+    static int t = t ?: s;  // expected-warning {{static variable 't' is suspiciously 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 {{static variable 'b' is suspiciously used within its own initialization}}
@@ -502,6 +529,12 @@ namespace statics {
       static int l = k ? l : l;  // expected-warning 2{{static variable 'l' is suspiciously used within its own initialization}}
       static int m = 1 + (k ? m : m); // expected-warning 2{{static variable 'm' is suspiciously used within its own initialization}}
       static int n = -n;  // expected-warning {{static variable 'n' is suspiciously used within its own initialization}}
+      static int o = std::move(o);  // expected-warning {{static variable 'o' is suspiciously used within its own initialization}}
+      static const int p = std::move(p);  // expected-warning {{static variable 'p' is suspiciously used within its own initialization}}
+      static int q = moved(std::move(q));  // expected-warning {{static variable 'q' is suspiciously used within its own initialization}}
+      static int r = std::move((p ? q : (18, r)));  // expected-warning {{static variable 'r' is suspiciously used within its own initialization}}
+      static int s = r ?: s;  // expected-warning {{static variable 's' is suspiciously used within its own initialization}}
+      static int t = t ?: s;  // expected-warning {{static variable 't' is suspiciously used within its own initialization}}
     }
   }
 }
@@ -530,13 +563,15 @@ namespace references {
   int &b(b); // expected-warning{{reference 'b' is not yet bound to a value when used within its own initialization}}
   int &c = a ? b : c; // expected-warning{{reference 'c' is not yet bound to a value when used within its own initialization}}
   int &d{d}; // expected-warning{{reference 'd' is not yet bound to a value when used within its own initialization}}
+  int &e = d ?: e; // expected-warning{{reference 'e' is not yet bound to a value when used within its own initialization}}
+  int &f = f ?: d; // expected-warning{{reference 'f' is not yet bound to a value when used within its own initialization}}
 
   struct S {
     S() : a(a) {} // expected-warning{{reference 'a' is not yet bound to a value when used here}}
     int &a;
   };
 
-  void f() {
+  void test() {
     int &a = a; // expected-warning{{reference 'a' is not yet bound to a value when used within its own initialization}}
     int &b(b); // expected-warning{{reference 'b' is not yet bound to a value when used within its own initialization}}
     int &c = a ? b : c; // expected-warning{{reference 'c' is not yet bound to a value when used within its own initialization}}
@@ -586,6 +621,7 @@ namespace lambdas {
 }
 
 namespace record_fields {
+  bool x;
   struct A {
     A() {}
     A get();
@@ -614,9 +650,10 @@ namespace record_fields {
     B(char (*)[10]) : a(std::move(a)) {}  // expected-warning {{uninitialized}}
     B(char (*)[11]) : a(A(std::move(a))) {}  // expected-warning {{uninitialized}}
     B(char (*)[12]) : a(rref(std::move(a))) {}  // expected-warning {{uninitialized}}
+    B(char (*)[13]) : a(std::move(x ? a : (25, a))) {}  // expected-warning 2{{uninitialized}}
   };
   struct C {
-    C() {} // expected-note8{{in this constructor}}
+    C() {} // expected-note9{{in this constructor}}
     A a1 = a1;  // expected-warning {{uninitialized}}
     A a2 = a2.get();  // expected-warning {{uninitialized}}
     A a3 = a3.num();
@@ -630,8 +667,9 @@ namespace record_fields {
     A a11 = std::move(a11);  // expected-warning {{uninitialized}}
     A a12 = A(std::move(a12));  // expected-warning {{uninitialized}}
     A a13 = rref(std::move(a13));  // expected-warning {{uninitialized}}
+    A a14 = std::move(x ? a13 : (22, a14));  // expected-warning {{uninitialized}}
   };
-  struct D {  // expected-note8{{in the implicit default constructor}}
+  struct D {  // expected-note9{{in the implicit default constructor}}
     A a1 = a1;  // expected-warning {{uninitialized}}
     A a2 = a2.get();  // expected-warning {{uninitialized}}
     A a3 = a3.num();
@@ -645,6 +683,7 @@ namespace record_fields {
     A a11 = std::move(a11);  // expected-warning {{uninitialized}}
     A a12 = A(std::move(a12));  // expected-warning {{uninitialized}}
     A a13 = rref(std::move(a13));  // expected-warning {{uninitialized}}
+    A a14 = std::move(x ? a13 : (22, a14));  // expected-warning {{uninitialized}}
   };
   D d;
   struct E {
@@ -661,6 +700,7 @@ namespace record_fields {
     A a11 = std::move(a11);
     A a12 = A(std::move(a12));
     A a13 = rref(std::move(a13));
+    A a14 = std::move(x ? a13 : (22, a14));
   };
 }
 





More information about the cfe-commits mailing list