Index: lib/StaticAnalyzer/Core/PlistDiagnostics.cpp =================================================================== --- lib/StaticAnalyzer/Core/PlistDiagnostics.cpp +++ lib/StaticAnalyzer/Core/PlistDiagnostics.cpp @@ -962,41 +962,62 @@ // CALL_FN(someFunctionName(param1, param2)) // we will find tok::l_paren, tok::r_paren, and tok::comma that do not divide // actual macro arguments, or do not represent the macro argument's closing - // parentheses, so we'll count how many parentheses aren't closed yet. + // parantheses, so we'll count how many parantheses aren't closed yet. + // If ParanthesesDepth + // * = 0, then there are no more arguments to lex. + // * = 1, then if we find a tok::comma, we can start lexing the next arg. + // * > 1, then tok::comma is a part of the current arg. int ParenthesesDepth = 1; + // If we encounter __VA_ARGS__, we will lex until the closing tok::r_paren, + // even if we lex a tok::comma and ParanthesesDepth == 1. + const IdentifierInfo *__VA_ARGS__II = PP.getIdentifierInfo("__VA_ARGS__"); + for (const IdentifierInfo *UnexpArgII : MacroArgs) { MacroArgMap::mapped_type ExpandedArgTokens; - // Lex the first token of the next macro parameter. - RawLexer.LexFromRawLexer(TheTok); + // One could also simply not supply a single argument to __VA_ARGS__ -- this + // results in a preprocessor warning, but is not an error: + // #define VARIADIC(ptr, ...) \ + // someVariadicTemplateFunction(__VA_ARGS__) + // + // int *ptr; + // VARIADIC(ptr); // Note that there are no commas, this isn't just an + // // empty parameter -- there are no parameters for '...'. + // In any other case, ParenthesesDepth mustn't be 0 here. + if (ParenthesesDepth != 0) { - while (TheTok.isNot(tok::comma) || ParenthesesDepth != 1) { - assert(TheTok.isNot(tok::eof) && - "EOF encountered while looking for expanded macro args!"); + // Lex the first token of the next macro parameter. + RawLexer.LexFromRawLexer(TheTok); - if (TheTok.is(tok::l_paren)) - ++ParenthesesDepth; + while (!(ParenthesesDepth == 1 && + (UnexpArgII == __VA_ARGS__II ? false : TheTok.is(tok::comma)))) { + assert(TheTok.isNot(tok::eof) && + "EOF encountered while looking for expanded macro args!"); - if (TheTok.is(tok::r_paren)) - --ParenthesesDepth; + if (TheTok.is(tok::l_paren)) + ++ParenthesesDepth; - if (ParenthesesDepth == 0) - break; + if (TheTok.is(tok::r_paren)) + --ParenthesesDepth; - if (TheTok.is(tok::raw_identifier)) - PP.LookUpIdentifierInfo(TheTok); + if (ParenthesesDepth == 0) + break; - ExpandedArgTokens.push_back(TheTok); - RawLexer.LexFromRawLexer(TheTok); + if (TheTok.is(tok::raw_identifier)) + PP.LookUpIdentifierInfo(TheTok); + + ExpandedArgTokens.push_back(TheTok); + RawLexer.LexFromRawLexer(TheTok); + } + } else { + assert(UnexpArgII == __VA_ARGS__II); } Args.emplace(UnexpArgII, std::move(ExpandedArgTokens)); } - // TODO: The condition really should be TheTok.is(tok::r_paren), but variadic - // macro arguments are not handled yet. - assert(TheTok.isOneOf(tok::r_paren, tok::comma) && + assert(TheTok.is(tok::r_paren) && "Expanded macro argument acquisition failed! After the end of the loop" " this token should be ')'!"); 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 @@ -4217,7 +4217,7 @@ file0 nameVARIADIC_SET_TO_NULL - expansionptr = nullptr; variadicFunc( 1) + expansionptr = nullptr; variadicFunc( 1, 5, "haha!") descriptionDereference of null pointer (loaded from variable 'ptr') @@ -4257,12 +4257,12 @@ start - line333 + line324 col3 file0 - line333 + line324 col5 file0 @@ -4270,12 +4270,181 @@ end - line334 + line327 col3 file0 - line334 + line327 + col22 + file0 + + + + + + + kindevent + location + + line327 + col3 + file0 + + ranges + + + + line327 + col3 + file0 + + + line327 + col27 + file0 + + + + depth0 + extended_message + Null pointer value stored to 'ptr' + message + Null pointer value stored to 'ptr' + + + kindcontrol + edges + + + start + + + line328 + col3 + file0 + + + line328 + col3 + file0 + + + end + + + line328 + col8 + file0 + + + line328 + col8 + file0 + + + + + + + kindevent + location + + line328 + col8 + file0 + + ranges + + + + line328 + col4 + file0 + + + line328 + col6 + file0 + + + + depth0 + extended_message + Dereference of null pointer (loaded from variable 'ptr') + message + Dereference of null pointer (loaded from variable 'ptr') + + + macro_expansions + + + location + + line327 + col3 + file0 + + nameVARIADIC_SET_TO_NULL + expansionptr = nullptr; variadicFunc() + + + descriptionDereference of null pointer (loaded from variable 'ptr') + categoryLogic error + typeDereference of null pointer + check_namecore.NullDereference + + issue_hash_content_of_line_in_context6aa30fd6a1e997027333f16c2064d973 + issue_context_kindfunction + issue_contextvariadicMacroArgumentWithoutAnyArgumentTest + issue_hash_function_offset5 + location + + line328 + col8 + file0 + + ExecutedLines + + 0 + + 323 + 324 + 327 + 328 + + + + + path + + + kindcontrol + edges + + + start + + + line343 + col3 + file0 + + + line343 + col5 + file0 + + + end + + + line344 + col3 + file0 + + + line344 col30 file0 @@ -4287,7 +4456,7 @@ kindevent location - line334 + line344 col3 file0 @@ -4295,12 +4464,12 @@ - line334 + line344 col3 file0 - line334 + line344 col45 file0 @@ -4320,12 +4489,12 @@ start - line335 + line345 col3 file0 - line335 + line345 col3 file0 @@ -4333,12 +4502,12 @@ end - line335 + line345 col8 file0 - line335 + line345 col8 file0 @@ -4350,7 +4519,7 @@ kindevent location - line335 + line345 col8 file0 @@ -4358,12 +4527,12 @@ - line335 + line345 col4 file0 - line335 + line345 col6 file0 @@ -4381,7 +4550,7 @@ location - line334 + line344 col3 file0 @@ -4400,7 +4569,7 @@ issue_hash_function_offset3 location - line335 + line345 col8 file0 @@ -4408,10 +4577,10 @@ 0 - 332 - 333 - 334 - 335 + 342 + 343 + 344 + 345 @@ -4426,12 +4595,12 @@ start - line347 + line357 col3 file0 - line347 + line357 col5 file0 @@ -4439,12 +4608,12 @@ end - line348 + line358 col3 file0 - line348 + line358 col11 file0 @@ -4456,7 +4625,7 @@ kindevent location - line348 + line358 col3 file0 @@ -4464,12 +4633,12 @@ - line348 + line358 col3 file0 - line348 + line358 col23 file0 @@ -4489,12 +4658,12 @@ start - line349 + line359 col3 file0 - line349 + line359 col3 file0 @@ -4502,12 +4671,12 @@ end - line349 + line359 col8 file0 - line349 + line359 col8 file0 @@ -4519,7 +4688,7 @@ kindevent location - line349 + line359 col8 file0 @@ -4527,12 +4696,12 @@ - line349 + line359 col4 file0 - line349 + line359 col6 file0 @@ -4550,7 +4719,7 @@ location - line348 + line358 col3 file0 @@ -4569,7 +4738,7 @@ issue_hash_function_offset3 location - line349 + line359 col8 file0 @@ -4577,10 +4746,10 @@ 0 - 346 - 347 - 348 - 349 + 356 + 357 + 358 + 359 @@ -4595,12 +4764,12 @@ start - line396 + line406 col3 file0 - line396 + line406 col5 file0 @@ -4608,12 +4777,12 @@ end - line396 + line406 col18 file0 - line396 + line406 col43 file0 @@ -4625,7 +4794,7 @@ kindevent location - line396 + line406 col18 file0 @@ -4633,12 +4802,12 @@ - line396 + line406 col18 file0 - line396 + line406 col49 file0 @@ -4654,7 +4823,7 @@ kindevent location - line391 + line401 col1 file0 @@ -4672,12 +4841,12 @@ start - line391 + line401 col1 file0 - line391 + line401 col3 file0 @@ -4685,12 +4854,12 @@ end - line392 + line402 col3 file0 - line392 + line402 col21 file0 @@ -4702,7 +4871,7 @@ kindevent location - line392 + line402 col3 file0 @@ -4710,12 +4879,12 @@ - line392 + line402 col3 file0 - line392 + line402 col27 file0 @@ -4733,7 +4902,7 @@ location - line392 + line402 col3 file0 @@ -4752,7 +4921,7 @@ issue_hash_function_offset1 location - line392 + line402 col3 file0 @@ -4760,10 +4929,10 @@ 0 - 391 - 392 - 395 - 396 + 401 + 402 + 405 + 406 @@ -4778,12 +4947,12 @@ start - line411 + line421 col3 file0 - line411 + line421 col5 file0 @@ -4791,12 +4960,12 @@ end - line412 + line422 col3 file0 - line412 + line422 col25 file0 @@ -4808,7 +4977,7 @@ kindevent location - line412 + line422 col3 file0 @@ -4816,12 +4985,12 @@ - line412 + line422 col3 file0 - line412 + line422 col67 file0 @@ -4841,12 +5010,12 @@ start - line413 + line423 col3 file0 - line413 + line423 col3 file0 @@ -4854,12 +5023,12 @@ end - line413 + line423 col8 file0 - line413 + line423 col8 file0 @@ -4871,7 +5040,7 @@ kindevent location - line413 + line423 col8 file0 @@ -4879,12 +5048,12 @@ - line413 + line423 col4 file0 - line413 + line423 col6 file0 @@ -4902,7 +5071,7 @@ location - line412 + line422 col3 file0 @@ -4921,7 +5090,7 @@ issue_hash_function_offset3 location - line413 + line423 col8 file0 @@ -4929,10 +5098,10 @@ 0 - 410 - 411 - 412 - 413 + 420 + 421 + 422 + 423 Index: test/Analysis/plist-macros-with-expansion.cpp =================================================================== --- test/Analysis/plist-macros-with-expansion.cpp +++ test/Analysis/plist-macros-with-expansion.cpp @@ -317,9 +317,19 @@ *ptr = 5; // expected-warning{{Dereference of null pointer}} } -// TODO: Should correctly display the rest of the parameters. // CHECK: nameVARIADIC_SET_TO_NULL -// CHECK-NEXT: expansionptr = nullptr; variadicFunc( 1) +// CHECK-NEXT: expansionptr = nullptr; variadicFunc( 1, 5, "haha!") + +void variadicMacroArgumentWithoutAnyArgumentTest() { + int *ptr; + // Not adding a single parameter to ... is silly (and also causes a + // preprocessor warning), but is not an excuse to crash on it. + VARIADIC_SET_TO_NULL(ptr); + *ptr = 5; // expected-warning{{Dereference of null pointer}} +} + +// CHECK: nameVARIADIC_SET_TO_NULL +// CHECK-NEXT: expansionptr = nullptr; variadicFunc() //===----------------------------------------------------------------------===// // Tests for # and ##.