forked from OSchip/llvm-project
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:
parent
6bd95b8aac
commit
955231ddf6
|
@ -5346,8 +5346,8 @@ void CheckImplicitConversion(Sema &S, Expr *E, QualType T,
|
||||||
if (Target->isSpecificBuiltinType(BuiltinType::Bool)) {
|
if (Target->isSpecificBuiltinType(BuiltinType::Bool)) {
|
||||||
if (isa<StringLiteral>(E))
|
if (isa<StringLiteral>(E))
|
||||||
// Warn on string literal to bool. Checks for string literals in logical
|
// Warn on string literal to bool. Checks for string literals in logical
|
||||||
// expressions, for instances, assert(0 && "error here"), are prevented
|
// and expressions, for instance, assert(0 && "error here"), are
|
||||||
// by a check in AnalyzeImplicitConversions().
|
// prevented by a check in AnalyzeImplicitConversions().
|
||||||
return DiagnoseImpCast(S, E, T, CC,
|
return DiagnoseImpCast(S, E, T, CC,
|
||||||
diag::warn_impcast_string_literal_to_bool);
|
diag::warn_impcast_string_literal_to_bool);
|
||||||
if (Source->isFunctionType()) {
|
if (Source->isFunctionType()) {
|
||||||
|
@ -5698,15 +5698,16 @@ void AnalyzeImplicitConversions(Sema &S, Expr *OrigE, SourceLocation CC) {
|
||||||
// Now just recurse over the expression's children.
|
// Now just recurse over the expression's children.
|
||||||
CC = E->getExprLoc();
|
CC = E->getExprLoc();
|
||||||
BinaryOperator *BO = dyn_cast<BinaryOperator>(E);
|
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) {
|
for (Stmt::child_range I = E->children(); I; ++I) {
|
||||||
Expr *ChildExpr = dyn_cast_or_null<Expr>(*I);
|
Expr *ChildExpr = dyn_cast_or_null<Expr>(*I);
|
||||||
if (!ChildExpr)
|
if (!ChildExpr)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (IsLogicalOperator &&
|
if (IsLogicalAndOperator &&
|
||||||
isa<StringLiteral>(ChildExpr->IgnoreParenImpCasts()))
|
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;
|
continue;
|
||||||
AnalyzeImplicitConversions(S, ChildExpr, CC);
|
AnalyzeImplicitConversions(S, ChildExpr, CC);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,20 @@
|
||||||
// RUN: %clang_cc1 -fsyntax-only -Wstring-conversion -verify %s
|
// RUN: %clang_cc1 -fsyntax-only -Wstring-conversion -verify %s
|
||||||
|
|
||||||
// Warn on cases where a string literal is converted into a bool.
|
// 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 assert(bool condition);
|
||||||
void test0() {
|
void test0() {
|
||||||
bool b0 = "hi"; // expected-warning{{implicit conversion turns string literal into bool: 'const char [3]' to 'bool'}}
|
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 = ""; // 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 && "";
|
||||||
|
b0 = "" && 0;
|
||||||
assert("error"); // expected-warning{{implicit conversion turns string literal into bool: 'const char [6]' to 'bool'}}
|
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(0 && "error");
|
||||||
|
assert("error" && 0);
|
||||||
|
|
||||||
while("hi") {} // expected-warning{{implicit conversion turns string literal into bool: 'const char [3]' to 'bool'}}
|
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'}}
|
do {} while("hi"); // expected-warning{{implicit conversion turns string literal into bool: 'const char [3]' to 'bool'}}
|
||||||
|
|
Loading…
Reference in New Issue