summaryrefslogtreecommitdiff
path: root/test/PCH
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2011-05-02 19:39:53 +0000
committerDimitry Andric <dim@FreeBSD.org>2011-05-02 19:39:53 +0000
commit01af97d3b23bded2b2b21af19bbc6e4cce49e5b3 (patch)
tree64a10f4c4154739d4a8191d7e1b52ce497f4ebd6 /test/PCH
parentc3b054d250cdca485c71845089c316e10610ebad (diff)
Notes
Diffstat (limited to 'test/PCH')
-rw-r--r--test/PCH/Inputs/working-directory-1.h5
-rw-r--r--test/PCH/chain-cxx.cpp35
-rw-r--r--test/PCH/chain-empty-initial-namespace.cpp24
-rw-r--r--test/PCH/chain-implicit-definition.cpp39
-rw-r--r--test/PCH/chain-late-anonymous-namespace.cpp61
-rw-r--r--test/PCH/chain-pending-instantiations.cpp33
-rw-r--r--test/PCH/cxx-chain-function-template.cpp32
-rw-r--r--test/PCH/cxx-for-range.cpp19
-rw-r--r--test/PCH/cxx-for-range.h35
-rw-r--r--test/PCH/cxx-reference.cpp6
-rw-r--r--test/PCH/cxx-reference.h13
-rw-r--r--test/PCH/cxx-templates.cpp29
-rw-r--r--test/PCH/cxx-templates.h12
-rw-r--r--test/PCH/cxx_exprs.cpp6
-rw-r--r--test/PCH/exprs.c5
-rw-r--r--test/PCH/exprs.h6
-rw-r--r--test/PCH/headersearch.cpp6
-rw-r--r--test/PCH/modified-header-crash.c10
-rw-r--r--test/PCH/modified-header-crash.h1
-rw-r--r--test/PCH/objcxx-ivar-class.h1
-rw-r--r--test/PCH/pragma-diag-section.cpp5
-rw-r--r--test/PCH/pragma-diag.c3
-rw-r--r--test/PCH/rdar8852495.c3
-rw-r--r--test/PCH/reloc.c2
-rw-r--r--test/PCH/source-manager-stack.c4
-rw-r--r--test/PCH/working-directory.cpp12
-rw-r--r--test/PCH/working-directory.h1
27 files changed, 386 insertions, 22 deletions
diff --git a/test/PCH/Inputs/working-directory-1.h b/test/PCH/Inputs/working-directory-1.h
new file mode 100644
index 0000000000000..e42eda45c87fa
--- /dev/null
+++ b/test/PCH/Inputs/working-directory-1.h
@@ -0,0 +1,5 @@
+template<typename T> struct A {
+ A() {
+ int a;
+ }
+};
diff --git a/test/PCH/chain-cxx.cpp b/test/PCH/chain-cxx.cpp
index d269de529fba3..af0a23afea9f1 100644
--- a/test/PCH/chain-cxx.cpp
+++ b/test/PCH/chain-cxx.cpp
@@ -4,9 +4,7 @@
// RUN: %clang_cc1 -fsyntax-only -verify -include %s -include %s %s
// With PCH
-// RUN: %clang_cc1 -x c++-header -emit-pch -o %t1 %s
-// RUN: %clang_cc1 -x c++-header -emit-pch -o %t2 %s -include-pch %t1 -chained-pch
-// RUN: %clang_cc1 -fsyntax-only -verify -include-pch %t2 %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s -chain-include %s -chain-include %s
#ifndef HEADER1
#define HEADER1
@@ -34,9 +32,26 @@ struct S<T *> { typedef int H; };
template <typename T> struct TS2;
typedef TS2<int> TS2int;
+template <typename T> struct TestBaseSpecifiers { };
+template<typename T> struct TestBaseSpecifiers2 : TestBaseSpecifiers<T> { };
+
+template <typename T>
+struct TS3 {
+ static const int value = 0;
+};
+template <typename T>
+const int TS3<T>::value;
+// Instantiate struct, but not value.
+struct instantiate : TS3<int> {};
+
+
//===----------------------------------------------------------------------===//
#elif not defined(HEADER2)
#define HEADER2
+#if !defined(HEADER1)
+#error Header inclusion order messed up
+#endif
+
//===----------------------------------------------------------------------===//
// Dependent header for C++ chained PCH test
@@ -73,6 +88,15 @@ struct S<int &> { typedef int L; };
template <typename T> struct TS2 { };
+struct TestBaseSpecifiers3 { };
+struct TestBaseSpecifiers4 : TestBaseSpecifiers3 { };
+
+struct A { };
+struct B : A { };
+
+// Instantiate TS3's member.
+static const int ts3m1 = TS3<int>::value;
+
//===----------------------------------------------------------------------===//
#else
//===----------------------------------------------------------------------===//
@@ -96,7 +120,12 @@ void test() {
typedef S<int &>::L T6;
TS2int ts2;
+
+ B b;
}
+// Should have remembered that there is a definition.
+static const int ts3m2 = TS3<int>::value;
+
//===----------------------------------------------------------------------===//
#endif
diff --git a/test/PCH/chain-empty-initial-namespace.cpp b/test/PCH/chain-empty-initial-namespace.cpp
new file mode 100644
index 0000000000000..bf15caa72cda1
--- /dev/null
+++ b/test/PCH/chain-empty-initial-namespace.cpp
@@ -0,0 +1,24 @@
+// no PCH
+// RUN: %clang_cc1 -include %s -include %s -fsyntax-only %s
+// full PCH
+// RUN: %clang_cc1 -chain-include %s -chain-include %s -fsyntax-only %s
+#if !defined(PASS1)
+#define PASS1
+
+namespace foo {} // no external storage
+
+#elif !defined(PASS2)
+#define PASS2
+
+namespace foo {
+ void bar();
+}
+
+#else
+// PASS3
+
+void test() {
+ foo::bar(); // no-error
+}
+
+#endif
diff --git a/test/PCH/chain-implicit-definition.cpp b/test/PCH/chain-implicit-definition.cpp
new file mode 100644
index 0000000000000..245e8f9e10f82
--- /dev/null
+++ b/test/PCH/chain-implicit-definition.cpp
@@ -0,0 +1,39 @@
+// no PCH
+// RUN: %clang_cc1 -emit-llvm-only -include %s -include %s %s
+// with PCH
+// RUN: %clang_cc1 -emit-llvm-only -chain-include %s -chain-include %s %s
+#if !defined(PASS1)
+#define PASS1
+
+// A base with a virtual dtor.
+struct A {
+ virtual ~A();
+};
+
+// A derived class with an implicit virtual dtor.
+struct B : A {
+ // Key function to suppress vtable definition.
+ virtual void virt();
+};
+
+#elif !defined(PASS2)
+#define PASS2
+
+// Further derived class that requires ~B().
+// Causes definition of ~B(), but it was lost when saving PCH.
+struct C : B {
+ C();
+ ~C() {}
+};
+
+#else
+
+void foo() {
+ // Variable that requires ~C().
+ C c;
+}
+
+// VTable placement would again cause definition of ~B(), hiding the bug,
+// if not for B::virt(), which suppresses the placement.
+
+#endif
diff --git a/test/PCH/chain-late-anonymous-namespace.cpp b/test/PCH/chain-late-anonymous-namespace.cpp
new file mode 100644
index 0000000000000..87205c631b3a8
--- /dev/null
+++ b/test/PCH/chain-late-anonymous-namespace.cpp
@@ -0,0 +1,61 @@
+// no PCH
+// RUN: %clang_cc1 -include %s -include %s -fsyntax-only %s
+// with PCH
+// RUN: %clang_cc1 -chain-include %s -chain-include %s -fsyntax-only %s
+#if !defined(PASS1)
+#define PASS1
+
+namespace ns {}
+namespace os {}
+
+#elif !defined(PASS2)
+#define PASS2
+
+namespace ns {
+ namespace {
+ extern int x;
+ }
+}
+
+namespace {
+ extern int y;
+}
+namespace {
+}
+
+namespace os {
+ extern "C" {
+ namespace {
+ extern int z;
+ }
+ }
+}
+
+#else
+
+namespace ns {
+ namespace {
+ int x;
+ }
+ void test() {
+ (void)x;
+ }
+}
+
+namespace {
+ int y;
+}
+void test() {
+ (void)y;
+}
+
+namespace os {
+ namespace {
+ int z;
+ }
+ void test() {
+ (void)z;
+ }
+}
+
+#endif
diff --git a/test/PCH/chain-pending-instantiations.cpp b/test/PCH/chain-pending-instantiations.cpp
new file mode 100644
index 0000000000000..e49abcda4484d
--- /dev/null
+++ b/test/PCH/chain-pending-instantiations.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -chain-include %s -chain-include %s | FileCheck %s
+// CHECK: define linkonce_odr %{{[^ ]+}} @_ZN1AI1BE3getEv
+#if !defined(PASS1)
+#define PASS1
+
+template <typename Derived>
+struct A {
+ Derived* get() { return 0; }
+};
+
+struct B : A<B> {
+};
+
+#elif !defined(PASS2)
+#define PASS2
+
+struct C : B {
+};
+
+struct D : C {
+ void run() {
+ (void)get();
+ }
+};
+
+#else
+
+int main() {
+ D d;
+ d.run();
+}
+
+#endif
diff --git a/test/PCH/cxx-chain-function-template.cpp b/test/PCH/cxx-chain-function-template.cpp
new file mode 100644
index 0000000000000..494e190f776b3
--- /dev/null
+++ b/test/PCH/cxx-chain-function-template.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -chain-include %s -chain-include %s -fsyntax-only %s
+// Just don't crash.
+#if !defined(RUN1)
+#define RUN1
+
+struct CXXRecordDecl { CXXRecordDecl(int); };
+
+template <typename T, typename U>
+T cast(U u) {
+ return reinterpret_cast<T&>(u);
+}
+
+void test1() {
+ cast<float>(1);
+}
+
+#elif !defined(RUN2)
+#define RUN2
+
+template <typename T>
+void test2(T) {
+ cast<CXXRecordDecl>(1.0f);
+}
+
+#else
+
+void test3() {
+ cast<CXXRecordDecl>(1.0f);
+ test2(1);
+}
+
+#endif
diff --git a/test/PCH/cxx-for-range.cpp b/test/PCH/cxx-for-range.cpp
new file mode 100644
index 0000000000000..5854917da5c7d
--- /dev/null
+++ b/test/PCH/cxx-for-range.cpp
@@ -0,0 +1,19 @@
+// Test this without pch.
+// RUN: %clang_cc1 -std=c++0x -include %S/cxx-for-range.h -fsyntax-only -emit-llvm -o - %s
+
+// Test with pch.
+// RUN: %clang_cc1 -std=c++0x -emit-pch -o %t %S/cxx-for-range.h
+// RUN: %clang_cc1 -std=c++0x -include-pch %t -fsyntax-only -emit-llvm -o - %s
+
+void h() {
+ f();
+
+ g<int>();
+
+ char a[3] = { 0, 1, 2 };
+ for (auto w : a)
+ for (auto x : S())
+ for (auto y : T())
+ for (auto z : U())
+ ;
+}
diff --git a/test/PCH/cxx-for-range.h b/test/PCH/cxx-for-range.h
new file mode 100644
index 0000000000000..f15c7e73df398
--- /dev/null
+++ b/test/PCH/cxx-for-range.h
@@ -0,0 +1,35 @@
+// Header for PCH test cxx-for-range.cpp
+
+struct S {
+ int *begin();
+ int *end();
+};
+
+struct T { };
+char *begin(T);
+char *end(T);
+
+struct U { };
+namespace std {
+ char *begin(U);
+ char *end(U);
+}
+
+void f() {
+ char a[3] = { 0, 1, 2 };
+ for (auto w : a)
+ for (auto x : S())
+ for (auto y : T())
+ for (auto z : U())
+ ;
+}
+
+template<typename A>
+void g() {
+ A a[3] = { 0, 1, 2 };
+ for (auto &v : a)
+ for (auto x : S())
+ for (auto y : T())
+ for (auto z : U())
+ ;
+}
diff --git a/test/PCH/cxx-reference.cpp b/test/PCH/cxx-reference.cpp
new file mode 100644
index 0000000000000..90d00d777c44f
--- /dev/null
+++ b/test/PCH/cxx-reference.cpp
@@ -0,0 +1,6 @@
+// Test this without pch.
+// RUN: %clang_cc1 -std=c++0x -include %S/cxx-reference.h -fsyntax-only -emit-llvm -o - %s
+
+// Test with pch.
+// RUN: %clang_cc1 -std=c++0x -emit-pch -o %t %S/cxx-reference.h
+// RUN: %clang_cc1 -std=c++0x -include-pch %t -fsyntax-only -emit-llvm -o - %s
diff --git a/test/PCH/cxx-reference.h b/test/PCH/cxx-reference.h
new file mode 100644
index 0000000000000..b46a3671a325f
--- /dev/null
+++ b/test/PCH/cxx-reference.h
@@ -0,0 +1,13 @@
+// Header for PCH test cxx-reference.cpp
+
+typedef char (&LR);
+typedef char (&&RR);
+
+char c;
+
+char &lr = c;
+char &&rr = 'c';
+LR &lrlr = c;
+LR &&rrlr = c;
+RR &lrrr = c;
+RR &&rrrr = 'c';
diff --git a/test/PCH/cxx-templates.cpp b/test/PCH/cxx-templates.cpp
index 05dd6ed0d2bed..982fc67e4e8a0 100644
--- a/test/PCH/cxx-templates.cpp
+++ b/test/PCH/cxx-templates.cpp
@@ -1,11 +1,11 @@
// Test this without pch.
-// RUN: %clang_cc1 -fexceptions -include %S/cxx-templates.h -verify %s -ast-dump -o -
-// RUN: %clang_cc1 -fexceptions -include %S/cxx-templates.h %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -include %S/cxx-templates.h -verify %s -ast-dump -o -
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -include %S/cxx-templates.h %s -emit-llvm -o - | FileCheck %s
// Test with pch.
-// RUN: %clang_cc1 -fexceptions -x c++-header -emit-pch -o %t %S/cxx-templates.h
-// RUN: %clang_cc1 -fexceptions -include-pch %t -verify %s -ast-dump -o -
-// RUN: %clang_cc1 -fexceptions -include-pch %t %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -x c++-header -emit-pch -o %t %S/cxx-templates.h
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -include-pch %t -verify %s -ast-dump -o -
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -include-pch %t %s -emit-llvm -o - | FileCheck %s
// CHECK: define weak_odr void @_ZN2S4IiE1mEv
// CHECK: define linkonce_odr void @_ZN2S3IiE1mEv
@@ -43,3 +43,22 @@ S7<int[5]> s7_5;
namespace ZeroLengthExplicitTemplateArgs {
template void f<X>(X*);
}
+
+// This used to overwrite memory and crash.
+namespace Test1 {
+ struct StringHasher {
+ template<typename T, char Converter(T)> static inline unsigned createHash(const T*, unsigned) {
+ return 0;
+ }
+ };
+
+ struct CaseFoldingHash {
+ static inline char foldCase(char) {
+ return 0;
+ }
+
+ static unsigned hash(const char* data, unsigned length) {
+ return StringHasher::createHash<char, foldCase>(data, length);
+ }
+ };
+}
diff --git a/test/PCH/cxx-templates.h b/test/PCH/cxx-templates.h
index d2c820f877c60..c45e02dcb23c1 100644
--- a/test/PCH/cxx-templates.h
+++ b/test/PCH/cxx-templates.h
@@ -193,3 +193,15 @@ namespace ZeroLengthExplicitTemplateArgs {
template<typename T> void g2(T);
};
}
+
+namespace NonTypeTemplateParmContext {
+ template<typename T, int inlineCapacity = 0> class Vector { };
+
+ struct String {
+ template<int inlineCapacity>
+ static String adopt(Vector<char, inlineCapacity>&);
+ };
+
+ template<int inlineCapacity>
+ inline bool equalIgnoringNullity(const Vector<char, inlineCapacity>& a, const String& b) { return false; }
+}
diff --git a/test/PCH/cxx_exprs.cpp b/test/PCH/cxx_exprs.cpp
index cf7ae338eba12..49df80db4fedb 100644
--- a/test/PCH/cxx_exprs.cpp
+++ b/test/PCH/cxx_exprs.cpp
@@ -1,9 +1,9 @@
// Test this without pch.
-// RUN: %clang_cc1 -fexceptions -include %S/cxx_exprs.h -std=c++0x -fsyntax-only -verify %s -ast-dump
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -include %S/cxx_exprs.h -std=c++0x -fsyntax-only -verify %s -ast-dump
// Test with pch. Use '-ast-dump' to force deserialization of function bodies.
-// RUN: %clang_cc1 -fexceptions -x c++-header -std=c++0x -emit-pch -o %t %S/cxx_exprs.h
-// RUN: %clang_cc1 -fexceptions -std=c++0x -include-pch %t -fsyntax-only -verify %s -ast-dump
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -x c++-header -std=c++0x -emit-pch -o %t %S/cxx_exprs.h
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -std=c++0x -include-pch %t -fsyntax-only -verify %s -ast-dump
int integer;
double floating;
diff --git a/test/PCH/exprs.c b/test/PCH/exprs.c
index d855defe7eed0..5928abda58f35 100644
--- a/test/PCH/exprs.c
+++ b/test/PCH/exprs.c
@@ -39,7 +39,7 @@ negate_enum *int_ptr4 = &integer;
// OffsetOfExpr
offsetof_type *offsetof_ptr = &size_type_value;
-// SizeOfAlignOfExpr
+// UnaryExprOrTypeTraitExpr
typeof(sizeof(float)) size_t_value;
typeof_sizeof *size_t_ptr = &size_t_value;
typeof_sizeof2 *size_t_ptr2 = &size_t_value;
@@ -93,3 +93,6 @@ choose_expr *int_ptr8 = &integer;
// ShuffleVectorExpr
shuffle_expr *vec_ptr = &vec2;
+
+// GenericSelectionExpr
+generic_selection_expr *double_ptr6 = &floating;
diff --git a/test/PCH/exprs.h b/test/PCH/exprs.h
index 80768f8df24e7..3495b8b4bbde1 100644
--- a/test/PCH/exprs.h
+++ b/test/PCH/exprs.h
@@ -38,7 +38,7 @@ struct Z {
typedef typeof(__builtin_offsetof(struct Z, y.array[1 + 2].member))
offsetof_type;
-// SizeOfAlignOfExpr
+// UnaryExprOrTypeTraitExpr
typedef typeof(sizeof(int)) typeof_sizeof;
typedef typeof(sizeof(Enumerator)) typeof_sizeof2;
@@ -99,3 +99,7 @@ typedef typeof(__builtin_choose_expr(17 > 19, d0, 1)) choose_expr;
// ShuffleVectorExpr
typedef typeof(__builtin_shufflevector(vec2, vec2b, 2, 1)) shuffle_expr;
+
+// GenericSelectionExpr
+typedef typeof(_Generic(i, char*: 0, int: 0., default: hello))
+ generic_selection_expr;
diff --git a/test/PCH/headersearch.cpp b/test/PCH/headersearch.cpp
index 151756c7071e6..8ca0c361c4dc6 100644
--- a/test/PCH/headersearch.cpp
+++ b/test/PCH/headersearch.cpp
@@ -1,8 +1,9 @@
// Test reading of PCH with changed location of original input files,
// i.e. invoking header search.
-// XFAIL: win32
+// REQUIRES: shell
// Generate the original files:
+// RUN: rm -rf %t_orig %t_moved
// RUN: mkdir -p %t_orig/sub %t_orig/sub2
// RUN: echo 'struct orig_sub{char c; int i; };' > %t_orig/sub/orig_sub.h
// RUN: echo 'void orig_sub2_1();' > %t_orig/sub2/orig_sub2_1.h
@@ -16,8 +17,7 @@
// Generate the PCH:
// RUN: cd %t_orig && %clang_cc1 -x c++ -emit-pch -o all.h.pch -Isub2 all.h
-// RUN: rm -rf %t_moved
-// RUN: mv %t_orig %t_moved
+// RUN: cp -pR %t_orig %t_moved
// Check diagnostic with location in original source:
// RUN: %clang_cc1 -include-pch all.h.pch -I%t_moved -I%t_moved/sub2 -Wpadded -emit-obj -o %t.o %s 2> %t.stderr
diff --git a/test/PCH/modified-header-crash.c b/test/PCH/modified-header-crash.c
new file mode 100644
index 0000000000000..c74ce2239c22d
--- /dev/null
+++ b/test/PCH/modified-header-crash.c
@@ -0,0 +1,10 @@
+// Don't crash.
+
+// RUN: cp %S/modified-header-crash.h %t.h
+// RUN: %clang_cc1 -DCAKE -x c-header %t.h -emit-pch -o %t
+// RUN: echo >> %t.h
+// RUN: not %clang_cc1 %s -include-pch %t -fsyntax-only
+
+void f(void) {
+ foo = 3;
+}
diff --git a/test/PCH/modified-header-crash.h b/test/PCH/modified-header-crash.h
new file mode 100644
index 0000000000000..971746e3bd4cd
--- /dev/null
+++ b/test/PCH/modified-header-crash.h
@@ -0,0 +1 @@
+int foo;
diff --git a/test/PCH/objcxx-ivar-class.h b/test/PCH/objcxx-ivar-class.h
index 50ebda709db0e..5e5565864d879 100644
--- a/test/PCH/objcxx-ivar-class.h
+++ b/test/PCH/objcxx-ivar-class.h
@@ -1,6 +1,7 @@
struct S {
S();
S(const S&);
+ ~S();
S& operator= (const S&);
};
diff --git a/test/PCH/pragma-diag-section.cpp b/test/PCH/pragma-diag-section.cpp
index 312f720ebd987..5b996bb2f0d16 100644
--- a/test/PCH/pragma-diag-section.cpp
+++ b/test/PCH/pragma-diag-section.cpp
@@ -12,7 +12,10 @@
#pragma clang diagnostic ignored "-Wtautological-compare"
template <typename T>
struct TS {
- void m() { T b = b==b; }
+ void m() {
+ T a = 0;
+ T b = a==a;
+ }
};
#pragma clang diagnostic pop
diff --git a/test/PCH/pragma-diag.c b/test/PCH/pragma-diag.c
index c5171036400f3..b304c4bf8c35f 100644
--- a/test/PCH/pragma-diag.c
+++ b/test/PCH/pragma-diag.c
@@ -13,7 +13,8 @@
#else
void f() {
- int b = b==b;
+ int a = 0;
+ int b = a==a;
}
#endif
diff --git a/test/PCH/rdar8852495.c b/test/PCH/rdar8852495.c
index 2d49e001b0515..fb465a37ce38d 100644
--- a/test/PCH/rdar8852495.c
+++ b/test/PCH/rdar8852495.c
@@ -16,7 +16,8 @@
#else
int f() {
- int b = b==b;
+ int a;
+ int b = a==a;
unsigned x;
signed y;
return x == y;
diff --git a/test/PCH/reloc.c b/test/PCH/reloc.c
index 51a7c4c879462..fd78feba60478 100644
--- a/test/PCH/reloc.c
+++ b/test/PCH/reloc.c
@@ -1,7 +1,7 @@
// RUN: %clang_cc1 -emit-pch -o %t -relocatable-pch -isysroot %S/libroot %S/libroot/usr/include/reloc.h
// RUN: %clang_cc1 -include-pch %t -isysroot %S/libroot %s -verify
// RUN: not %clang_cc1 -include-pch %t %s
-// XFAIL: win32
+
#include <reloc.h>
int x = 2; // expected-error{{redefinition}}
diff --git a/test/PCH/source-manager-stack.c b/test/PCH/source-manager-stack.c
index cc8555661a4d4..8f5da2f0e371c 100644
--- a/test/PCH/source-manager-stack.c
+++ b/test/PCH/source-manager-stack.c
@@ -2,9 +2,9 @@
// when using PCH.
// RUN: echo 'int x;' > %t.prefix.h
-// RUN: not %clang_cc1 -fsyntax-only -include %t.prefix.h %s 2> %t.diags.no_pch.txt
+// RUN: not %clang_cc1 -fsyntax-only -fdiagnostics-show-note-include-stack -include %t.prefix.h %s 2> %t.diags.no_pch.txt
// RUN: %clang_cc1 -emit-pch -o %t.prefix.pch %t.prefix.h
-// RUN: not %clang_cc1 -fsyntax-only -include-pch %t.prefix.pch %s 2> %t.diags.pch.txt
+// RUN: not %clang_cc1 -fsyntax-only -fdiagnostics-show-note-include-stack -include-pch %t.prefix.pch %s 2> %t.diags.pch.txt
// RUN: diff %t.diags.no_pch.txt %t.diags.pch.txt
// XFAIL: *
// PR5662
diff --git a/test/PCH/working-directory.cpp b/test/PCH/working-directory.cpp
new file mode 100644
index 0000000000000..e77d31b4be617
--- /dev/null
+++ b/test/PCH/working-directory.cpp
@@ -0,0 +1,12 @@
+// Test this without pch.
+// RUN: %clang_cc1 -working-directory %S -I. -include working-directory.h %s -Wunused
+
+// Test with pch.
+// RUN: %clang_cc1 -working-directory %S -x c++-header -emit-pch -o %t.pch -I. working-directory.h
+// RUN: %clang_cc1 -include-pch %t.pch -fsyntax-only %s -Wunused
+
+void f() {
+ // Instantiating A<char> will trigger a warning, which will end up trying to get the path to
+ // the header that contains A.
+ A<char> b;
+}
diff --git a/test/PCH/working-directory.h b/test/PCH/working-directory.h
new file mode 100644
index 0000000000000..02a60e3e763ef
--- /dev/null
+++ b/test/PCH/working-directory.h
@@ -0,0 +1 @@
+#include <Inputs/working-directory-1.h>