Pārlūkot izejas kodu

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


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@200056 91177308-0d34-0410-b5e6-96231b3b80d8

Richard Trieu 11 gadi atpakaļ
vecāks
revīzija
c8a38fbc6b
2 mainītis faili ar 13 papildinājumiem un 6 dzēšanām
  1. 6 5
      lib/Sema/SemaChecking.cpp
  2. 7 1
      test/SemaCXX/warn-string-conversion.cpp

+ 6 - 5
lib/Sema/SemaChecking.cpp

@@ -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);
   }

+ 7 - 1
test/SemaCXX/warn-string-conversion.cpp

@@ -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'}}