Broaden -Wstring-conversion to catch string literals in logical or expressions.

Previously, string literals were ignored in all logical expressions.  This
reduces it to only ignore in logical and expressions.

assert(0 && "error"); // No warning
assert(0 || "error"); // Warn

Fixes PR17565

llvm-svn: 200056
This commit is contained in:
Richard Trieu 2014-01-25 01:10:35 +00:00
parent 6bd95b8aac
commit 955231ddf6
2 changed files with 13 additions and 6 deletions

View File

@ -5346,8 +5346,8 @@ void CheckImplicitConversion(Sema &S, Expr *E, QualType T,
if (Target->isSpecificBuiltinType(BuiltinType::Bool)) {
if (isa<StringLiteral>(E))
// Warn on string literal to bool. Checks for string literals in logical
// expressions, for instances, assert(0 && "error here"), are prevented
// by a check in AnalyzeImplicitConversions().
// and expressions, for instance, assert(0 && "error here"), are
// prevented by a check in AnalyzeImplicitConversions().
return DiagnoseImpCast(S, E, T, CC,
diag::warn_impcast_string_literal_to_bool);
if (Source->isFunctionType()) {
@ -5698,15 +5698,16 @@ void AnalyzeImplicitConversions(Sema &S, Expr *OrigE, SourceLocation CC) {
// Now just recurse over the expression's children.
CC = E->getExprLoc();
BinaryOperator *BO = dyn_cast<BinaryOperator>(E);
bool IsLogicalOperator = BO && BO->isLogicalOp();
bool IsLogicalAndOperator = BO && BO->getOpcode() == BO_LAnd;
for (Stmt::child_range I = E->children(); I; ++I) {
Expr *ChildExpr = dyn_cast_or_null<Expr>(*I);
if (!ChildExpr)
continue;
if (IsLogicalOperator &&
if (IsLogicalAndOperator &&
isa<StringLiteral>(ChildExpr->IgnoreParenImpCasts()))
// Ignore checking string literals that are in logical operators.
// Ignore checking string literals that are in logical and operators.
// This is a common pattern for asserts.
continue;
AnalyzeImplicitConversions(S, ChildExpr, CC);
}

View File

@ -1,14 +1,20 @@
// RUN: %clang_cc1 -fsyntax-only -Wstring-conversion -verify %s
// Warn on cases where a string literal is converted into a bool.
// An exception is made for this in logical operators.
// An exception is made for this in logical and operators.
void assert(bool condition);
void test0() {
bool b0 = "hi"; // expected-warning{{implicit conversion turns string literal into bool: 'const char [3]' to 'bool'}}
b0 = ""; // expected-warning{{implicit conversion turns string literal into bool: 'const char [1]' to 'bool'}}
b0 = 0 || ""; // expected-warning{{implicit conversion turns string literal into bool: 'const char [1]' to 'bool'}}
b0 = "" || 0; // expected-warning{{implicit conversion turns string literal into bool: 'const char [1]' to 'bool'}}
b0 = 0 && "";
b0 = "" && 0;
assert("error"); // expected-warning{{implicit conversion turns string literal into bool: 'const char [6]' to 'bool'}}
assert(0 || "error"); // expected-warning{{implicit conversion turns string literal into bool: 'const char [6]' to 'bool'}}
assert("error" || 0); // expected-warning{{implicit conversion turns string literal into bool: 'const char [6]' to 'bool'}}
assert(0 && "error");
assert("error" && 0);
while("hi") {} // expected-warning{{implicit conversion turns string literal into bool: 'const char [3]' to 'bool'}}
do {} while("hi"); // expected-warning{{implicit conversion turns string literal into bool: 'const char [3]' to 'bool'}}