[cfe-commits] r93266 - in /cfe/trunk: include/clang/Basic/PartialDiagnostic.h lib/Sema/SemaExpr.cpp test/Sema/exprs.c test/Sema/self-comparison.c

Douglas Gregor dgregor at apple.com
Tue Jan 12 15:18:54 PST 2010


Author: dgregor
Date: Tue Jan 12 17:18:54 2010
New Revision: 93266

URL: http://llvm.org/viewvc/llvm-project?rev=93266&view=rev
Log:
Don't emit string-comparison or self-comparison warnings in
unevaluated contexts, because they only matter for code that will
actually be evaluated at runtime.

As part of this, I had to extend PartialDiagnostic to support fix-it
hints.

Modified:
    cfe/trunk/include/clang/Basic/PartialDiagnostic.h
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/test/Sema/exprs.c
    cfe/trunk/test/Sema/self-comparison.c

Modified: cfe/trunk/include/clang/Basic/PartialDiagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/PartialDiagnostic.h?rev=93266&r1=93265&r2=93266&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/PartialDiagnostic.h (original)
+++ cfe/trunk/include/clang/Basic/PartialDiagnostic.h Tue Jan 12 17:18:54 2010
@@ -26,7 +26,8 @@
   
 class PartialDiagnostic {
   struct Storage {
-    Storage() : NumDiagArgs(0), NumDiagRanges(0) { }
+    Storage() : NumDiagArgs(0), NumDiagRanges(0), NumCodeModificationHints(0) {
+    }
 
     enum {
         /// MaxArguments - The maximum number of arguments we can hold. We 
@@ -42,6 +43,10 @@
     /// NumDiagRanges - This is the number of ranges in the DiagRanges array.
     unsigned char NumDiagRanges;
 
+    /// \brief The number of code modifications hints in the
+    /// CodeModificationHints array.
+    unsigned char NumCodeModificationHints;
+    
     /// DiagArgumentsKind - This is an array of ArgumentKind::ArgumentKind enum
     /// values, with one for each argument.  This specifies whether the argument
     /// is in DiagArgumentsStr or in DiagArguments.
@@ -56,6 +61,12 @@
     /// DiagRanges - The list of ranges added to this diagnostic.  It currently
     /// only support 10 ranges, could easily be extended if needed.
     SourceRange DiagRanges[10];
+    
+    enum { MaxCodeModificationHints = 3 };
+    
+    /// CodeModificationHints - If valid, provides a hint with some code
+    /// to insert, remove, or modify at a particular position.
+    CodeModificationHint CodeModificationHints[MaxCodeModificationHints];    
   };
 
   /// DiagID - The diagnostic ID.
@@ -84,6 +95,20 @@
     DiagStorage->DiagRanges[DiagStorage->NumDiagRanges++] = R;
   }  
 
+  void AddCodeModificationHint(const CodeModificationHint &Hint) const {
+    if (Hint.isNull())
+      return;
+    
+    if (!DiagStorage)
+      DiagStorage = new Storage;
+
+    assert(DiagStorage->NumCodeModificationHints < 
+             Storage::MaxCodeModificationHints &&
+           "Too many code modification hints!");
+    DiagStorage->CodeModificationHints[DiagStorage->NumCodeModificationHints++]
+      = Hint;
+  }
+  
 public:
   PartialDiagnostic(unsigned DiagID)
     : DiagID(DiagID), DiagStorage(0) { }
@@ -130,6 +155,10 @@
     // Add all ranges.
     for (unsigned i = 0, e = DiagStorage->NumDiagRanges; i != e; ++i)
       DB.AddSourceRange(DiagStorage->DiagRanges[i]);
+    
+    // Add all code modification hints
+    for (unsigned i = 0, e = DiagStorage->NumCodeModificationHints; i != e; ++i)
+      DB.AddCodeModificationHint(DiagStorage->CodeModificationHints[i]);
   }
   
   friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
