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 ##.