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