Index: cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
===================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
@@ -900,7 +900,8 @@
// If this is a function-like macro, skip its arguments, as
// getExpandedMacro() already printed them. If this is the case, let's
// first jump to the '(' token.
- if (MI->getNumParams() != 0)
+ auto N = std::next(It);
+ if (N != E && N->is(tok::l_paren))
It = getMatchingRParen(++It, E);
continue;
}
@@ -928,7 +929,16 @@
getMacroNameAndPrintExpansion(Printer, ArgIt->getLocation(), PP,
Info.Args, AlreadyProcessedTokens);
- if (MI->getNumParams() != 0)
+ // 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))
+ auto N = std::next(ArgIt);
+ if (N != ArgEnd && N->is(tok::l_paren))
ArgIt = getMatchingRParen(++ArgIt, ArgEnd);
}
continue;
@@ -990,8 +1000,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: cfe/trunk/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
===================================================================
--- cfe/trunk/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
+++ cfe/trunk/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
@@ -5577,6 +5577,484 @@
+
+ path
+
+
+ kindcontrol
+ edges
+
+
+ start
+
+
+ line459
+ col33
+ file0
+
+
+ line459
+ col33
+ file0
+
+
+ end
+
+
+ line459
+ col37
+ file0
+
+
+ line459
+ col39
+ file0
+
+
+
+
+
+
+ kindevent
+ location
+
+ line459
+ col37
+ file0
+
+ ranges
+
+
+
+ line459
+ col37
+ file0
+
+
+ line459
+ col41
+ file0
+
+
+
+ depth0
+ extended_message
+ Calling 'foo'
+ message
+ Calling 'foo'
+
+
+ kindevent
+ location
+
+ line458
+ col1
+ file0
+
+ depth1
+ extended_message
+ Entered call from 'useZeroApplier1'
+ message
+ Entered call from 'useZeroApplier1'
+
+
+ kindevent
+ location
+
+ line458
+ col1
+ file0
+
+ ranges
+
+
+
+ line458
+ col1
+ file0
+
+
+ line458
+ col16
+ file0
+
+
+
+ depth1
+ extended_message
+ Returning zero
+ message
+ Returning zero
+
+
+ kindevent
+ location
+
+ line459
+ col37
+ file0
+
+ ranges
+
+
+
+ line459
+ col37
+ file0
+
+
+ line459
+ col41
+ file0
+
+
+
+ depth0
+ extended_message
+ Returning from 'foo'
+ message
+ Returning from 'foo'
+
+
+ kindcontrol
+ edges
+
+
+ start
+
+
+ line459
+ col37
+ file0
+
+
+ line459
+ col39
+ file0
+
+
+ end
+
+
+ line459
+ col35
+ file0
+
+
+ line459
+ col35
+ file0
+
+
+
+
+
+
+ kindevent
+ location
+
+ line459
+ col35
+ file0
+
+ ranges
+
+
+
+ line459
+ col33
+ file0
+
+
+ line459
+ col41
+ file0
+
+
+
+ depth0
+ extended_message
+ Division by zero
+ message
+ Division by zero
+
+
+ macro_expansions
+
+
+ location
+
+ line458
+ col1
+ file0
+
+ nameAPPLY_ZERO1
+ expansionint foo() { return x; }(0)
+
+
+ descriptionDivision by zero
+ categoryLogic error
+ typeDivision by zero
+ check_namecore.DivideZero
+
+ issue_hash_content_of_line_in_context7ff82561a6c752746649d05220deeb40
+ issue_context_kindfunction
+ issue_contextuseZeroApplier1
+ issue_hash_function_offset0
+ location
+
+ line459
+ col35
+ file0
+
+ ExecutedLines
+
+ 0
+
+ 458
+ 459
+
+
+
+
+ path
+
+
+ kindcontrol
+ edges
+
+
+ start
+
+
+ line468
+ col33
+ file0
+
+
+ line468
+ col33
+ file0
+
+
+ end
+
+
+ line468
+ col37
+ file0
+
+
+ line468
+ col39
+ file0
+
+
+
+
+
+
+ kindevent
+ location
+
+ line468
+ col37
+ file0
+
+ ranges
+
+
+
+ line468
+ col37
+ file0
+
+
+ line468
+ col41
+ file0
+
+
+
+ depth0
+ extended_message
+ Calling 'bar'
+ message
+ Calling 'bar'
+
+
+ kindevent
+ location
+
+ line467
+ col1
+ file0
+
+ depth1
+ extended_message
+ Entered call from 'useZeroApplier2'
+ message
+ Entered call from 'useZeroApplier2'
+
+
+ kindevent
+ location
+
+ line467
+ col1
+ file0
+
+ ranges
+
+
+
+ line467
+ col1
+ file0
+
+
+ line467
+ col11
+ file0
+
+
+
+ depth1
+ extended_message
+ Returning zero
+ message
+ Returning zero
+
+
+ kindevent
+ location
+
+ line468
+ col37
+ file0
+
+ ranges
+
+
+
+ line468
+ col37
+ file0
+
+
+ line468
+ col41
+ file0
+
+
+
+ depth0
+ extended_message
+ Returning from 'bar'
+ message
+ Returning from 'bar'
+
+
+ kindcontrol
+ edges
+
+
+ start
+
+
+ line468
+ col37
+ file0
+
+
+ line468
+ col39
+ file0
+
+
+ end
+
+
+ line468
+ col35
+ file0
+
+
+ line468
+ col35
+ file0
+
+
+
+
+
+
+ kindevent
+ location
+
+ line468
+ col35
+ file0
+
+ ranges
+
+
+
+ line468
+ col33
+ file0
+
+
+ line468
+ col41
+ file0
+
+
+
+ depth0
+ extended_message
+ Division by zero
+ message
+ Division by zero
+
+
+ macro_expansions
+
+
+ location
+
+ line467
+ col1
+ file0
+
+ nameAPPLY_ZERO2
+ expansionint bar() { return 0; }
+
+
+ descriptionDivision by zero
+ categoryLogic error
+ typeDivision by zero
+ check_namecore.DivideZero
+
+ issue_hash_content_of_line_in_contextdd82c11b436b00009e37f54b1620a728
+ issue_context_kindfunction
+ issue_contextuseZeroApplier2
+ issue_hash_function_offset0
+ location
+
+ line468
+ col35
+ file0
+
+ ExecutedLines
+
+ 0
+
+ 467
+ 468
+
+
+
files
Index: cfe/trunk/test/Analysis/plist-macros-with-expansion.cpp
===================================================================
--- cfe/trunk/test/Analysis/plist-macros-with-expansion.cpp
+++ cfe/trunk/test/Analysis/plist-macros-with-expansion.cpp
@@ -451,3 +451,21 @@
1 / value; // expected-warning{{Division by zero}}
// expected-warning@-1{{expression result unused}}
}
+
+#define FOO(x) int foo() { return x; }
+#define APPLY_ZERO1(function) function(0)
+
+APPLY_ZERO1(FOO)
+void useZeroApplier1() { (void)(1 / foo()); } // expected-warning{{Division by zero}}
+
+// CHECK: nameAPPLY_ZERO1
+// CHECK-NEXT: expansionint foo() { return x; }(0)
+
+#define BAR(x) int bar() { return x; }
+#define APPLY_ZERO2 BAR(0)
+
+APPLY_ZERO2
+void useZeroApplier2() { (void)(1 / bar()); } // expected-warning{{Division by zero}}
+
+// CHECK: nameAPPLY_ZERO2
+// CHECK-NEXT: expansionint bar() { return 0; }