Szelethus created this revision.
Szelethus added reviewers: xazax.hun, NoQ, george.karpenkov, rnkovacs, 
baloghadamsoftware.
Herald added subscribers: cfe-commits, mikhail.ramalho, a.sidorin, szepet, 
whisperity.

>From what I can see, this should be the last patch needed to replicate macro 
>argument expansions.

Thanks again to @donat.nagy for spotting this!


Repository:
  rC Clang

https://reviews.llvm.org/D52988

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

Index: test/Analysis/plist-macros-with-expansion.cpp
===================================================================
--- test/Analysis/plist-macros-with-expansion.cpp
+++ test/Analysis/plist-macros-with-expansion.cpp
@@ -278,9 +278,17 @@
   *ptr = 5; // expected-warning{{Dereference of null pointer}}
 }
 
-// TODO: Should expand correctly.
 // CHECK: <key>name</key><string>DECLARE_FUNC_AND_SET_TO_NULL</string>
-// CHECK: <key>expansion</key><string>void generated_ ## whatever ( ) ; ptr = nullptr ; </string>
+// CHECK: <key>expansion</key><string>void generated_whatever ( ) ; ptr = nullptr ; </string>
+
+void macroArgContainsHashHashInStringTest() {
+  int *a;
+  TO_NULL_AND_PRINT(a, "Will this ## cause a crash?");
+  *a = 5; // expected-warning{{Dereference of null pointer}}
+}
+
+// CHECK: <key>name</key><string>TO_NULL_AND_PRINT</string>
+// CHECK: <key>expansion</key><string>a = 0 ; print ( &quot;Will this ## cause a crash?&quot; ) </string>
 
 #define PRINT_STR(str, ptr) \
   print(#str);              \
@@ -292,6 +300,14 @@
   *ptr = 5; // expected-warning{{Dereference of null pointer}}
 }
 
-// TODO: Should expand correctly.
 // CHECK: <key>name</key><string>PRINT_STR</string>
-// CHECK: <key>expansion</key><string>print ( # Hello ) ; ptr = nullptr </string>
+// CHECK: <key>expansion</key><string>print ( &quot;Hello&quot; ) ; ptr = nullptr </string>
+
+void macroArgContainsHashInStringTest() {
+  int *a;
+  TO_NULL_AND_PRINT(a, "Will this # cause a crash?");
+  *a = 5; // expected-warning{{Dereference of null pointer}}
+}
+
+// CHECK: <key>name</key><string>TO_NULL_AND_PRINT</string>
+// CHECK: <key>expansion</key><string>a = 0 ; print ( &quot;Will this # cause a crash?&quot; ) </string>
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
@@ -3,7 +3,7 @@
 <plist version="1.0">
 <dict>
  <key>clang_version</key>
