r258778 - Fix -Wnull-conversion for long macros.

Richard Trieu via cfe-commits cfe-commits at lists.llvm.org
Mon Jan 25 18:51:56 PST 2016


Author: rtrieu
Date: Mon Jan 25 20:51:55 2016
New Revision: 258778

URL: http://llvm.org/viewvc/llvm-project?rev=258778&view=rev
Log:
Fix -Wnull-conversion for long macros.

Move the function to get a macro name from DiagnosticRenderer.cpp to Lexer.cpp
so that other files can use it.  Lexer now has two functions to get the
immediate macro name, the newly added one is better for diagnostic purposes.
Make -Wnull-conversion use this function for better NULL macro detection.

Modified:
    cfe/trunk/include/clang/Lex/Lexer.h
    cfe/trunk/lib/Frontend/DiagnosticRenderer.cpp
    cfe/trunk/lib/Lex/Lexer.cpp
    cfe/trunk/lib/Sema/SemaChecking.cpp
    cfe/trunk/test/SemaCXX/conversion.cpp

Modified: cfe/trunk/include/clang/Lex/Lexer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Lexer.h?rev=258778&r1=258777&r2=258778&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/Lexer.h (original)
+++ cfe/trunk/include/clang/Lex/Lexer.h Mon Jan 25 20:51:55 2016
@@ -410,6 +410,26 @@ public:
                                          const SourceManager &SM,
                                          const LangOptions &LangOpts);
 
+  /// \brief Retrieve the name of the immediate macro expansion.
+  ///
+  /// This routine starts from a source location, and finds the name of the
+  /// macro responsible for its immediate expansion. It looks through any
+  /// intervening macro argument expansions to compute this. It returns a
+  /// StringRef which refers to the SourceManager-owned buffer of the source
+  /// where that macro name is spelled. Thus, the result shouldn't out-live
+  /// that SourceManager.
+  ///
+  /// This differs from Lexer::getImmediateMacroName in that any macro argument
+  /// location will result in the topmost function macro that accepted it.
+  /// e.g.
+  /// \code
+  ///   MAC1( MAC2(foo) )
+  /// \endcode
+  /// for location of 'foo' token, this function will return "MAC1" while
+  /// Lexer::getImmediateMacroName will return "MAC2".
+  static StringRef getImmediateMacroNameForDiagnostics(
+      SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts);
+
   /// \brief Compute the preamble of the given file.
   ///
   /// The preamble of a file contains the initial comments, include directives,

Modified: cfe/trunk/lib/Frontend/DiagnosticRenderer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/DiagnosticRenderer.cpp?rev=258778&r1=258777&r2=258778&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/DiagnosticRenderer.cpp (original)
+++ cfe/trunk/lib/Frontend/DiagnosticRenderer.cpp Mon Jan 25 20:51:55 2016
@@ -23,48 +23,6 @@
 #include <algorithm>
 using namespace clang;
 
-/// \brief Retrieve the name of the immediate macro expansion.
-///
-/// This routine starts from a source location, and finds the name of the macro
-/// responsible for its immediate expansion. It looks through any intervening
-/// macro argument expansions to compute this. It returns a StringRef which
-/// refers to the SourceManager-owned buffer of the source where that macro
-/// name is spelled. Thus, the result shouldn't out-live that SourceManager.
-///
-/// This differs from Lexer::getImmediateMacroName in that any macro argument
-/// location will result in the topmost function macro that accepted it.
-/// e.g.
-/// \code
-///   MAC1( MAC2(foo) )
-/// \endcode
-/// for location of 'foo' token, this function will return "MAC1" while
-/// Lexer::getImmediateMacroName will return "MAC2".
-static StringRef getImmediateMacroName(SourceLocation Loc,
-                                       const SourceManager &SM,
-                                       const LangOptions &LangOpts) {
-   assert(Loc.isMacroID() && "Only reasonble to call this on macros");
-   // Walk past macro argument expanions.
-   while (SM.isMacroArgExpansion(Loc))
-     Loc = SM.getImmediateExpansionRange(Loc).first;
-
-   // If the macro's spelling has no FileID, then it's actually a token paste
-   // or stringization (or similar) and not a macro at all.
-   if (!SM.getFileEntryForID(SM.getFileID(SM.getSpellingLoc(Loc))))
-     return StringRef();
-
-   // Find the spelling location of the start of the non-argument expansion
-   // range. This is where the macro name was spelled in order to begin
-   // expanding this macro.
-   Loc = SM.getSpellingLoc(SM.getImmediateExpansionRange(Loc).first);
-
-   // Dig out the buffer where the macro name was spelled and the extents of the
-   // name so that we can render it into the expansion note.
-   std::pair<FileID, unsigned> ExpansionInfo = SM.getDecomposedLoc(Loc);
-   unsigned MacroTokenLength = Lexer::MeasureTokenLength(Loc, SM, LangOpts);
-   StringRef ExpansionBuffer = SM.getBufferData(ExpansionInfo.first);
-   return ExpansionBuffer.substr(ExpansionInfo.second, MacroTokenLength);
-}
-
 DiagnosticRenderer::DiagnosticRenderer(const LangOptions &LangOpts,
                                        DiagnosticOptions *DiagOpts)
   : LangOpts(LangOpts), DiagOpts(DiagOpts), LastLevel() {}
