r367006 - [CrossTU] Fix plist macro expansion if macro in other file.

Balazs Keri via cfe-commits cfe-commits at lists.llvm.org
Thu Jul 25 03:53:22 PDT 2019


Author: balazske
Date: Thu Jul 25 03:53:22 2019
New Revision: 367006

URL: http://llvm.org/viewvc/llvm-project?rev=367006&view=rev
Log:
[CrossTU] Fix plist macro expansion if macro in other file.

Summary:
When cross TU analysis is used it is possible that a macro expansion
is generated for a macro that is defined (and used) in other than
the main translation unit. To get the expansion for it the source
location in the original source file and original preprocessor
is needed.

Reviewers: martong, xazax.hun, Szelethus, ilya-biryukov

Reviewed By: Szelethus

Subscribers: mgorny, NoQ, ilya-biryukov, rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D64638

Added:
    cfe/trunk/test/Analysis/Inputs/plist-macros-ctu.c
    cfe/trunk/test/Analysis/Inputs/plist-macros-ctu.h
    cfe/trunk/test/Analysis/Inputs/plist-macros-with-expansion-ctu.c.externalDefMap.txt
    cfe/trunk/test/Analysis/plist-macros-with-expansion-ctu.c
Modified:
    cfe/trunk/lib/StaticAnalyzer/Core/CMakeLists.txt
    cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CMakeLists.txt?rev=367006&r1=367005&r2=367006&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CMakeLists.txt (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CMakeLists.txt Thu Jul 25 03:53:22 2019
@@ -53,6 +53,7 @@ add_clang_library(clangStaticAnalyzerCor
   clangAnalysis
   clangBasic
   clangCrossTU
+  clangFrontend
   clangLex
   clangRewrite
   )

Modified: cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp?rev=367006&r1=367005&r2=367006&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp Thu Jul 25 03:53:22 2019
@@ -15,6 +15,7 @@
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/Version.h"
 #include "clang/CrossTU/CrossTranslationUnit.h"
+#include "clang/Frontend/ASTUnit.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Lex/TokenConcatenation.h"
 #include "clang/Rewrite/Core/HTMLRewrite.h"
@@ -75,12 +76,14 @@ class PlistPrinter {
   const FIDMap& FM;
   AnalyzerOptions &AnOpts;
   const Preprocessor &PP;
+  const cross_tu::CrossTranslationUnitContext &CTU;
   llvm::SmallVector<const PathDiagnosticMacroPiece *, 0> MacroPieces;
 
 public:
   PlistPrinter(const FIDMap& FM, AnalyzerOptions &AnOpts,
-               const Preprocessor &PP)
-    : FM(FM), AnOpts(AnOpts), PP(PP) {
+               const Preprocessor &PP,
+               const cross_tu::CrossTranslationUnitContext &CTU)
+    : FM(FM), AnOpts(AnOpts), PP(PP), CTU(CTU) {
   }
 
   void ReportDiag(raw_ostream &o, const PathDiagnosticPiece& P) {
@@ -162,8 +165,8 @@ struct ExpansionInfo {
 } // end of anonymous namespace
 
 static void printBugPath(llvm::raw_ostream &o, const FIDMap& FM,
-                         AnalyzerOptions &AnOpts,
-                         const Preprocessor &PP,
+                         AnalyzerOptions &AnOpts, const Preprocessor &PP,
+                         const cross_tu::CrossTranslationUnitContext &CTU,
                          const PathPieces &Path);
 
 /// Print coverage information to output stream {@code o}.
@@ -174,8 +177,9 @@ static void printCoverage(const PathDiag
                           FIDMap &FM,
                           llvm::raw_fd_ostream &o);
 
-static ExpansionInfo getExpandedMacro(SourceLocation MacroLoc,
-                                      const Preprocessor &PP);
+static ExpansionInfo
+getExpandedMacro(SourceLocation MacroLoc, const Preprocessor &PP,
+                 const cross_tu::CrossTranslationUnitContext &CTU);
 
 //===----------------------------------------------------------------------===//
 // Methods of PlistPrinter.
@@ -349,7 +353,7 @@ void PlistPrinter::ReportMacroExpansions
 
   for (const PathDiagnosticMacroPiece *P : MacroPieces) {
     const SourceManager &SM = PP.getSourceManager();
-    ExpansionInfo EI = getExpandedMacro(P->getLocation().asLocation(), PP);
+    ExpansionInfo EI = getExpandedMacro(P->getLocation().asLocation(), PP, CTU);
 
     Indent(o, indent) << "<dict>\n";
     ++indent;
@@ -471,10 +475,10 @@ static void printCoverage(const PathDiag
 }
 
 static void printBugPath(llvm::raw_ostream &o, const FIDMap& FM,
-                         AnalyzerOptions &AnOpts,
-                         const Preprocessor &PP,
+                         AnalyzerOptions &AnOpts, const Preprocessor &PP,
+                         const cross_tu::CrossTranslationUnitContext &CTU,
                          const PathPieces &Path) {
-  PlistPrinter Printer(FM, AnOpts, PP);
+  PlistPrinter Printer(FM, AnOpts, PP, CTU);
   assert(std::is_partitioned(
            Path.begin(), Path.end(),
            [](const std::shared_ptr<PathDiagnosticPiece> &E)
@@ -619,7 +623,7 @@ void PlistDiagnostics::FlushDiagnosticsI
     o << "  <dict>\n";
 
     const PathDiagnostic *D = *DI;
-    printBugPath(o, FM, AnOpts, PP, D->path);
+    printBugPath(o, FM, AnOpts, PP, CTU, D->path);
 
     // Output the bug type and bug category.
     o << "   <key>description</key>";
@@ -872,17 +876,23 @@ static const MacroInfo *getMacroInfoForL
 // Definitions of helper functions and methods for expanding macros.
 //===----------------------------------------------------------------------===//
 
-static ExpansionInfo getExpandedMacro(SourceLocation MacroLoc,
-                                      const Preprocessor &PP) {
+static ExpansionInfo
+getExpandedMacro(SourceLocation MacroLoc, const Preprocessor &PP,
+                 const cross_tu::CrossTranslationUnitContext &CTU) {
+
+  const Preprocessor *PPToUse = &PP;
+  if (auto LocAndUnit = CTU.getImportedFromSourceLocation(MacroLoc)) {
+    MacroLoc = LocAndUnit->first;
+    PPToUse = &LocAndUnit->second->getPreprocessor();
+  }
 
   llvm::SmallString<200> ExpansionBuf;
   llvm::raw_svector_ostream OS(ExpansionBuf);
-  TokenPrinter Printer(OS, PP);
+  TokenPrinter Printer(OS, *PPToUse);
   llvm::SmallPtrSet<IdentifierInfo*, 8> AlreadyProcessedTokens;
 
-  std::string MacroName =
-            getMacroNameAndPrintExpansion(Printer, MacroLoc, PP, MacroArgMap{},
-                                         AlreadyProcessedTokens);
+  std::string MacroName = getMacroNameAndPrintExpansion(
+      Printer, MacroLoc, *PPToUse, MacroArgMap{}, AlreadyProcessedTokens);
   return { MacroName, OS.str() };
 }
 

Added: cfe/trunk/test/Analysis/Inputs/plist-macros-ctu.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/Inputs/plist-macros-ctu.c?rev=367006&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/Inputs/plist-macros-ctu.c (added)
+++ cfe/trunk/test/Analysis/Inputs/plist-macros-ctu.c Thu Jul 25 03:53:22 2019
@@ -0,0 +1,21 @@
+
+#include "plist-macros-ctu.h"
+
+#define M *X = (int *)0
+
+void F1(int **X) {
+  M;
+}
+
+#undef M
+#define M *Y = (int *)0
+
+void F2(int **Y) {
+  M;
+}
+
+#define M1 *Z = (int *)0
+
+void F3(int **Z) {
+  M1;
+}

Added: cfe/trunk/test/Analysis/Inputs/plist-macros-ctu.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/Inputs/plist-macros-ctu.h?rev=367006&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/Inputs/plist-macros-ctu.h (added)
+++ cfe/trunk/test/Analysis/Inputs/plist-macros-ctu.h Thu Jul 25 03:53:22 2019
@@ -0,0 +1,4 @@
+#define M_H *A = (int *)0
+void F_H(int **A) {
+  M_H;
+}

Added: cfe/trunk/test/Analysis/Inputs/plist-macros-with-expansion-ctu.c.externalDefMap.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/Inputs/plist-macros-with-expansion-ctu.c.externalDefMap.txt?rev=367006&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/Inputs/plist-macros-with-expansion-ctu.c.externalDefMap.txt (added)
+++ cfe/trunk/test/Analysis/Inputs/plist-macros-with-expansion-ctu.c.externalDefMap.txt Thu Jul 25 03:53:22 2019
@@ -0,0 +1,4 @@
+c:@F at F1 plist-macros-ctu.c.ast
+c:@F at F2 plist-macros-ctu.c.ast
+c:@F at F3 plist-macros-ctu.c.ast
+c:@F at F_H plist-macros-ctu.c.ast

Added: cfe/trunk/test/Analysis/plist-macros-with-expansion-ctu.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/plist-macros-with-expansion-ctu.c?rev=367006&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/plist-macros-with-expansion-ctu.c (added)
+++ cfe/trunk/test/Analysis/plist-macros-with-expansion-ctu.c Thu Jul 25 03:53:22 2019
@@ -0,0 +1,80 @@
+// RUN: rm -rf %t && mkdir %t
+// RUN: mkdir -p %t/ctudir
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu \
+// RUN:   -emit-pch -o %t/ctudir/plist-macros-ctu.c.ast %S/Inputs/plist-macros-ctu.c
+// RUN: cp %S/Inputs/plist-macros-with-expansion-ctu.c.externalDefMap.txt %t/ctudir/externalDefMap.txt
+
+// RUN: %clang_analyze_cc1 -analyzer-checker=core \
+// RUN:   -analyzer-config experimental-enable-naive-ctu-analysis=true \
+// RUN:   -analyzer-config ctu-dir=%t/ctudir \
+// RUN:   -analyzer-config expand-macros=true \
+// RUN:   -analyzer-output=plist-multi-file -o %t.plist -verify %s
+
+// Check the macro expansions from the plist output here, to make the test more
+// understandable.
+//   RUN: FileCheck --input-file=%t.plist %s
+
+extern void F1(int **);
+extern void F2(int **);
+extern void F3(int **);
+extern void F_H(int **);
+
+void test0() {
+  int *X;
+  F3(&X);
+  *X = 1; // expected-warning{{Dereference of null pointer}}
+}
+// CHECK: <key>name</key><string>M1</string>
+// CHECK-NEXT: <key>expansion</key><string>*Z = (int *)0</string>
+
+
+void test1() {
+  int *X;
+  F1(&X);
+  *X = 1; // expected-warning{{Dereference of null pointer}}
+}
+// CHECK: <key>name</key><string>M</string>
+// CHECK-NEXT: <key>expansion</key><string>*X = (int *)0</string>
+
+void test2() {
+  int *X;
+  F2(&X);
+  *X = 1; // expected-warning{{Dereference of null pointer}}
+}
+// CHECK: <key>name</key><string>M</string>
+// CHECK-NEXT: <key>expansion</key><string>*Y = (int *)0</string>
+
+#define M F1(&X)
+
+void test3() {
+  int *X;
+  M;
+  *X = 1; // expected-warning{{Dereference of null pointer}}
+}
+// CHECK: <key>name</key><string>M</string>
+// CHECK-NEXT: <key>expansion</key><string>F1(&X)</string>
+// CHECK: <key>name</key><string>M</string>
+// CHECK-NEXT: <key>expansion</key><string>*X = (int *)0</string>
+
+#undef M
+#define M F2(&X)
+
+void test4() {
+  int *X;
+  M;
+  *X = 1; // expected-warning{{Dereference of null pointer}}
+}
+
+// CHECK: <key>name</key><string>M</string>
+// CHECK-NEXT: <key>expansion</key><string>F2(&X)</string>
+// CHECK: <key>name</key><string>M</string>
+// CHECK-NEXT: <key>expansion</key><string>*Y = (int *)0</string>
+
+void test_h() {
+  int *X;
+  F_H(&X);
+  *X = 1; // expected-warning{{Dereference of null pointer}}
+}
+
+// CHECK: <key>name</key><string>M_H</string>
+// CHECK-NEXT: <key>expansion</key><string>*A = (int *)0</string>




More information about the cfe-commits mailing list