[PATCH] D64638: [CrossTU] Fix plist macro expansion if macro in other file.

2019-07-25 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added a comment.

Problem should be fixed now (r367013).


Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D64638/new/

https://reviews.llvm.org/D64638



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D64638: [CrossTU] Fix plist macro expansion if macro in other file.

2019-07-25 Thread Simon Pilgrim via Phabricator via cfe-commits
RKSimon added a comment.

@balazske This is causing buildbot failures - revert?


Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D64638/new/

https://reviews.llvm.org/D64638



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D64638: [CrossTU] Fix plist macro expansion if macro in other file.

2019-07-25 Thread Balázs Kéri via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL367006: [CrossTU] Fix plist macro expansion if macro in 
other file. (authored by balazske, committed by ).
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D64638/new/

https://reviews.llvm.org/D64638

Files:
  cfe/trunk/lib/StaticAnalyzer/Core/CMakeLists.txt
  cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
  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

Index: cfe/trunk/test/Analysis/plist-macros-with-expansion-ctu.c
===
--- cfe/trunk/test/Analysis/plist-macros-with-expansion-ctu.c
+++ cfe/trunk/test/Analysis/plist-macros-with-expansion-ctu.c
@@ -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 = 1; // expected-warning{{Dereference of null pointer}}
+}
+// CHECK: nameM1
+// CHECK-NEXT: expansion*Z = (int *)0
+
+
+void test1() {
+  int *X;
+  F1();
+  *X = 1; // expected-warning{{Dereference of null pointer}}
+}
+// CHECK: nameM
+// CHECK-NEXT: expansion*X = (int *)0
+
+void test2() {
+  int *X;
+  F2();
+  *X = 1; // expected-warning{{Dereference of null pointer}}
+}
+// CHECK: nameM
+// CHECK-NEXT: expansion*Y = (int *)0
+
+#define M F1()
+
+void test3() {
+  int *X;
+  M;
+  *X = 1; // expected-warning{{Dereference of null pointer}}
+}
+// CHECK: nameM
+// CHECK-NEXT: expansionF1(X)
+// CHECK: nameM
+// CHECK-NEXT: expansion*X = (int *)0
+
+#undef M
+#define M F2()
+
+void test4() {
+  int *X;
+  M;
+  *X = 1; // expected-warning{{Dereference of null pointer}}
+}
+
+// CHECK: nameM
+// CHECK-NEXT: expansionF2(X)
+// CHECK: nameM
+// CHECK-NEXT: expansion*Y = (int *)0
+
+void test_h() {
+  int *X;
+  F_H();
+  *X = 1; // expected-warning{{Dereference of null pointer}}
+}
+
+// CHECK: nameM_H
+// CHECK-NEXT: expansion*A = (int *)0
Index: cfe/trunk/test/Analysis/Inputs/plist-macros-ctu.c
===
--- cfe/trunk/test/Analysis/Inputs/plist-macros-ctu.c
+++ cfe/trunk/test/Analysis/Inputs/plist-macros-ctu.c
@@ -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;
+}
Index: cfe/trunk/test/Analysis/Inputs/plist-macros-with-expansion-ctu.c.externalDefMap.txt
===
--- cfe/trunk/test/Analysis/Inputs/plist-macros-with-expansion-ctu.c.externalDefMap.txt
+++ cfe/trunk/test/Analysis/Inputs/plist-macros-with-expansion-ctu.c.externalDefMap.txt
@@ -0,0 +1,4 @@
+c:@F@F1 plist-macros-ctu.c.ast
+c:@F@F2 plist-macros-ctu.c.ast
+c:@F@F3 plist-macros-ctu.c.ast
+c:@F@F_H plist-macros-ctu.c.ast
Index: cfe/trunk/test/Analysis/Inputs/plist-macros-ctu.h
===
--- cfe/trunk/test/Analysis/Inputs/plist-macros-ctu.h
+++ cfe/trunk/test/Analysis/Inputs/plist-macros-ctu.h
@@ -0,0 +1,4 @@
+#define M_H *A = (int *)0
+void F_H(int **A) {
+  M_H;
+}
Index: cfe/trunk/lib/StaticAnalyzer/Core/CMakeLists.txt
===
--- cfe/trunk/lib/StaticAnalyzer/Core/CMakeLists.txt
+++ cfe/trunk/lib/StaticAnalyzer/Core/CMakeLists.txt
@@ -53,6 +53,7 @@
   clangAnalysis
   clangBasic
   clangCrossTU
+  clangFrontend
   clangLex
   clangRewrite
   )
Index: cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
===
--- cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
@@ -15,6 +15,7 @@
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/Version.h"
 #include "clang/CrossTU/CrossTranslationUnit.h"
