[cfe-commits] r66387 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.def lib/Sema/SemaExpr.cpp test/Sema/exprs.c

Chris Lattner sabre at nondot.org
Sun Mar 8 12:39:53 PDT 2009


Author: lattner
Date: Sun Mar  8 14:39:53 2009
New Revision: 66387

URL: http://llvm.org/viewvc/llvm-project?rev=66387&view=rev
Log:
implement PR3753, warning about comparisons with a string literal.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/test/Sema/exprs.c

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def?rev=66387&r1=66386&r2=66387&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def Sun Mar  8 14:39:53 2009
@@ -1344,10 +1344,12 @@
   "reference to stack memory associated with local variable %0 returned")
 
 
-// CHECK: for non-floating point, expressions of the form x == x or x != x
+// for non-floating point, expressions of the form x == x or x != x
 // should result in a warning, since these always evaluate to a constant.
-DIAG(warn_selfcomparison,WARNING,
-     "self-comparison always results in a constant value.")
+DIAG(warn_selfcomparison, WARNING,
+     "self-comparison always results in a constant value")
+DIAG(warn_stringcompare, WARNING,
+     "comparison against a string literal is undefined (use strcmp?)")
 
 
 // Blocks

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=66387&r1=66386&r2=66387&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sun Mar  8 14:39:53 2009
@@ -3155,18 +3155,35 @@
   QualType lType = lex->getType();
   QualType rType = rex->getType();
 
-  // For non-floating point types, check for self-comparisons of the form
-  // x == x, x != x, x < x, etc.  These always evaluate to a constant, and
-  // often indicate logic errors in the program.
   if (!lType->isFloatingType()) {
-    if (DeclRefExpr* DRL = dyn_cast<DeclRefExpr>(lex->IgnoreParens()))
-      if (DeclRefExpr* DRR = dyn_cast<DeclRefExpr>(rex->IgnoreParens()))
+    // For non-floating point types, check for self-comparisons of the form
+    // x == x, x != x, x < x, etc.  These always evaluate to a constant, and
+    // often indicate logic errors in the program.
+    Expr *LHSStripped = lex->IgnoreParens();
+    Expr *RHSStripped = rex->IgnoreParens();
+    if (DeclRefExpr* DRL = dyn_cast<DeclRefExpr>(LHSStripped))
+      if (DeclRefExpr* DRR = dyn_cast<DeclRefExpr>(RHSStripped))
         if (DRL->getDecl() == DRR->getDecl())
           Diag(Loc, diag::warn_selfcomparison);
+    
+    if (isa<CastExpr>(LHSStripped))
+      LHSStripped = LHSStripped->IgnoreParenCasts();
+    if (isa<CastExpr>(RHSStripped))
+      RHSStripped = RHSStripped->IgnoreParenCasts();
+    
+    // Warn about comparisons against a string constant (unless the other
+    // operand is null), the user probably wants strcmp.
+    if ((isa<StringLiteral>(LHSStripped) || isa<ObjCEncodeExpr>(LHSStripped)) &&
+        !RHSStripped->isNullPointerConstant(Context))
+      Diag(Loc, diag::warn_stringcompare) << lex->getSourceRange();
+    else if ((isa<StringLiteral>(RHSStripped) ||
+              isa<ObjCEncodeExpr>(RHSStripped)) &&
+             !LHSStripped->isNullPointerConstant(Context))
+      Diag(Loc, diag::warn_stringcompare) << rex->getSourceRange();
   }
 
   // The result of comparisons is 'bool' in C++, 'int' in C.
-  QualType ResultTy = getLangOptions().CPlusPlus? Context.BoolTy : Context.IntTy;
+  QualType ResultTy = getLangOptions().CPlusPlus? Context.BoolTy :Context.IntTy;
 
   if (isRelational) {
     if (lType->isRealType() && rType->isRealType())
@@ -3174,7 +3191,7 @@
   } else {
     // Check for comparisons of floating point operands using != and ==.
     if (lType->isFloatingType()) {
-      assert (rType->isFloatingType());
+      assert(rType->isFloatingType());
       CheckFloatComparison(Loc,lex,rex);
     }
 

Modified: cfe/trunk/test/Sema/exprs.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/exprs.c?rev=66387&r1=66386&r2=66387&view=diff

==============================================================================
--- cfe/trunk/test/Sema/exprs.c (original)
+++ cfe/trunk/test/Sema/exprs.c Sun Mar  8 14:39:53 2009
@@ -72,7 +72,12 @@
 #define MYMAX(A,B)    __extension__ ({ __typeof__(A) __a = (A); __typeof__(B) __b = (B); __a < __b ? __b : __a; })
 
 struct mystruct {int A; };
-void foo(struct mystruct P, float F) {
+void test11(struct mystruct P, float F) {
   MYMAX(P, F);  // expected-error {{invalid operands to binary expression ('typeof(P)' (aka 'struct mystruct') and 'typeof(F)' (aka 'float'))}}
 }
 
+// PR3753
+int test12(const char *X) {
+  return X == "foo";  // expected-warning {{comparison against a string literal is undefined}}
+}
+





More information about the cfe-commits mailing list