-<string>clang version 8.0.0 (http://mainstream.inf.elte.hu/Szelethus/clang 531e9e44e37061619212a542a5d1076525fdbea9) (https://github.com/llvm-mirror/llvm 1ffbf26a1a0a190d69327af875a3337b74a2ce82)</string>
+<string>clang version 8.0.0 (http://mainstream.inf.elte.hu/Szelethus/clang 263b6f72a3ff1483b445ba5bd8c1cdefcad4f6f6) (https://github.com/llvm-mirror/llvm 1ffbf26a1a0a190d69327af875a3337b74a2ce82)</string>
  <key>diagnostics</key>
  <array>
   <dict>
@@ -3757,7 +3757,7 @@
       <key>file</key><integer>0</integer>
      </dict>
      <key>name</key><string>DECLARE_FUNC_AND_SET_TO_NULL</string>
-     <key>expansion</key><string>void generated_ ## whatever ( ) ; ptr = nullptr ; </string>
+     <key>expansion</key><string>void generated_whatever ( ) ; ptr = nullptr ; </string>
     </dict>
     <dict>
      <key>kind</key><string>event</string>
@@ -3889,25 +3889,192 @@
         <key>start</key>
          <array>
           <dict>
-           <key>line</key><integer>290</integer>
+           <key>line</key><integer>285</integer>
            <key>col</key><integer>3</integer>
            <key>file</key><integer>0</integer>
           </dict>
           <dict>
-           <key>line</key><integer>290</integer>
+           <key>line</key><integer>285</integer>
            <key>col</key><integer>5</integer>
            <key>file</key><integer>0</integer>
           </dict>
          </array>
         <key>end</key>
          <array>
           <dict>
-           <key>line</key><integer>291</integer>
+           <key>line</key><integer>286</integer>
            <key>col</key><integer>3</integer>
            <key>file</key><integer>0</integer>
           </dict>
           <dict>
-           <key>line</key><integer>291</integer>
+           <key>line</key><integer>286</integer>
+           <key>col</key><integer>19</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+         </array>
+       </dict>
+      </array>
+    </dict>
+    <dict>
+     <key>kind</key><string>macro_expansion</string>
+     <key>location</key>
+     <dict>
+      <key>line</key><integer>286</integer>
+      <key>col</key><integer>3</integer>
+      <key>file</key><integer>0</integer>
+     </dict>
+     <key>name</key><string>TO_NULL_AND_PRINT</string>
+     <key>expansion</key><string>a = 0 ; print ( &quot;Will this ## cause a crash?&quot; ) </string>
+    </dict>
+    <dict>
+     <key>kind</key><string>event</string>
+     <key>location</key>
+     <dict>
+      <key>line</key><integer>286</integer>
+      <key>col</key><integer>3</integer>
+      <key>file</key><integer>0</integer>
+     </dict>
+     <key>ranges</key>
+     <array>
+       <array>
+        <dict>
+         <key>line</key><integer>286</integer>
+         <key>col</key><integer>3</integer>
+         <key>file</key><integer>0</integer>
+        </dict>
+        <dict>
+         <key>line</key><integer>286</integer>
+         <key>col</key><integer>53</integer>
+         <key>file</key><integer>0</integer>
+        </dict>
+       </array>
+     </array>
+     <key>depth</key><integer>0</integer>
+     <key>extended_message</key>
+     <string>Null pointer value stored to &apos;a&apos;</string>
+     <key>message</key>
+     <string>Null pointer value stored to &apos;a&apos;</string>
+    </dict>
+    <dict>
+     <key>kind</key><string>control</string>
+     <key>edges</key>
+      <array>
+       <dict>
+        <key>start</key>
+         <array>
+          <dict>
+           <key>line</key><integer>287</integer>
+           <key>col</key><integer>3</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+          <dict>
+           <key>line</key><integer>287</integer>
+           <key>col</key><integer>3</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+         </array>
+        <key>end</key>
+         <array>
+          <dict>
+           <key>line</key><integer>287</integer>
+           <key>col</key><integer>6</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+          <dict>
+           <key>line</key><integer>287</integer>
+           <key>col</key><integer>6</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>287</integer>
+      <key>col</key><integer>6</integer>
+      <key>file</key><integer>0</integer>
+     </dict>
+     <key>ranges</key>
+     <array>
+       <array>
+        <dict>
+         <key>line</key><integer>287</integer>
+         <key>col</key><integer>4</integer>
+         <key>file</key><integer>0</integer>
+        </dict>
+        <dict>
+         <key>line</key><integer>287</integer>
+         <key>col</key><integer>4</integer>
+         <key>file</key><integer>0</integer>
+        </dict>
+       </array>
+     </array>
+     <key>depth</key><integer>0</integer>
+     <key>extended_message</key>
+     <string>Dereference of null pointer (loaded from variable &apos;a&apos;)</string>
+     <key>message</key>
+     <string>Dereference of null pointer (loaded from variable &apos;a&apos;)</string>
+    </dict>
+   </array>
+   <key>description</key><string>Dereference of null pointer (loaded from variable &apos;a&apos;)</string>
+   <key>category</key><string>Logic error</string>
+   <key>type</key><string>Dereference of null pointer</string>
+   <key>check_name</key><string>core.NullDereference</string>
+   <!-- This hash is experimental and going to change! -->
+   <key>issue_hash_content_of_line_in_context</key><string>6817572ced27cb7d28fc87b2aba75fb4</string>
+  <key>issue_context_kind</key><string>function</string>
+  <key>issue_context</key><string>macroArgContainsHashHashInStringTest</string>
+  <key>issue_hash_function_offset</key><string>3</string>
+  <key>location</key>
+  <dict>
+   <key>line</key><integer>287</integer>
+   <key>col</key><integer>6</integer>
+   <key>file</key><integer>0</integer>
+  </dict>
+  <key>ExecutedLines</key>
+  <dict>
+   <key>0</key>
+   <array>
+    <integer>284</integer>
+    <integer>285</integer>
+    <integer>286</integer>
+    <integer>287</integer>
+   </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>298</integer>
+           <key>col</key><integer>3</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+          <dict>
+           <key>line</key><integer>298</integer>
+           <key>col</key><integer>5</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+         </array>
+        <key>end</key>
+         <array>
+          <dict>
+           <key>line</key><integer>299</integer>
+           <key>col</key><integer>3</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+          <dict>
+           <key>line</key><integer>299</integer>
            <key>col</key><integer>11</integer>
            <key>file</key><integer>0</integer>
           </dict>
@@ -3919,31 +4086,31 @@
      <key>kind</key><string>macro_expansion</string>
      <key>location</key>
      <dict>
-      <key>line</key><integer>291</integer>
+      <key>line</key><integer>299</integer>
       <key>col</key><integer>3</integer>
       <key>file</key><integer>0</integer>
      </dict>
      <key>name</key><string>PRINT_STR</string>
-     <key>expansion</key><string>print ( # Hello ) ; ptr = nullptr </string>
+     <key>expansion</key><string>print ( &quot;Hello &quot;) ; ptr = nullptr </string>
     </dict>
     <dict>
      <key>kind</key><string>event</string>
      <key>location</key>
      <dict>
-      <key>line</key><integer>291</integer>
+      <key>line</key><integer>299</integer>
       <key>col</key><integer>3</integer>
       <key>file</key><integer>0</integer>
      </dict>
      <key>ranges</key>
      <array>
        <array>
         <dict>
-         <key>line</key><integer>291</integer>
+         <key>line</key><integer>299</integer>
          <key>col</key><integer>3</integer>
          <key>file</key><integer>0</integer>
         </dict>
         <dict>
-         <key>line</key><integer>291</integer>
+         <key>line</key><integer>299</integer>
          <key>col</key><integer>23</integer>
          <key>file</key><integer>0</integer>
         </dict>
@@ -3963,25 +4130,25 @@
         <key>start</key>
          <array>
           <dict>
-           <key>line</key><integer>292</integer>
+           <key>line</key><integer>300</integer>
            <key>col</key><integer>3</integer>
            <key>file</key><integer>0</integer>
           </dict>
           <dict>
-           <key>line</key><integer>292</integer>
+           <key>line</key><integer>300</integer>
            <key>col</key><integer>3</integer>
            <key>file</key><integer>0</integer>
           </dict>
          </array>
         <key>end</key>
          <array>
           <dict>
-           <key>line</key><integer>292</integer>
+           <key>line</key><integer>300</integer>
            <key>col</key><integer>8</integer>
            <key>file</key><integer>0</integer>
           </dict>
           <dict>
-           <key>line</key><integer>292</integer>
+           <key>line</key><integer>300</integer>
            <key>col</key><integer>8</integer>
            <key>file</key><integer>0</integer>
           </dict>
@@ -3993,20 +4160,20 @@
      <key>kind</key><string>event</string>
      <key>location</key>
      <dict>
-      <key>line</key><integer>292</integer>
+      <key>line</key><integer>300</integer>
       <key>col</key><integer>8</integer>
       <key>file</key><integer>0</integer>
      </dict>
      <key>ranges</key>
      <array>
        <array>
         <dict>
-         <key>line</key><integer>292</integer>
+         <key>line</key><integer>300</integer>
          <key>col</key><integer>4</integer>
          <key>file</key><integer>0</integer>
         </dict>
         <dict>
-         <key>line</key><integer>292</integer>
+         <key>line</key><integer>300</integer>
          <key>col</key><integer>6</integer>
          <key>file</key><integer>0</integer>
         </dict>
@@ -4030,18 +4197,185 @@
   <key>issue_hash_function_offset</key><string>3</string>
   <key>location</key>
   <dict>
-   <key>line</key><integer>292</integer>
+   <key>line</key><integer>300</integer>
    <key>col</key><integer>8</integer>
    <key>file</key><integer>0</integer>
   </dict>
   <key>ExecutedLines</key>
   <dict>
    <key>0</key>
    <array>
-    <integer>289</integer>
-    <integer>290</integer>
-    <integer>291</integer>
-    <integer>292</integer>
+    <integer>297</integer>
+    <integer>298</integer>
+    <integer>299</integer>
+    <integer>300</integer>
+   </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>307</integer>
+           <key>col</key><integer>3</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+          <dict>
+           <key>line</key><integer>307</integer>
+           <key>col</key><integer>5</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+         </array>
+        <key>end</key>
+         <array>
+          <dict>
+           <key>line</key><integer>308</integer>
+           <key>col</key><integer>3</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+          <dict>
+           <key>line</key><integer>308</integer>
+           <key>col</key><integer>19</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+         </array>
+       </dict>
+      </array>
+    </dict>
+    <dict>
+     <key>kind</key><string>macro_expansion</string>
+     <key>location</key>
+     <dict>
+      <key>line</key><integer>308</integer>
+      <key>col</key><integer>3</integer>
+      <key>file</key><integer>0</integer>
+     </dict>
+     <key>name</key><string>TO_NULL_AND_PRINT</string>
+     <key>expansion</key><string>a = 0 ; print ( &quot;Will this # cause a crash?&quot; ) </string>
+    </dict>
+    <dict>
+     <key>kind</key><string>event</string>
+     <key>location</key>
+     <dict>
+      <key>line</key><integer>308</integer>
+      <key>col</key><integer>3</integer>
+      <key>file</key><integer>0</integer>
+     </dict>
+     <key>ranges</key>
+     <array>
+       <array>
+        <dict>
+         <key>line</key><integer>308</integer>
+         <key>col</key><integer>3</integer>
+         <key>file</key><integer>0</integer>
+        </dict>
+        <dict>
+         <key>line</key><integer>308</integer>
+         <key>col</key><integer>52</integer>
+         <key>file</key><integer>0</integer>
+        </dict>
+       </array>
+     </array>
+     <key>depth</key><integer>0</integer>
+     <key>extended_message</key>
+     <string>Null pointer value stored to &apos;a&apos;</string>
+     <key>message</key>
+     <string>Null pointer value stored to &apos;a&apos;</string>
+    </dict>
+    <dict>
+     <key>kind</key><string>control</string>
+     <key>edges</key>
+      <array>
+       <dict>
+        <key>start</key>
+         <array>
+          <dict>
+           <key>line</key><integer>309</integer>
+           <key>col</key><integer>3</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+          <dict>
+           <key>line</key><integer>309</integer>
+           <key>col</key><integer>3</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+         </array>
+        <key>end</key>
+         <array>
+          <dict>
+           <key>line</key><integer>309</integer>
+           <key>col</key><integer>6</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+          <dict>
+           <key>line</key><integer>309</integer>
+           <key>col</key><integer>6</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>309</integer>
+      <key>col</key><integer>6</integer>
+      <key>file</key><integer>0</integer>
+     </dict>
+     <key>ranges</key>
+     <array>
+       <array>
+        <dict>
+         <key>line</key><integer>309</integer>
+         <key>col</key><integer>4</integer>
+         <key>file</key><integer>0</integer>
+        </dict>
+        <dict>
+         <key>line</key><integer>309</integer>
+         <key>col</key><integer>4</integer>
+         <key>file</key><integer>0</integer>
+        </dict>
+       </array>
+     </array>
+     <key>depth</key><integer>0</integer>
+     <key>extended_message</key>
+     <string>Dereference of null pointer (loaded from variable &apos;a&apos;)</string>
+     <key>message</key>
+     <string>Dereference of null pointer (loaded from variable &apos;a&apos;)</string>
+    </dict>
+   </array>
+   <key>description</key><string>Dereference of null pointer (loaded from variable &apos;a&apos;)</string>
+   <key>category</key><string>Logic error</string>
+   <key>type</key><string>Dereference of null pointer</string>
+   <key>check_name</key><string>core.NullDereference</string>
+   <!-- This hash is experimental and going to change! -->
+   <key>issue_hash_content_of_line_in_context</key><string>b1da2db423e721067ed5cfda858890be</string>
+  <key>issue_context_kind</key><string>function</string>
+  <key>issue_context</key><string>macroArgContainsHashInStringTest</string>
+  <key>issue_hash_function_offset</key><string>3</string>
+  <key>location</key>
+  <dict>
+   <key>line</key><integer>309</integer>
+   <key>col</key><integer>6</integer>
+   <key>file</key><integer>0</integer>
+  </dict>
+  <key>ExecutedLines</key>
+  <dict>
+   <key>0</key>
+   <array>
+    <integer>306</integer>
+    <integer>307</integer>
+    <integer>308</integer>
+    <integer>309</integer>
    </array>
   </dict>
   </dict>
Index: lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
===================================================================
--- lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
+++ lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
@@ -785,17 +785,46 @@
 
       // If this token is the current macro's argument, we should expand it.
       if (Args && Args->count(II)) {
+
+        bool WasPreviousTokenHash = false;
+        if (It != MI->tokens_begin())
+          WasPreviousTokenHash = (It - 1)->is(tok::hash);
+
+        // If WasPreviousTokenHash is true, the starting '"' was printed in the
+        // previous iteration.
+
         for (const Token &ExpandedArgT : Args->at(II)) {
-          ExpansionOS << PP.getSpelling(ExpandedArgT) + ' ';
+          ExpansionOS << PP.getSpelling(ExpandedArgT);
+
+          // If the previous token was #, printing spaces would modify a string.
+          if (!WasPreviousTokenHash)
+            ExpansionOS << ' ';
         }
+
+        if (WasPreviousTokenHash)
+          ExpansionOS << "\" ";
         continue;
       }
     }
 
-    // TODO: Handle tok::hash and tok::hashhash.
-
     // If control reaches here, there's nothing left to do, print the token.
-    ExpansionOS << PP.getSpelling(T) + ' ';
+    ExpansionOS << PP.getSpelling(T);
+
+    if (It != E) {
+      Token NextTok = *(It + 1);
+
+      if (NextTok.is(tok::hash))
+        ExpansionOS << " \"";
+
+      if (NextTok.isOneOf(tok::hash, tok::hashhash)) {
+        // Don't print the # or ## token.
+        ++It;
+        // Don't print space.
+        continue;
+      }
+    }
+
+    ExpansionOS << ' ';
   }
 
   return {MacroName, ExpansionOS.str()};
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to