@@ -474,7 +432,8 @@ void DiagnosticRenderer::emitSingleMacro
 
   SmallString<100> MessageStorage;
   llvm::raw_svector_ostream Message(MessageStorage);
-  StringRef MacroName = getImmediateMacroName(Loc, SM, LangOpts);
+  StringRef MacroName =
+      Lexer::getImmediateMacroNameForDiagnostics(Loc, SM, LangOpts);
   if (MacroName.empty())
     Message << "expanded from here";
   else

Modified: cfe/trunk/lib/Lex/Lexer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Lexer.cpp?rev=258778&r1=258777&r2=258778&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/Lexer.cpp (original)
+++ cfe/trunk/lib/Lex/Lexer.cpp Mon Jan 25 20:51:55 2016
@@ -1000,6 +1000,31 @@ StringRef Lexer::getImmediateMacroName(S
   return ExpansionBuffer.substr(ExpansionInfo.second, MacroTokenLength);
 }
 
+StringRef Lexer::getImmediateMacroNameForDiagnostics(
+    SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts) {
+  assert(Loc.isMacroID() && "Only reasonble to call this on macros");
+  // Walk past macro argument expanions.
+  while (SM.isMacroArgExpansion(Loc))
+    Loc = SM.getImmediateExpansionRange(Loc).first;
+
+  // If the macro's spelling has no FileID, then it's actually a token paste
+  // or stringization (or similar) and not a macro at all.
+  if (!SM.getFileEntryForID(SM.getFileID(SM.getSpellingLoc(Loc))))
+    return StringRef();
+
+  // Find the spelling location of the start of the non-argument expansion
+  // range. This is where the macro name was spelled in order to begin
+  // expanding this macro.
+  Loc = SM.getSpellingLoc(SM.getImmediateExpansionRange(Loc).first);
+
+  // Dig out the buffer where the macro name was spelled and the extents of the
+  // name so that we can render it into the expansion note.
+  std::pair<FileID, unsigned> ExpansionInfo = SM.getDecomposedLoc(Loc);
+  unsigned MacroTokenLength = Lexer::MeasureTokenLength(Loc, SM, LangOpts);
+  StringRef ExpansionBuffer = SM.getBufferData(ExpansionInfo.first);
+  return ExpansionBuffer.substr(ExpansionInfo.second, MacroTokenLength);
+}
+
 bool Lexer::isIdentifierBodyChar(char c, const LangOptions &LangOpts) {
   return isIdentifierBody(c, LangOpts.DollarIdents);
 }

Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=258778&r1=258777&r2=258778&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Mon Jan 25 20:51:55 2016
@@ -7068,8 +7068,8 @@ static void DiagnoseNullConversion(Sema
   // __null is usually wrapped in a macro.  Go up a macro if that is the case.
   if (NullKind == Expr::NPCK_GNUNull) {
     if (Loc.isMacroID()) {
-      StringRef MacroName =
-          Lexer::getImmediateMacroName(Loc, S.SourceMgr, S.getLangOpts());
+      StringRef MacroName = Lexer::getImmediateMacroNameForDiagnostics(
+          Loc, S.SourceMgr, S.getLangOpts());
       if (MacroName == "NULL")
         Loc = S.SourceMgr.getImmediateExpansionRange(Loc).first;
     }

Modified: cfe/trunk/test/SemaCXX/conversion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/conversion.cpp?rev=258778&r1=258777&r2=258778&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/conversion.cpp (original)
+++ cfe/trunk/test/SemaCXX/conversion.cpp Mon Jan 25 20:51:55 2016
@@ -228,3 +228,31 @@ namespace test10 {
     assert(test2(x));
   }
 }
+
+namespace test11 {
+
+#define assert11(expr) ((expr) ? 0 : 0)
+
+// The whitespace in macro run1 are important to trigger the macro being split
+// over multiple SLocEntry's.
+#define run1() (dostuff() ? \
+    NULL                                   : NULL)
+#define run2() (dostuff() ? NULL : NULL)
+int dostuff ();
+
+void test(const char * content_type) {
+  assert11(run1());
+  assert11(run2());
+}
+
+}
+
+namespace test12 {
+
+#define x return NULL;
+
+bool run() {
+  x  // expected-warning{{}}
+}
+
+}




More information about the cfe-commits mailing list