[PATCH] D57893: [analyzer] Fix function macro crash

Tibor Brunner via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Feb 7 07:30:19 PST 2019


bruntib created this revision.
bruntib added reviewers: NoQ, george.karpenkov, Szelethus, xazax.hun.
Herald added subscribers: cfe-commits, dkrupp, donat.nagy, mikhail.ramalho, a.sidorin, rnkovacs, szepet, baloghadamsoftware.
Herald added a project: clang.

When there is a functor-like macro which is passed as parameter to another "function" macro then its parameters are not listed at the place of expansion:

#define foo(x) int bar() { return x; }
#define hello(fvar) fvar(0)
hello(foo)
int main() { 1 / bar(); }

Expansion of hello(foo) asserted Clang, because it expected an l_paren token in the 3rd line after "foo", since it is a function-like token.


Repository:
  rC Clang

https://reviews.llvm.org/D57893

Files:
  lib/StaticAnalyzer/Core/PlistDiagnostics.cpp


Index: lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
===================================================================
--- lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
+++ lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
@@ -879,8 +879,18 @@
 
         getMacroNameAndPrintExpansion(Printer, ArgIt->getLocation(), PP,
                                       Info.Args, AlreadyProcessedTokens);
-        if (MI->getNumParams() != 0)
-          ArgIt = getMatchingRParen(++ArgIt, ArgEnd);
+        // Peek the next token if it is a tok::l_paren. This way we can decide
+        // if this is the application or just a reference to a function maxro
+        // symbol:
+        //
+        // #define apply(f) ...
+        // #define func(x) ...
+        // apply(func)
+        // apply(func(42))
+        if ((++ArgIt)->is(tok::l_paren))
+          ArgIt = getMatchingRParen(ArgIt, ArgEnd);
+        else
+          --ArgIt;
       }
       continue;
     }
@@ -941,8 +951,16 @@
     return { MacroName, MI, {} };
 
   RawLexer.LexFromRawLexer(TheTok);
-  assert(TheTok.is(tok::l_paren) &&
-         "The token after the macro's identifier token should be '('!");
+  // When this is a token which expands to another macro function then its
+  // parentheses are not at its expansion locaiton. For example:
+  //
+  // #define foo(x) int bar() { return x; }
+  // #define apply_zero(f) f(0)
+  // apply_zero(foo)
+  //               ^
+  //               This is not a tok::l_paren, but foo is a function.
+  if (TheTok.isNot(tok::l_paren))
+    return { MacroName, MI, {} };
 
   MacroArgMap Args;
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D57893.185760.patch
Type: text/x-patch
Size: 1595 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20190207/41d3c146/attachment-0001.bin>


More information about the cfe-commits mailing list