vabridgers created this revision.
vabridgers added a reviewer: Szelethus.
Herald added subscribers: steakhal, ASDenysPetrov, martong, Charusso, dkrupp, 
donat.nagy, mikhail.ramalho, a.sidorin, szepet, baloghadamsoftware, xazax.hun, 
whisperity.
vabridgers requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This change attempts to address
https://bugs.llvm.org/show_bug.cgi?id=48588.

In certain cases, it appears that __VA_ARGS__ is not in PrevParamMap
before it's accessed using at(). This change simply skips injectRange()
if __VA_ARGS__ is not found in PrevParamMap.

The crash seen is described below, the case this was discovered in was
distilled into a reproducer inserted into the LIT tests for this module.

terminate called after throwing an instance of 'std::out_of_range'

  what():  map::at
  
  #0 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int)
      <base>/llvm/lib/Support/Unix/Signals.inc:563:22

...

#11 std::__throw_out_of_range(char const*)

  <base>/libstdc++-v3/src/c++11/functexcept.cc:82:5

#12 std::map<clang::IdentifierInfo const*,

    llvm::SmallVector<clang::Token, 2u>, std::less<clang::IdentifierInfo
    const*>, std::allocator<std::pair<clang::IdentifierInfo const* const,
    llvm::SmallVector<clang::Token, 2u> > > >::at(clang::IdentifierInfo
    const* const&) const
  <base>/gcc/9.3.0/include/c++/9.3.0/bits/stl_map.h:549:10

#13 getMacroExpansionInfo((anonymous namespace)::MacroParamMap const&,

    clang::SourceLocation, clang::Preprocessor const&)
  <base>/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp:1242:66

...


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D93787

Files:
  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

Index: clang/test/Analysis/plist-macros-with-expansion.cpp
===================================================================
--- clang/test/Analysis/plist-macros-with-expansion.cpp
+++ clang/test/Analysis/plist-macros-with-expansion.cpp
@@ -543,3 +543,23 @@
 
 // CHECK: <key>name</key><string>BZ44493_GNUVA</string>
 // CHECK-NEXT: <key>expansion</key><string>--(a);</string>
+
+// Expected warning, and don't crash
+const char *traceid(const char *);
+int trace(int, const char *, int, ...);
+#define TRACE_CALL(tracelevel, ...) \
+  { __VA_ARGS__; }
+
+#define TRACE(tracelevel, str, ...) \
+  TRACE_CALL((tracelevel), trace((0), traceid("formatstr " str), 0, tracelevel, __VA_ARGS__))
+
+#define TRACE_WRAPPER TRACE
+
+void funcXXX(
+    void *Context_p) {
+  int localvar;
+  TRACE_WRAPPER(
+      localvar,
+      "localvar=%u ",
+      0); // expected-warning{{4th function call argument is an uninitialized value}}
+}
Index: clang/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
===================================================================
--- clang/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
+++ clang/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
@@ -6923,6 +6923,142 @@
    </array>
   </dict>
   </dict>
+  <dict>
+   <key>path</key>
+   <array>
+    <dict>
+     <key>kind</key><string>event</string>
+     <key>location</key>
+     <dict>
+      <key>line</key><integer>560</integer>
+      <key>col</key><integer>3</integer>
+      <key>file</key><integer>0</integer>
+     </dict>
+     <key>ranges</key>
+     <array>
+       <array>
+        <dict>
+         <key>line</key><integer>560</integer>
+         <key>col</key><integer>3</integer>
+         <key>file</key><integer>0</integer>
+        </dict>
+        <dict>
+         <key>line</key><integer>560</integer>
+         <key>col</key><integer>14</integer>
+         <key>file</key><integer>0</integer>
+        </dict>
+       </array>
+     </array>
+     <key>depth</key><integer>0</integer>
+     <key>extended_message</key>
+     <string>&apos;localvar&apos; declared without an initial value</string>
+     <key>message</key>
+     <string>&apos;localvar&apos; declared without an initial value</string>
+    </dict>
+    <dict>
+     <key>kind</key><string>control</string>
+     <key>edges</key>
+      <array>
+       <dict>
+        <key>start</key>
+         <array>
+          <dict>
+           <key>line</key><integer>560</integer>
+           <key>col</key><integer>3</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+          <dict>
+           <key>line</key><integer>560</integer>
+           <key>col</key><integer>5</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+         </array>
+        <key>end</key>
+         <array>
+          <dict>
+           <key>line</key><integer>561</integer>
+           <key>col</key><integer>3</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+          <dict>
+           <key>line</key><integer>561</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>561</integer>
+      <key>col</key><integer>3</integer>
+      <key>file</key><integer>0</integer>
+     </dict>
+     <key>ranges</key>
+     <array>
+       <array>
+        <dict>
+         <key>line</key><integer>561</integer>
+         <key>col</key><integer>3</integer>
+         <key>file</key><integer>0</integer>
+        </dict>
+        <dict>
+         <key>line</key><integer>564</integer>
+         <key>col</key><integer>12</integer>
+         <key>file</key><integer>0</integer>
+        </dict>
+       </array>
+     </array>
+     <key>depth</key><integer>0</integer>
+     <key>extended_message</key>
+     <string>4th function call argument is an uninitialized value</string>
+     <key>message</key>
+     <string>4th function call argument is an uninitialized value</string>
+    </dict>
+   </array>
+   <key>macro_expansions</key>
+   <array>
+    <dict>
+     <key>location</key>
+     <dict>
+      <key>line</key><integer>561</integer>
+      <key>col</key><integer>3</integer>
+      <key>file</key><integer>0</integer>
+     </dict>
+     <key>name</key><string>TRACE_WRAPPER</string>
+     <key>expansion</key><string>{ trace((0), traceid(&quot;formatstr &quot; str), 0, tracelevel,); }</string>
+    </dict>
+   </array>
+   <key>description</key><string>4th function call argument is an uninitialized value</string>
+   <key>category</key><string>Logic error</string>
+   <key>type</key><string>Uninitialized argument value</string>
+   <key>check_name</key><string>core.CallAndMessage</string>
+   <!-- This hash is experimental and going to change! -->
+   <key>issue_hash_content_of_line_in_context</key><string>7b4de363511977d731e5dfab4fd89c66</string>
+  <key>issue_context_kind</key><string>function</string>
+  <key>issue_context</key><string>funcXXX</string>
+  <key>issue_hash_function_offset</key><string>2</string>
+  <key>location</key>
+  <dict>
+   <key>line</key><integer>561</integer>
+   <key>col</key><integer>3</integer>
+   <key>file</key><integer>0</integer>
+  </dict>
+  <key>ExecutedLines</key>
+  <dict>
+   <key>0</key>
+   <array>
+    <integer>557</integer>
+    <integer>558</integer>
+    <integer>559</integer>
+    <integer>560</integer>
+    <integer>561</integer>
+   </array>
+  </dict>
+  </dict>
  </array>
  <key>files</key>
  <array>
Index: clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
+++ clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
@@ -1238,7 +1238,8 @@
           // the processing of DISPATCH what __VA_ARGS__ maps to, so we'll
           // retrieve the next series of tokens from that.
           if (TheTok.getIdentifierInfo() == VariadicParamII) {
-            TStream.injectRange(PrevParamMap.at(VariadicParamII));
+            if (PrevParamMap.find(VariadicParamII) != PrevParamMap.end())
+              TStream.injectRange(PrevParamMap.at(VariadicParamII));
             TStream.next(TheTok);
             continue;
           }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to