diff --git a/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp b/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
--- a/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
+++ b/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
@@ -1132,7 +1132,7 @@
std::string MacroName = PP.getSpelling(TheTok);
const auto *II = PP.getIdentifierInfo(MacroName);
- assert(II && "Failed to acquire the IndetifierInfo for the macro!");
+ assert(II && "Failed to acquire the IdentifierInfo for the macro!");
const MacroInfo *MI = getMacroInfoForLocation(PP, SM, II, ExpanLoc);
// assert(MI && "The macro must've been defined at it's expansion location!");
@@ -1180,9 +1180,16 @@
// * > 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__");
+ // If we encounter the variadic arg, we will lex until the closing
+ // tok::r_paren, even if we lex a tok::comma and ParanthesesDepth == 1.
+ const IdentifierInfo *VariadicParamII = PP.getIdentifierInfo("__VA_ARGS__");
+ if (MI->isGNUVarargs()) {
+ // If macro uses GNU-style variadic args, the param name is user-supplied,
+ // an not "__VA_ARGS__". E.g.:
+ // #define FOO(a, b, myvargs...)
+ // In this case, just use the last parameter:
+ VariadicParamII = *(MacroParams.rbegin());
+ }
for (const IdentifierInfo *CurrParamII : MacroParams) {
MacroParamMap::mapped_type ArgTokens;
@@ -1201,9 +1208,8 @@
// Lex the first token of the next macro parameter.
TStream.next(TheTok);
- while (
- !(ParenthesesDepth == 1 &&
- (CurrParamII == __VA_ARGS__II ? false : TheTok.is(tok::comma)))) {
+ while (CurrParamII == VariadicParamII || ParenthesesDepth != 1 ||
+ !TheTok.is(tok::comma)) {
assert(TheTok.isNot(tok::eof) &&
"EOF encountered while looking for expanded macro args!");
@@ -1226,7 +1232,7 @@
// PARAMS_RESOLVE_TO_VA_ARGS(__VA_ARGS__);
// // ^~~~~~~~~~~ Variadic parameter here
//
- // void mulitpleParamsResolveToVA_ARGS(void) {
+ // void multipleParamsResolveToVA_ARGS(void) {
// int x = 1;
// DISPATCH(x, "LF1M healer"); // Multiple arguments are mapped to
// // a single __VA_ARGS__ parameter.
@@ -1237,8 +1243,8 @@
// PARAMS_RESOLVE_TO_VA_ARGS. By this point, we already noted during
// the processing of DISPATCH what __VA_ARGS__ maps to, so we'll
// retrieve the next series of tokens from that.
- if (TheTok.getIdentifierInfo() == __VA_ARGS__II) {
- TStream.injectRange(PrevParamMap.at(__VA_ARGS__II));
+ if (TheTok.getIdentifierInfo() == VariadicParamII) {
+ TStream.injectRange(PrevParamMap.at(VariadicParamII));
TStream.next(TheTok);
continue;
}
@@ -1248,9 +1254,9 @@
TStream.next(TheTok);
}
} else {
- assert(CurrParamII == __VA_ARGS__II &&
+ assert(CurrParamII == VariadicParamII &&
"No more macro arguments are found, but the current parameter "
- "isn't __VA_ARGS__!");
+ "isn't the variadic arg!");
}
ParamMap.emplace(CurrParamII, std::move(ArgTokens));
diff --git a/clang/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist b/clang/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
--- a/clang/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
+++ b/clang/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
@@ -6787,6 +6787,221 @@
+
+ path
+
+
+ kindcontrol
+ edges
+
+
+ start
+
+
+ line539
+ col3
+ file0
+
+
+ line539
+ col5
+ file0
+
+
+ end
+
+
+ line540
+ col3
+ file0
+
+
+ line540
+ col13
+ file0
+
+
+
+
+
+
+ kindevent
+ location
+
+ line542
+ col3
+ file0
+
+ ranges
+
+
+
+ line542
+ col3
+ file0
+
+
+ line542
+ col7
+ file0
+
+
+
+ depth0
+ extended_message
+ 'a' declared without an initial value
+ message
+ 'a' declared without an initial value
+
+
+ kindcontrol
+ edges
+
+
+ start
+
+
+ line542
+ col3
+ file0
+
+
+ line542
+ col5
+ file0
+
+
+ end
+
+
+ line543
+ col3
+ file0
+
+
+ line543
+ col3
+ file0
+
+
+
+
+
+
+ kindcontrol
+ edges
+
+
+ start
+
+
+ line543
+ col3
+ file0
+
+
+ line543
+ col3
+ file0
+
+
+ end
+
+
+ line543
+ col5
+ file0
+
+
+ line543
+ col5
+ file0
+
+
+
+
+
+
+ kindevent
+ location
+
+ line543
+ col5
+ file0
+
+ ranges
+
+
+
+ line543
+ col3
+ file0
+
+
+ line543
+ col3
+ file0
+
+
+
+ depth0
+ extended_message
+ The left operand of '&' is a garbage value
+ message
+ The left operand of '&' is a garbage value
+
+
+ macro_expansions
+
+
+ location
+
+ line540
+ col3
+ file0
+
+ namebz44493_log
+ expansiondo { } while(0)
+
+
+ location
+
+ line541
+ col3
+ file0
+
+ namebz44493_log
+ expansiondo { } while(0)
+
+
+ descriptionThe left operand of '&' is a garbage value
+ categoryLogic error
+ typeResult of operation is garbage or undefined
+ check_namecore.UndefinedBinaryOperatorResult
+
+ issue_hash_content_of_line_in_context7515419ef7ac803c938efbeaf5ed1c6f
+ issue_context_kindfunction
+ issue_contextbz44493
+ issue_hash_function_offset5
+ location
+
+ line543
+ col5
+ file0
+
+ ExecutedLines
+
+ 0
+
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+
+
+
files
diff --git a/clang/test/Analysis/plist-macros-with-expansion.cpp b/clang/test/Analysis/plist-macros-with-expansion.cpp
--- a/clang/test/Analysis/plist-macros-with-expansion.cpp
+++ b/clang/test/Analysis/plist-macros-with-expansion.cpp
@@ -529,3 +529,17 @@
// FIXME: Stringify and escape __VA_ARGS__ correctly.
// CHECK: nameSTRINGIFIED_VA_ARGS
// CHECK-NEXT: expansionvariadicCFunction(x, "Additional supply depots required.", ")";x = 0;
+
+// bz44493: Support GNU-style named variadic arguments in plister
+#define bz44493_log(args...) \
+ do { \
+ } while (0)
+
+int bz44493(void) {
+ int x = 1;
+ bz44493_log("arg");
+ bz44493_log("arg", "arg2");
+ int a;
+ a & 0xffc00000; // expected-warning{{expression result unused}}
+ return 0;
+}