forked from OSchip/llvm-project
[Analyzer] GNU named variadic macros in Plister
Added support for GNU named variadic macros in macro expansion for plist generation. Fix for https://bugs.llvm.org/show_bug.cgi?id=44493 Reviewed By: Szelethus Differential Revision: https://reviews.llvm.org/D87942
This commit is contained in:
parent
7451bf0b0b
commit
2697d138a6
|
@ -1132,7 +1132,7 @@ getMacroExpansionInfo(const MacroParamMap &PrevParamMap,
|
|||
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 @@ getMacroExpansionInfo(const MacroParamMap &PrevParamMap,
|
|||
// * > 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 @@ getMacroExpansionInfo(const MacroParamMap &PrevParamMap,
|
|||
// 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 @@ getMacroExpansionInfo(const MacroParamMap &PrevParamMap,
|
|||
// 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 @@ getMacroExpansionInfo(const MacroParamMap &PrevParamMap,
|
|||
// 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 @@ getMacroExpansionInfo(const MacroParamMap &PrevParamMap,
|
|||
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));
|
||||
|
|
|
@ -6787,6 +6787,142 @@
|
|||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>path</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>kind</key><string>control</string>
|
||||
<key>edges</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>start</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>line</key><integer>537</integer>
|
||||
<key>col</key><integer>3</integer>
|
||||
<key>file</key><integer>0</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>line</key><integer>537</integer>
|
||||
<key>col</key><integer>5</integer>
|
||||
<key>file</key><integer>0</integer>
|
||||
</dict>
|
||||
</array>
|
||||
<key>end</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>line</key><integer>539</integer>
|
||||
<key>col</key><integer>3</integer>
|
||||
<key>file</key><integer>0</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>line</key><integer>539</integer>
|
||||
<key>col</key><integer>15</integer>
|
||||
<key>file</key><integer>0</integer>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>kind</key><string>event</string>
|
||||
<key>location</key>
|
||||
<dict>
|
||||
<key>line</key><integer>539</integer>
|
||||
<key>col</key><integer>3</integer>
|
||||
<key>file</key><integer>0</integer>
|
||||
</dict>
|
||||
<key>ranges</key>
|
||||
<array>
|
||||
<array>
|
||||
<dict>
|
||||
<key>line</key><integer>539</integer>
|
||||
<key>col</key><integer>3</integer>
|
||||
<key>file</key><integer>0</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>line</key><integer>539</integer>
|
||||
<key>col</key><integer>26</integer>
|
||||
<key>file</key><integer>0</integer>
|
||||
</dict>
|
||||
</array>
|
||||
</array>
|
||||
<key>depth</key><integer>0</integer>
|
||||
<key>extended_message</key>
|
||||
<string>The value 0 is assigned to 'a'</string>
|
||||
<key>message</key>
|
||||
<string>The value 0 is assigned to 'a'</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>kind</key><string>event</string>
|
||||
<key>location</key>
|
||||
<dict>
|
||||
<key>line</key><integer>540</integer>
|
||||
<key>col</key><integer>13</integer>
|
||||
<key>file</key><integer>0</integer>
|
||||
</dict>
|
||||
<key>ranges</key>
|
||||
<array>
|
||||
<array>
|
||||
<dict>
|
||||
<key>line</key><integer>540</integer>
|
||||
<key>col</key><integer>10</integer>
|
||||
<key>file</key><integer>0</integer>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>line</key><integer>540</integer>
|
||||
<key>col</key><integer>15</integer>
|
||||
<key>file</key><integer>0</integer>
|
||||
</dict>
|
||||
</array>
|
||||
</array>
|
||||
<key>depth</key><integer>0</integer>
|
||||
<key>extended_message</key>
|
||||
<string>Division by zero</string>
|
||||
<key>message</key>
|
||||
<string>Division by zero</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>macro_expansions</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>location</key>
|
||||
<dict>
|
||||
<key>line</key><integer>539</integer>
|
||||
<key>col</key><integer>3</integer>
|
||||
<key>file</key><integer>0</integer>
|
||||
</dict>
|
||||
<key>name</key><string>BZ44493_GNUVA</string>
|
||||
<key>expansion</key><string>--(a);</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>description</key><string>Division by zero</string>
|
||||
<key>category</key><string>Logic error</string>
|
||||
<key>type</key><string>Division by zero</string>
|
||||
<key>check_name</key><string>core.DivideZero</string>
|
||||
<!-- This hash is experimental and going to change! -->
|
||||
<key>issue_hash_content_of_line_in_context</key><string>21c6d180d8c8c30cf730b7a7136980a9</string>
|
||||
<key>issue_context_kind</key><string>function</string>
|
||||
<key>issue_context</key><string>bz44493</string>
|
||||
<key>issue_hash_function_offset</key><string>4</string>
|
||||
<key>location</key>
|
||||
<dict>
|
||||
<key>line</key><integer>540</integer>
|
||||
<key>col</key><integer>13</integer>
|
||||
<key>file</key><integer>0</integer>
|
||||
</dict>
|
||||
<key>ExecutedLines</key>
|
||||
<dict>
|
||||
<key>0</key>
|
||||
<array>
|
||||
<integer>536</integer>
|
||||
<integer>537</integer>
|
||||
<integer>538</integer>
|
||||
<integer>539</integer>
|
||||
<integer>540</integer>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
<key>files</key>
|
||||
<array>
|
||||
|
|
|
@ -529,3 +529,17 @@ void stringifyVA_ARGSEmpty(void) {
|
|||
// FIXME: Stringify and escape __VA_ARGS__ correctly.
|
||||
// CHECK: <key>name</key><string>STRINGIFIED_VA_ARGS</string>
|
||||
// CHECK-NEXT: <key>expansion</key><string>variadicCFunction(x, "Additional supply depots required.", ")";x = 0;</string>
|
||||
|
||||
// bz44493: Support GNU-style named variadic arguments in plister
|
||||
#define BZ44493_GNUVA(i, args...) --(i);
|
||||
|
||||
int bz44493(void) {
|
||||
int a = 2;
|
||||
BZ44493_GNUVA(a);
|
||||
BZ44493_GNUVA(a, "arg2");
|
||||
(void)(10 / a); // expected-warning{{Division by zero}}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// CHECK: <key>name</key><string>BZ44493_GNUVA</string>
|
||||
// CHECK-NEXT: <key>expansion</key><string>--(a);</string>
|
||||
|
|
Loading…
Reference in New Issue