+#include 

[PATCH] D64638: [CrossTU] Fix plist macro expansion if macro in other file.

2019-07-25 Thread Balázs Kéri via Phabricator via cfe-commits
balazske updated this revision to Diff 211689.
balazske added a comment.
Herald added a subscriber: mgorny.

Added clangFrontend to CMakeLists.txt.


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D64638/new/

https://reviews.llvm.org/D64638

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

Index: test/Analysis/plist-macros-with-expansion-ctu.c
===
--- /dev/null
+++ test/Analysis/plist-macros-with-expansion-ctu.c
@@ -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 = 1; // expected-warning{{Dereference of null pointer}}
+}
+// CHECK: nameM1
+// CHECK-NEXT: expansion*Z = (int *)0
+
+
+void test1() {
+  int *X;
+  F1();
+  *X = 1; // expected-warning{{Dereference of null pointer}}
+}
+// CHECK: nameM
+// CHECK-NEXT: expansion*X = (int *)0
+
+void test2() {
+  int *X;
+  F2();
+  *X = 1; // expected-warning{{Dereference of null pointer}}
+}
+// CHECK: nameM
+// CHECK-NEXT: expansion*Y = (int *)0
+
+#define M F1()
+
+void test3() {
+  int *X;
+  M;
+  *X = 1; // expected-warning{{Dereference of null pointer}}
+}
+// CHECK: nameM
+// CHECK-NEXT: expansionF1(X)
+// CHECK: nameM
+// CHECK-NEXT: expansion*X = (int *)0
+
+#undef M
+#define M F2()
+
+void test4() {
+  int *X;
+  M;
+  *X = 1; // expected-warning{{Dereference of null pointer}}
+}
+
+// CHECK: nameM
+// CHECK-NEXT: expansionF2(X)
+// CHECK: nameM
+// CHECK-NEXT: expansion*Y = (int *)0
+
+void test_h() {
+  int *X;
+  F_H();
+  *X = 1; // expected-warning{{Dereference of null pointer}}
+}
+
+// CHECK: nameM_H
+// CHECK-NEXT: expansion*A = (int *)0
Index: test/Analysis/Inputs/plist-macros-with-expansion-ctu.c.externalDefMap.txt
===
--- /dev/null
+++ test/Analysis/Inputs/plist-macros-with-expansion-ctu.c.externalDefMap.txt
@@ -0,0 +1,4 @@
+c:@F@F1 plist-macros-ctu.c.ast
+c:@F@F2 plist-macros-ctu.c.ast
+c:@F@F3 plist-macros-ctu.c.ast
+c:@F@F_H plist-macros-ctu.c.ast
Index: test/Analysis/Inputs/plist-macros-ctu.h
===
--- /dev/null
+++ test/Analysis/Inputs/plist-macros-ctu.h
@@ -0,0 +1,4 @@
+#define M_H *A = (int *)0
+void F_H(int **A) {
+  M_H;
+}
Index: test/Analysis/Inputs/plist-macros-ctu.c
===
--- /dev/null
+++ test/Analysis/Inputs/plist-macros-ctu.c
@@ -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;
+}
Index: lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
===
--- lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
+++ lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
@@ -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 @@
   const FIDMap& FM;
   AnalyzerOptions 
   const Preprocessor 
