Index: lib/Sema/SemaChecking.cpp =================================================================== --- lib/Sema/SemaChecking.cpp +++ lib/Sema/SemaChecking.cpp @@ -5327,7 +5327,7 @@ // Diagnose implicit casts to bool. if (Target->isSpecificBuiltinType(BuiltinType::Bool)) { - if (isa(E)) + if (isa(E) || isa(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(). @@ -5688,7 +5688,8 @@ continue; if (IsLogicalOperator && - isa(ChildExpr->IgnoreParenImpCasts())) + (isa(ChildExpr->IgnoreParenImpCasts()) || + isa(ChildExpr->IgnoreParenImpCasts()))) // Ignore checking string literals that are in logical operators. continue; AnalyzeImplicitConversions(S, ChildExpr, CC); Index: test/SemaObjCXX/warn-string-conversion.mm =================================================================== --- test/SemaObjCXX/warn-string-conversion.mm +++ test/SemaObjCXX/warn-string-conversion.mm @@ -0,0 +1,31 @@ +// 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. +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 && ""; + assert("error"); // expected-warning{{implicit conversion turns string literal into bool: 'const char [6]' to 'bool'}} + assert(0 && "error"); + + 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'}} + for (;"hi";); // expected-warning{{implicit conversion turns string literal into bool: 'const char [3]' to 'bool'}} + if("hi") {} // expected-warning{{implicit conversion turns string literal into bool: 'const char [3]' to 'bool'}} +} + +void test1() { + bool b0 = @"hi"; // expected-warning{{implicit conversion turns string literal into bool: 'NSString *' to 'bool'}} + b0 = @""; // expected-warning{{implicit conversion turns string literal into bool: 'NSString *' to 'bool'}} + b0 = 0 && @""; + assert(@"error"); // expected-warning{{implicit conversion turns string literal into bool: 'NSString *' to 'bool'}} + assert(0 && @"error"); + + while(@"hi") {} // expected-warning{{implicit conversion turns string literal into bool: 'NSString *' to 'bool'}} + do {} while(@"hi"); // expected-warning{{implicit conversion turns string literal into bool: 'NSString *' to 'bool'}} + for (;@"hi";); // expected-warning{{implicit conversion turns string literal into bool: 'NSString *' to 'bool'}} + if(@"hi") {} // expected-warning{{implicit conversion turns string literal into bool: 'NSString *' to 'bool'}} +} +