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)