+  const cross_tu::CrossTranslationUnitContext 
   llvm::SmallVector MacroPieces;
 
 public:
   PlistPrinter(const FIDMap& FM, AnalyzerOptions ,
-   const Preprocessor )
-: FM(FM), AnOpts(AnOpts), PP(PP) {
+   const Preprocessor ,
+   const cross_tu::CrossTranslationUnitContext )
+: FM(FM), AnOpts(AnOpts), PP(PP), CTU(CTU) {
   }
 
   void ReportDiag(raw_ostream , const PathDiagnosticPiece& P) {
@@ -162,8 +165,8 @@
 } // end of anonymous namespace
 
 static void printBugPath(llvm::raw_ostream , const FIDMap& FM,
- AnalyzerOptions ,
- 

[PATCH] D64638: [CrossTU] Fix plist macro expansion if macro in other file.

2019-07-24 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added a comment.

The Frontend is needed because "ASTUnit.h" is added now into 
PlistDiagnostics.cpp. The `ASTUnit` object is used to pass information out from 
`getImportedFromSourceLocation`. The StaticAnalyzerCore library uses CrossTU 
library, and CrossTU uses Frontend, so I think it may be not a problem if 
StaticAnalyzerCore will use directly Frontend. Otherwise the 
`getImportedFromSourceLocation` can return the `Preprocessor` (and 
`ASTContext`) (in a tuple) instead of an `ASTUnit` and use of `ASTUnit` is not 
needed. (Patch in D65064  contains a test that 
does work only if the TranslationUnitDecl of the imported-from AST is known, to 
get this value an `ASTUnit` or `ASTContext` must be returned from 
`getImportedFromSourceLocation`.)


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D64638/new/

https://reviews.llvm.org/D64638



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D64638: [CrossTU] Fix plist macro expansion if macro in other file.

2019-07-23 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ added a comment.

The preprocessor is defined in `Lex`, so i guess i'm curious about a more 
precise description of what's impossible to do without `Frontend`.


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D64638/new/

https://reviews.llvm.org/D64638



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D64638: [CrossTU] Fix plist macro expansion if macro in other file.

2019-07-23 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added a comment.

Maybe CrossTU should not use the Frontend library? (Now the StaticAnalyzerCore 
is using CrossTU and CrossTU is using Frontend, in this way StaticAnalyzerCore 
could use Frontend too.)


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D64638/new/

https://reviews.llvm.org/D64638



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D64638: [CrossTU] Fix plist macro expansion if macro in other file.

2019-07-23 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added a comment.

It is possible to use the `Preprocessor` instead of `ASTUnit` in 
`getImportedFromSourceLocation`. But this will contain less useful (even if 
currently not used) information. The test extension in D65064 
 is not possible to do if not `ASTUnit` is 
used. (Or a tuple must be used that contains `Preprocessor` and 
`TranslationUnitDecl` and maybe other objects that are stored in the `ASTUnit`.)


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D64638/new/

https://reviews.llvm.org/D64638



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D64638: [CrossTU] Fix plist macro expansion if macro in other file.

2019-07-23 Thread Gabor Marton via Phabricator via cfe-commits
martong added a subscriber: NoQ.
martong added a comment.

In D64638#1593382 , @ilya-biryukov 
wrote:

> `StaticAnalyzer/Core` does not depend on `clangFrontend` now, you can see 
> this by looking at `lib/StaticAnalyzer/Core/CMakeLists.txt`:
>
>   add_clang_library(clangStaticAnalyzerCore
>   ...
> LINK_LIBS
> clangAST
> clangASTMatchers
> clangAnalysis
> clangBasic
> clangCrossTU
> clangLex
> clangRewrite
> )
>
>
> Not a `StaticAnalyzer` expert, so I don't know whether it's acceptable to add 
> this dependency to `clangStaticAnalyzerCore`, you'll have to find someone who 
> owns the code to know whether this dependency is justified.
>  (My wild guess from looking at the names of the libraries would be that this 
> dependency is not ok and the code should go into 
> `clangStaticAnalyzerFrontend` instead. But again, not an expert here, just a 
> guess).
>
> But please add a dependency into `LINK_LIBS` inside `CMakeLists.txt` if you 
> start depending on `clangFrontend`.
>  Most of these violations are found if you build in a `cmake 
> -DBUILD_SHARED_LIBS=On` configuration.


@Szelethus @Noq Could StaticAnalyzer/Core depend on clangFrontend? I am not 
sure if we can get the Preprocessor somewhere else ...


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D64638/new/

https://reviews.llvm.org/D64638



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D64638: [CrossTU] Fix plist macro expansion if macro in other file.

2019-07-19 Thread Ilya Biryukov via Phabricator via cfe-commits
ilya-biryukov added a comment.

`StaticAnalyzer/Core` does not depend on `clangFrontend` now, you can see this 
by looking at `lib/StaticAnalyzer/Core/CMakeLists.txt`:

  add_clang_library(clangStaticAnalyzerCore
  ...
LINK_LIBS
clangAST
clangASTMatchers
clangAnalysis
clangBasic
clangCrossTU
clangLex
clangRewrite
)

Not a `StaticAnalyzer` expert, so I don't know whether it's acceptable to add 
this dependency to `clangStaticAnalyzerCore`, you'll have to find someone who 
owns the code to know whether this dependency is justified.
(My wild guess from looking at the names of the libraries would be that this 
dependency is not ok and the code should go into `clangStaticAnalyzerFrontend` 
instead. But again, not an expert here, just a guess).

But please add a dependency into `LINK_LIBS` inside `CMakeLists.txt` if you 
start depending on `clangFrontend`.
Most of these violations are found if you build in a `cmake 
-DBUILD_SHARED_LIBS=On` configuration.


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D64638/new/

https://reviews.llvm.org/D64638



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D64638: [CrossTU] Fix plist macro expansion if macro in other file.

2019-07-19 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added a reviewer: ilya-biryukov.
balazske added a subscriber: ilya-biryukov.
balazske added a comment.

@ilya-biryukov Please check if it is acceptable to use `ASTUnit` in 
PlistDiagnostic.cpp.


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D64638/new/

https://reviews.llvm.org/D64638



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D64638: [CrossTU] Fix plist macro expansion if macro in other file.

2019-07-12 Thread Kristóf Umann via Phabricator via cfe-commits
Szelethus accepted this revision.
Szelethus added a comment.
This revision is now accepted and ready to land.

LGTM! Thanks!


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D64638/new/

https://reviews.llvm.org/D64638



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D64638: [CrossTU] Fix plist macro expansion if macro in other file.

2019-07-12 Thread Balázs Kéri via Phabricator via cfe-commits
balazske created this revision.
Herald added subscribers: cfe-commits, gamesh411, Szelethus, dkrupp.
Herald added a project: clang.

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.


Repository:
  rC Clang

https://reviews.llvm.org/D64638

Files:
  lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
  test/Analysis/Inputs/plist-macros-ctu.c
  test/Analysis/Inputs/plist-macros-ctu.h
  test/Analysis/Inputs/plist-macros-with-expansion-ctu.c.externalDefMap.txt
  test/Analysis/plist-macros-with-expansion-ctu.c

Index: test/Analysis/plist-macros-with-expansion-ctu.c
===
--- /dev/null
+++ test/Analysis/plist-macros-with-expansion-ctu.c
@@ -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 = 1; // expected-warning{{Dereference of null pointer}}
+}
+// CHECK: nameM1
+// CHECK-NEXT: expansion*Z = (int *)0
+
+
+void test1() {
+  int *X;
+  F1();
+  *X = 1; // expected-warning{{Dereference of null pointer}}
+}
+// CHECK: nameM
+// CHECK-NEXT: expansion*X = (int *)0
+
+void test2() {
+  int *X;
+  F2();
+  *X = 1; // expected-warning{{Dereference of null pointer}}
+}
+// CHECK: nameM
+// CHECK-NEXT: expansion*Y = (int *)0
+
+#define M F1()
+
+void test3() {
+  int *X;
+  M;
+  *X = 1; // expected-warning{{Dereference of null pointer}}
+}
+// CHECK: nameM
+// CHECK-NEXT: expansionF1(X)
+// CHECK: nameM
+// CHECK-NEXT: expansion*X = (int *)0
+
+#undef M
+#define M F2()
+
+void test4() {
+  int *X;
+  M;
+  *X = 1; // expected-warning{{Dereference of null pointer}}
+}
+
+// CHECK: nameM
+// CHECK-NEXT: expansionF2(X)
+// CHECK: nameM
+// CHECK-NEXT: expansion*Y = (int *)0
+
+void test_h() {
+  int *X;
+  F_H();
+  *X = 1; // expected-warning{{Dereference of null pointer}}
+}
+
+// CHECK: nameM_H
+// CHECK-NEXT: expansion*A = (int *)0
Index: test/Analysis/Inputs/plist-macros-with-expansion-ctu.c.externalDefMap.txt
===
--- /dev/null
+++ test/Analysis/Inputs/plist-macros-with-expansion-ctu.c.externalDefMap.txt
@@ -0,0 +1,4 @@
+c:@F@F1 plist-macros-ctu.c.ast
+c:@F@F2 plist-macros-ctu.c.ast
+c:@F@F3 plist-macros-ctu.c.ast
+c:@F@F_H plist-macros-ctu.c.ast
Index: test/Analysis/Inputs/plist-macros-ctu.h
===
--- /dev/null
+++ test/Analysis/Inputs/plist-macros-ctu.h
@@ -0,0 +1,4 @@
+#define M_H *A = (int *)0
+void F_H(int **A) {
+  M_H;
+}
Index: test/Analysis/Inputs/plist-macros-ctu.c
===
--- /dev/null
+++ test/Analysis/Inputs/plist-macros-ctu.c
@@ -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;
+}
Index: lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
===
--- lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
+++ lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
@@ -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 @@
   const FIDMap& FM;
   AnalyzerOptions 
   const Preprocessor 
+  const cross_tu::CrossTranslationUnitContext 
   llvm::SmallVector MacroPieces;
 
 public:
   PlistPrinter(const FIDMap& FM, AnalyzerOptions ,
-   const Preprocessor )
-: FM(FM), AnOpts(AnOpts), PP(PP) {
+   const Preprocessor ,
+   const cross_tu::CrossTranslationUnitContext )
+: FM(FM), AnOpts(AnOpts), PP(PP), CTU(CTU) {
   }
 
   void ReportDiag(raw_ostream , const PathDiagnosticPiece& P) {
@@ -162,8 +165,8 @@
 }