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;
Index: test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
===================================================================
--- test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
+++ test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
@@ -5168,6 +5168,237 @@
file0
+
+ path
+
+
+ kindcontrol
+ edges
+
+
+ start
+
+
+ line449
+ col10
+ file0
+
+
+ line449
+ col10
+ file0
+
+
+ end
+
+
+ line449
+ col14
+ file0
+
+
+ line449
+ col16
+ file0
+
+
+
+
+
+
+ kindevent
+ location
+
+ line449
+ col14
+ file0
+
+ ranges
+
+
+
+ line449
+ col14
+ file0
+
+
+ line449
+ col18
+ file0
+
+
+
+ depth0
+ extended_message
+ Calling 'bar'
+ message
+ Calling 'bar'
+
+
+ kindevent
+ location
+
+ line447
+ col1
+ file0
+
+ depth1
+ extended_message
+ Entered call from 'useZeroApplier'
+ message
+ Entered call from 'useZeroApplier'
+
+
+ kindevent
+ location
+
+ line447
+ col1
+ file0
+
+ ranges
+
+
+
+ line447
+ col1
+ file0
+
+
+ line447
+ col15
+ file0
+
+
+
+ depth1
+ extended_message
+ Returning zero
+ message
+ Returning zero
+
+
+ kindevent
+ location
+
+ line449
+ col14
+ file0
+
+ ranges
+
+
+
+ line449
+ col14
+ file0
+
+
+ line449
+ col18
+ file0
+
+
+
+ depth0
+ extended_message
+ Returning from 'bar'
+ message
+ Returning from 'bar'
+
+
+ kindcontrol
+ edges
+
+
+ start
+
+
+ line449
+ col14
+ file0
+
+
+ line449
+ col16
+ file0
+
+
+ end
+
+
+ line449
+ col12
+ file0
+
+
+ line449
+ col12
+ file0
+
+
+
+
+
+
+ kindevent
+ location
+
+ line449
+ col12
+ file0
+
+ ranges
+
+
+
+ line449
+ col10
+ file0
+
+
+ line449
+ col18
+ file0
+
+
+
+ depth0
+ extended_message
+ Division by zero
+ message
+ Division by zero
+
+
+ macro_expansions
+
+
+ location
+
+ line447
+ col1
+ file0
+
+ nameAPPLY_ZERO
+ expansionint bar() { return x; }(0)
+
+
+ descriptionDivision by zero
+ categoryLogic error
+ typeDivision by zero
+ check_namecore.DivideZero
+
+ issue_hash_content_of_line_in_contextb41a3835d64fddaac63749c968f17e81
+ issue_context_kindfunction
+ issue_contextuseZeroApplier
+ issue_hash_function_offset1
+ location
+
+ line449
+ col12
+ file0
+
+
Index: test/Analysis/plist-macros-with-expansion.cpp
===================================================================
--- test/Analysis/plist-macros-with-expansion.cpp
+++ test/Analysis/plist-macros-with-expansion.cpp
@@ -441,3 +441,13 @@
}
// CHECK: nameYET_ANOTHER_SET_TO_NULL
// CHECK-NEXT: expansionprint((void *)5); print((void *)"Remember the Vasa"); ptr = nullptr;
+
+#define FOO(x) int bar() { return x; }
+#define APPLY_ZERO(function) function(0)
+APPLY_ZERO(FOO)
+void useZeroApplier() {
+ (void)(1 / bar()); // expected-warning{{Division by zero}}
+}
+
+// CHECK: nameAPPLY_ZERO
+// CHECK-NEXT: expansionint bar() { return x; }(0)