@@ -165,6 +194,13 @@
 
   friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
                                              DeclarationName N);
+  
+  friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+                                             const CodeModificationHint &Hint) {
+    PD.AddCodeModificationHint(Hint);
+    return PD;
+  }
+  
 };
 
 inline PartialDiagnostic PDiag(unsigned DiagID = 0) {

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Jan 12 17:18:54 2010
@@ -5196,7 +5196,7 @@
       if (DeclRefExpr* DRR = dyn_cast<DeclRefExpr>(RHSStripped))
         if (DRL->getDecl() == DRR->getDecl() &&
             !isa<EnumConstantDecl>(DRL->getDecl()))
-          Diag(Loc, diag::warn_selfcomparison);
+          DiagRuntimeBehavior(Loc, PDiag(diag::warn_selfcomparison));
 
     if (isa<CastExpr>(LHSStripped))
       LHSStripped = LHSStripped->IgnoreParenCasts();
@@ -5231,15 +5231,17 @@
       case BinaryOperator::NE: resultComparison = ") != 0"; break;
       default: assert(false && "Invalid comparison operator");
       }
-      Diag(Loc, diag::warn_stringcompare)
-        << isa<ObjCEncodeExpr>(literalStringStripped)
-        << literalString->getSourceRange()
-        << CodeModificationHint::CreateReplacement(SourceRange(Loc), ", ")
-        << CodeModificationHint::CreateInsertion(lex->getLocStart(),
-                                                 "strcmp(")
-        << CodeModificationHint::CreateInsertion(
-                                       PP.getLocForEndOfToken(rex->getLocEnd()),
-                                       resultComparison);
+      
+      DiagRuntimeBehavior(Loc,
+        PDiag(diag::warn_stringcompare)
+          << isa<ObjCEncodeExpr>(literalStringStripped)
+          << literalString->getSourceRange()
+          << CodeModificationHint::CreateReplacement(SourceRange(Loc), ", ")
+          << CodeModificationHint::CreateInsertion(lex->getLocStart(),
+                                                   "strcmp(")
+          << CodeModificationHint::CreateInsertion(
+                                         PP.getLocForEndOfToken(rex->getLocEnd()),
+                                         resultComparison));
     }
   }
 
@@ -5503,7 +5505,7 @@
     if (DeclRefExpr* DRL = dyn_cast<DeclRefExpr>(lex->IgnoreParens()))
       if (DeclRefExpr* DRR = dyn_cast<DeclRefExpr>(rex->IgnoreParens()))
         if (DRL->getDecl() == DRR->getDecl())
-          Diag(Loc, diag::warn_selfcomparison);
+          DiagRuntimeBehavior(Loc, PDiag(diag::warn_selfcomparison));
   }
 
   // Check for comparisons of floating point operands using != and ==.

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

==============================================================================
--- cfe/trunk/test/Sema/exprs.c (original)
+++ cfe/trunk/test/Sema/exprs.c Tue Jan 12 17:18:54 2010
@@ -87,6 +87,10 @@
   return X == "foo";  // expected-warning {{comparison against a string literal is unspecified}}
 }
 
+int test12b(const char *X) {
+  return sizeof(X == "foo"); // no-warning
+}
+
 // rdar://6719156
 void test13(
             void (^P)()) { // expected-error {{blocks support disabled - compile with -fblocks}}

Modified: cfe/trunk/test/Sema/self-comparison.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/self-comparison.c?rev=93266&r1=93265&r2=93266&view=diff

==============================================================================
--- cfe/trunk/test/Sema/self-comparison.c (original)
+++ cfe/trunk/test/Sema/self-comparison.c Tue Jan 12 17:18:54 2010
@@ -31,3 +31,8 @@
   enum { A };
   return A == A; // no-warning
 }
+
+// Don't complain in unevaluated contexts.
+int compare_sizeof(int x) {
+  return sizeof(x == x); // no-warning
+}





More information about the cfe-commits mailing list