[clang] 2697d13 - [Analyzer] GNU named variadic macros in Plister

Chris Hamilton via cfe-commits cfe-commits at lists.llvm.org
Mon Sep 21 13:39:11 PDT 2020


Author: Chris Hamilton
Date: 2020-09-21T15:38:28-05:00
New Revision: 2697d138a65a51b8cf58baa2d4a924c1f43af482

URL: https://github.com/llvm/llvm-project/commit/2697d138a65a51b8cf58baa2d4a924c1f43af482
DIFF: https://github.com/llvm/llvm-project/commit/2697d138a65a51b8cf58baa2d4a924c1f43af482.diff

LOG: [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

Added: 
    

Modified: 
    clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
    clang/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
    clang/test/Analysis/plist-macros-with-expansion.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp b/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
index ce4addd2f945..676d621e4978 100644
--- a/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
+++ b/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
@@ -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));

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
index 4a2741f0d493..61f9972672a2 100644
--- 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,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>

diff  --git a/clang/test/Analysis/plist-macros-with-expansion.cpp b/clang/test/Analysis/plist-macros-with-expansion.cpp
index f79070095385..a6e06b19bb2b 100644
--- a/clang/test/Analysis/plist-macros-with-expansion.cpp
+++ b/clang/test/Analysis/plist-macros-with-expansion.cpp
@@ -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>


        


More information about the cfe-commits mailing list