diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-04-16 16:02:28 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-04-16 16:02:28 +0000 |
commit | 7442d6faa2719e4e7d33a7021c406c5a4facd74d (patch) | |
tree | c72b9241553fc9966179aba84f90f17bfa9235c3 /test/Modules | |
parent | b52119637f743680a99710ce5fdb6646da2772af (diff) |
Notes
Diffstat (limited to 'test/Modules')
108 files changed, 1776 insertions, 46 deletions
diff --git a/test/Modules/ExtDebugInfo.cpp b/test/Modules/ExtDebugInfo.cpp index c39bce950664e..3bd58a3da5510 100644 --- a/test/Modules/ExtDebugInfo.cpp +++ b/test/Modules/ExtDebugInfo.cpp @@ -16,7 +16,7 @@ // RUN: %clang_cc1 -std=c++11 -debug-info-kind=standalone \ // RUN: -dwarf-ext-refs -fmodule-format=obj \ // RUN: -triple %itanium_abi_triple \ -// RUN: -include-pch %t.pch %s -emit-llvm -o %t-pch.ll %s +// RUN: -include-pch %t.pch %s -emit-llvm -o %t-pch.ll // RUN: cat %t-pch.ll | FileCheck %s // RUN: cat %t-pch.ll | FileCheck %s --check-prefix=CHECK-PCH diff --git a/test/Modules/Inputs/Main.framework/Frameworks/Sub.framework/Headers/B.h b/test/Modules/Inputs/Main.framework/Frameworks/Sub.framework/Headers/B.h new file mode 100644 index 0000000000000..761540b09cb33 --- /dev/null +++ b/test/Modules/Inputs/Main.framework/Frameworks/Sub.framework/Headers/B.h @@ -0,0 +1 @@ +// B.h diff --git a/test/Modules/Inputs/Main.framework/Frameworks/Sub.framework/Headers/Sub.h b/test/Modules/Inputs/Main.framework/Frameworks/Sub.framework/Headers/Sub.h new file mode 100644 index 0000000000000..fd86e3cf872fb --- /dev/null +++ b/test/Modules/Inputs/Main.framework/Frameworks/Sub.framework/Headers/Sub.h @@ -0,0 +1,2 @@ +// Sub.h +#import "B.h" diff --git a/test/Modules/Inputs/Main.framework/Frameworks/Sub.framework/PrivateHeaders/BPriv.h b/test/Modules/Inputs/Main.framework/Frameworks/Sub.framework/PrivateHeaders/BPriv.h new file mode 100644 index 0000000000000..4ab49b798c631 --- /dev/null +++ b/test/Modules/Inputs/Main.framework/Frameworks/Sub.framework/PrivateHeaders/BPriv.h @@ -0,0 +1 @@ +// BPriv.h diff --git a/test/Modules/Inputs/Main.framework/Frameworks/Sub.framework/PrivateHeaders/SubPriv.h b/test/Modules/Inputs/Main.framework/Frameworks/Sub.framework/PrivateHeaders/SubPriv.h new file mode 100644 index 0000000000000..f6ac6188d65ff --- /dev/null +++ b/test/Modules/Inputs/Main.framework/Frameworks/Sub.framework/PrivateHeaders/SubPriv.h @@ -0,0 +1 @@ +#import "BPriv.h" diff --git a/test/Modules/Inputs/Main.framework/Headers/A.h b/test/Modules/Inputs/Main.framework/Headers/A.h new file mode 100644 index 0000000000000..975f1f0437bb1 --- /dev/null +++ b/test/Modules/Inputs/Main.framework/Headers/A.h @@ -0,0 +1 @@ +// A.h diff --git a/test/Modules/Inputs/Main.framework/Headers/Main.h b/test/Modules/Inputs/Main.framework/Headers/Main.h new file mode 100644 index 0000000000000..cb8cc00a0c45e --- /dev/null +++ b/test/Modules/Inputs/Main.framework/Headers/Main.h @@ -0,0 +1,2 @@ +// Main.h +#import "A.h" diff --git a/test/Modules/Inputs/Main.framework/Modules/module.modulemap b/test/Modules/Inputs/Main.framework/Modules/module.modulemap new file mode 100644 index 0000000000000..9fab5d350fea0 --- /dev/null +++ b/test/Modules/Inputs/Main.framework/Modules/module.modulemap @@ -0,0 +1,12 @@ +framework module Main { + umbrella header "Main.h" + + module * { export * } + export * + + framework module Sub { + umbrella header "Sub.h" + module * { export * } + export * + } +} diff --git a/test/Modules/Inputs/Main.framework/Modules/module.private.modulemap b/test/Modules/Inputs/Main.framework/Modules/module.private.modulemap new file mode 100644 index 0000000000000..54e8be79bfa58 --- /dev/null +++ b/test/Modules/Inputs/Main.framework/Modules/module.private.modulemap @@ -0,0 +1,11 @@ +module Main.Private { + umbrella header "MainPriv.h" + module * { export * } + export * +} + +module Main.Sub.Private { + umbrella header "SubPriv.h" + module * { export * } + export * +} diff --git a/test/Modules/Inputs/Main.framework/PrivateHeaders/APriv.h b/test/Modules/Inputs/Main.framework/PrivateHeaders/APriv.h new file mode 100644 index 0000000000000..6ac683c39c55c --- /dev/null +++ b/test/Modules/Inputs/Main.framework/PrivateHeaders/APriv.h @@ -0,0 +1 @@ +// APriv.h diff --git a/test/Modules/Inputs/Main.framework/PrivateHeaders/MainPriv.h b/test/Modules/Inputs/Main.framework/PrivateHeaders/MainPriv.h new file mode 100644 index 0000000000000..68103017ad0b1 --- /dev/null +++ b/test/Modules/Inputs/Main.framework/PrivateHeaders/MainPriv.h @@ -0,0 +1 @@ +#import "APriv.h" diff --git a/test/Modules/Inputs/anon-redecl/a.h b/test/Modules/Inputs/anon-redecl/a.h new file mode 100644 index 0000000000000..1b23e724160af --- /dev/null +++ b/test/Modules/Inputs/anon-redecl/a.h @@ -0,0 +1,2 @@ +struct X { union { int n; }; }; +inline int a(X x) { return x.n; } diff --git a/test/Modules/Inputs/anon-redecl/b.h b/test/Modules/Inputs/anon-redecl/b.h new file mode 100644 index 0000000000000..23ea804a2459c --- /dev/null +++ b/test/Modules/Inputs/anon-redecl/b.h @@ -0,0 +1,2 @@ +struct X { union { int n; }; }; +inline int b(X x) { return x.n; } diff --git a/test/Modules/Inputs/anon-redecl/c1.h b/test/Modules/Inputs/anon-redecl/c1.h new file mode 100644 index 0000000000000..600af314ec35e --- /dev/null +++ b/test/Modules/Inputs/anon-redecl/c1.h @@ -0,0 +1,2 @@ +#include "a.h" +#include "b.h" diff --git a/test/Modules/Inputs/anon-redecl/c2.h b/test/Modules/Inputs/anon-redecl/c2.h new file mode 100644 index 0000000000000..2e99b27194c8b --- /dev/null +++ b/test/Modules/Inputs/anon-redecl/c2.h @@ -0,0 +1,2 @@ +struct X { union { int n; }; }; +inline int c(X x) { return x.n; } diff --git a/test/Modules/Inputs/anon-redecl/module.modulemap b/test/Modules/Inputs/anon-redecl/module.modulemap new file mode 100644 index 0000000000000..49678452e0c4e --- /dev/null +++ b/test/Modules/Inputs/anon-redecl/module.modulemap @@ -0,0 +1,6 @@ +module a { header "a.h" } +module b { header "b.h" } +module c { + module c1 { header "c1.h" } + module c2 { header "c2.h" } +} diff --git a/test/Modules/Inputs/category_right_sub.h b/test/Modules/Inputs/category_right_sub.h index 231f65ffe0adc..c8ba7937f561e 100644 --- a/test/Modules/Inputs/category_right_sub.h +++ b/test/Modules/Inputs/category_right_sub.h @@ -15,3 +15,8 @@ @interface Foo(LeftP4) <P4> @end + +// A hidden extension +@interface Foo () +@property (assign) int hiddenPropertyFromExtension; +@end diff --git a/test/Modules/Inputs/codegen-flags/foo.h b/test/Modules/Inputs/codegen-flags/foo.h new file mode 100644 index 0000000000000..7b9c1cd8e086e --- /dev/null +++ b/test/Modules/Inputs/codegen-flags/foo.h @@ -0,0 +1,4 @@ +struct foo { +}; +inline void f1() { +} diff --git a/test/Modules/Inputs/codegen-flags/foo.modulemap b/test/Modules/Inputs/codegen-flags/foo.modulemap new file mode 100644 index 0000000000000..2e095d2794c34 --- /dev/null +++ b/test/Modules/Inputs/codegen-flags/foo.modulemap @@ -0,0 +1 @@ +module foo { header "foo.h" } diff --git a/test/Modules/Inputs/codegen-flags/use.cpp b/test/Modules/Inputs/codegen-flags/use.cpp new file mode 100644 index 0000000000000..378ff3124e756 --- /dev/null +++ b/test/Modules/Inputs/codegen-flags/use.cpp @@ -0,0 +1,5 @@ +#include "foo.h" +void use() { + f1(); + foo f; +} diff --git a/test/Modules/Inputs/codegen-nodep/foo.h b/test/Modules/Inputs/codegen-nodep/foo.h new file mode 100644 index 0000000000000..e7b20a512db16 --- /dev/null +++ b/test/Modules/Inputs/codegen-nodep/foo.h @@ -0,0 +1,11 @@ +template <typename T> +void foot() { +} +inline void foo() { +} + +template <typename T> +struct bart { +}; +struct bar { +}; diff --git a/test/Modules/Inputs/codegen-nodep/foo.modulemap b/test/Modules/Inputs/codegen-nodep/foo.modulemap new file mode 100644 index 0000000000000..2e095d2794c34 --- /dev/null +++ b/test/Modules/Inputs/codegen-nodep/foo.modulemap @@ -0,0 +1 @@ +module foo { header "foo.h" } diff --git a/test/Modules/Inputs/codegen-opt/bar.h b/test/Modules/Inputs/codegen-opt/bar.h new file mode 100644 index 0000000000000..a00e8f70e0896 --- /dev/null +++ b/test/Modules/Inputs/codegen-opt/bar.h @@ -0,0 +1,2 @@ +#include "foo.h" +inline void bar() { foo(); } diff --git a/test/Modules/Inputs/codegen-opt/bar.modulemap b/test/Modules/Inputs/codegen-opt/bar.modulemap new file mode 100644 index 0000000000000..f1dc625857e02 --- /dev/null +++ b/test/Modules/Inputs/codegen-opt/bar.modulemap @@ -0,0 +1 @@ +module bar { header "bar.h" } diff --git a/test/Modules/Inputs/codegen-opt/foo.h b/test/Modules/Inputs/codegen-opt/foo.h new file mode 100644 index 0000000000000..b3a7af7c9d9bc --- /dev/null +++ b/test/Modules/Inputs/codegen-opt/foo.h @@ -0,0 +1,10 @@ +void f1(int &); +static void f2() {} +inline void foo() { + static int i; + f1(i); + f2(); +} +inline void foo2() { +} +void foo_ext() {} diff --git a/test/Modules/Inputs/codegen-opt/foo.modulemap b/test/Modules/Inputs/codegen-opt/foo.modulemap new file mode 100644 index 0000000000000..2e095d2794c34 --- /dev/null +++ b/test/Modules/Inputs/codegen-opt/foo.modulemap @@ -0,0 +1 @@ +module foo { header "foo.h" } diff --git a/test/Modules/Inputs/codegen-opt/use.cpp b/test/Modules/Inputs/codegen-opt/use.cpp new file mode 100644 index 0000000000000..b55a31fe158f5 --- /dev/null +++ b/test/Modules/Inputs/codegen-opt/use.cpp @@ -0,0 +1,2 @@ +#include "bar.h" +int main() { bar(); } diff --git a/test/Modules/Inputs/codegen/foo.h b/test/Modules/Inputs/codegen/foo.h new file mode 100644 index 0000000000000..bd3b6489e710f --- /dev/null +++ b/test/Modules/Inputs/codegen/foo.h @@ -0,0 +1,32 @@ +inline void f1(const char* fmt, ...) { + __builtin_va_list args; + __builtin_va_start(args, fmt); +} + +struct non_trivial_dtor { + ~non_trivial_dtor(); +}; + +struct implicit_dtor { + non_trivial_dtor d; +}; + +struct uninst_implicit_dtor { + non_trivial_dtor d; +}; + +inline void use_implicit_dtor() { + implicit_dtor d; +} + +template <typename T> +void inst() { +} + +inline void inst_decl() { + // cause inst<int>'s declaration to be instantiated, without a definition. + (void)sizeof(&inst<int>); + inst<float>(); +} + +asm("narf"); diff --git a/test/Modules/Inputs/codegen/foo.modulemap b/test/Modules/Inputs/codegen/foo.modulemap new file mode 100644 index 0000000000000..2e095d2794c34 --- /dev/null +++ b/test/Modules/Inputs/codegen/foo.modulemap @@ -0,0 +1 @@ +module foo { header "foo.h" } diff --git a/test/Modules/Inputs/codegen/use.cpp b/test/Modules/Inputs/codegen/use.cpp new file mode 100644 index 0000000000000..cd1a4a642d09d --- /dev/null +++ b/test/Modules/Inputs/codegen/use.cpp @@ -0,0 +1,8 @@ +#include "foo.h" +void non_modular_use_of_implicit_dtor() { + implicit_dtor d1; + uninst_implicit_dtor d2; +} +void use_of_instantiated_declaration_without_definition() { + inst<int>(); +} diff --git a/test/Modules/Inputs/cxx17/decls.h b/test/Modules/Inputs/cxx17/decls.h new file mode 100644 index 0000000000000..473b6d15112ad --- /dev/null +++ b/test/Modules/Inputs/cxx17/decls.h @@ -0,0 +1,3 @@ +struct MergeExceptionSpec { + ~MergeExceptionSpec(); // unevaluated exception spec +}; diff --git a/test/Modules/Inputs/cxx17/module.modulemap b/test/Modules/Inputs/cxx17/module.modulemap new file mode 100644 index 0000000000000..2339e49e03bd9 --- /dev/null +++ b/test/Modules/Inputs/cxx17/module.modulemap @@ -0,0 +1 @@ +module Decls { header "decls.h" } diff --git a/test/Modules/Inputs/diag_pragma.h b/test/Modules/Inputs/diag_pragma.h index a8f958994ca58..59c73ea756e0f 100644 --- a/test/Modules/Inputs/diag_pragma.h +++ b/test/Modules/Inputs/diag_pragma.h @@ -1,3 +1,13 @@ #define DIAG_PRAGMA_MACRO 1 #pragma clang diagnostic ignored "-Wparentheses" + +#ifdef __cplusplus +template<typename T> const char *f(T t) { + return "foo" + t; +} +#pragma clang diagnostic ignored "-Wstring-plus-int" +template<typename T> const char *g(T t) { + return "foo" + t; +} +#endif diff --git a/test/Modules/Inputs/gnumode-non-benign/module.h b/test/Modules/Inputs/gnumode-non-benign/module.h new file mode 100644 index 0000000000000..efde0ad70c553 --- /dev/null +++ b/test/Modules/Inputs/gnumode-non-benign/module.h @@ -0,0 +1,5 @@ +// Check for GNUMode = 1 by looking for the "linux" define which only exists +// for GNUMode = 1. +#ifdef linux + #error "Submodule has GNUMode=1" +#endif diff --git a/test/Modules/Inputs/gnumode-non-benign/module.modulemap b/test/Modules/Inputs/gnumode-non-benign/module.modulemap new file mode 100644 index 0000000000000..702ef596eb06b --- /dev/null +++ b/test/Modules/Inputs/gnumode-non-benign/module.modulemap @@ -0,0 +1 @@ +module "module.h" { header "module.h"} diff --git a/test/Modules/Inputs/hidden-names/hidden.h b/test/Modules/Inputs/hidden-names/hidden.h new file mode 100644 index 0000000000000..e5c2f551c52df --- /dev/null +++ b/test/Modules/Inputs/hidden-names/hidden.h @@ -0,0 +1,3 @@ +namespace NS { + struct X {}; +} diff --git a/test/Modules/Inputs/hidden-names/module.modulemap b/test/Modules/Inputs/hidden-names/module.modulemap new file mode 100644 index 0000000000000..1471f589c6660 --- /dev/null +++ b/test/Modules/Inputs/hidden-names/module.modulemap @@ -0,0 +1,4 @@ +module hidden { + header "visible.h" + explicit module sub { header "hidden.h" } +} diff --git a/test/Modules/Inputs/hidden-names/visible.h b/test/Modules/Inputs/hidden-names/visible.h new file mode 100644 index 0000000000000..3dfc9c715cdae --- /dev/null +++ b/test/Modules/Inputs/hidden-names/visible.h @@ -0,0 +1,2 @@ +// hidden-names/visible.h +namespace NS {} diff --git a/test/Modules/Inputs/implicit-built-Werror-using-W/convert.h b/test/Modules/Inputs/implicit-built-Werror-using-W/convert.h new file mode 100644 index 0000000000000..0ed02bc793bd1 --- /dev/null +++ b/test/Modules/Inputs/implicit-built-Werror-using-W/convert.h @@ -0,0 +1,8 @@ +#ifdef USE_PRAGMA +#pragma clang diagnostic push +#pragma clang diagnostic warning "-Wshorten-64-to-32" +#endif +template <class T> int convert(T V) { return V; } +#ifdef USE_PRAGMA +#pragma clang diagnostic pop +#endif diff --git a/test/Modules/Inputs/implicit-built-Werror-using-W/module.modulemap b/test/Modules/Inputs/implicit-built-Werror-using-W/module.modulemap new file mode 100644 index 0000000000000..825eb86038eda --- /dev/null +++ b/test/Modules/Inputs/implicit-built-Werror-using-W/module.modulemap @@ -0,0 +1,3 @@ +module convert { + header "convert.h" +} diff --git a/test/Modules/Inputs/invalid-module-id/NC-Prefix.pch b/test/Modules/Inputs/invalid-module-id/NC-Prefix.pch new file mode 100644 index 0000000000000..73a9816a3abd9 --- /dev/null +++ b/test/Modules/Inputs/invalid-module-id/NC-Prefix.pch @@ -0,0 +1,3 @@ +#ifdef __OBJC__ + #import <NC/NULog.h> +#endif diff --git a/test/Modules/Inputs/invalid-module-id/NC.framework/Headers/NC.h b/test/Modules/Inputs/invalid-module-id/NC.framework/Headers/NC.h new file mode 100644 index 0000000000000..3866c88828212 --- /dev/null +++ b/test/Modules/Inputs/invalid-module-id/NC.framework/Headers/NC.h @@ -0,0 +1 @@ +#import <NC/NUGeometry.h> diff --git a/test/Modules/Inputs/invalid-module-id/NC.framework/Headers/NU-Visibility.h b/test/Modules/Inputs/invalid-module-id/NC.framework/Headers/NU-Visibility.h new file mode 100644 index 0000000000000..1e7614c0c3811 --- /dev/null +++ b/test/Modules/Inputs/invalid-module-id/NC.framework/Headers/NU-Visibility.h @@ -0,0 +1 @@ +// NU-Visibility.h diff --git a/test/Modules/Inputs/invalid-module-id/NC.framework/Headers/NUGeometry.h b/test/Modules/Inputs/invalid-module-id/NC.framework/Headers/NUGeometry.h new file mode 100644 index 0000000000000..8923e042db6cd --- /dev/null +++ b/test/Modules/Inputs/invalid-module-id/NC.framework/Headers/NUGeometry.h @@ -0,0 +1 @@ +#import <NC/NU-Visibility.h> diff --git a/test/Modules/Inputs/invalid-module-id/NC.framework/Modules/module.modulemap b/test/Modules/Inputs/invalid-module-id/NC.framework/Modules/module.modulemap new file mode 100644 index 0000000000000..475b414733600 --- /dev/null +++ b/test/Modules/Inputs/invalid-module-id/NC.framework/Modules/module.modulemap @@ -0,0 +1,6 @@ +framework module NC { + umbrella header "NC.h" + + export * + module * { export * } +} diff --git a/test/Modules/Inputs/invalid-module-id/NC.framework/Modules/module.private.modulemap b/test/Modules/Inputs/invalid-module-id/NC.framework/Modules/module.private.modulemap new file mode 100644 index 0000000000000..80488bd5d3d1e --- /dev/null +++ b/test/Modules/Inputs/invalid-module-id/NC.framework/Modules/module.private.modulemap @@ -0,0 +1,5 @@ +explicit module NC.Private +{ + header "NULog.h" + header "NUAssert.h" +} diff --git a/test/Modules/Inputs/invalid-module-id/NC.framework/PrivateHeaders/NUAssert.h b/test/Modules/Inputs/invalid-module-id/NC.framework/PrivateHeaders/NUAssert.h new file mode 100644 index 0000000000000..7bf8defa8ccbe --- /dev/null +++ b/test/Modules/Inputs/invalid-module-id/NC.framework/PrivateHeaders/NUAssert.h @@ -0,0 +1 @@ +#import <NC/NULog.h> diff --git a/test/Modules/Inputs/invalid-module-id/NC.framework/PrivateHeaders/NULog.h b/test/Modules/Inputs/invalid-module-id/NC.framework/PrivateHeaders/NULog.h new file mode 100644 index 0000000000000..8923e042db6cd --- /dev/null +++ b/test/Modules/Inputs/invalid-module-id/NC.framework/PrivateHeaders/NULog.h @@ -0,0 +1 @@ +#import <NC/NU-Visibility.h> diff --git a/test/Modules/Inputs/merge-function-defs/a.h b/test/Modules/Inputs/merge-function-defs/a.h new file mode 100644 index 0000000000000..7fc0e52c41043 --- /dev/null +++ b/test/Modules/Inputs/merge-function-defs/a.h @@ -0,0 +1,4 @@ +struct X { + virtual void f(); +}; +inline void X::f() {} diff --git a/test/Modules/Inputs/merge-function-defs/b.h b/test/Modules/Inputs/merge-function-defs/b.h new file mode 100644 index 0000000000000..e69de29bb2d1d --- /dev/null +++ b/test/Modules/Inputs/merge-function-defs/b.h diff --git a/test/Modules/Inputs/merge-function-defs/map b/test/Modules/Inputs/merge-function-defs/map new file mode 100644 index 0000000000000..f84c7ddfd5adc --- /dev/null +++ b/test/Modules/Inputs/merge-function-defs/map @@ -0,0 +1,4 @@ +module m { + module a { header "a.h" } + module b { header "b.h" } +} diff --git a/test/Modules/Inputs/merge-name-for-linkage/b.h b/test/Modules/Inputs/merge-name-for-linkage/b.h index 82f2fdd83e311..5593e41171399 100644 --- a/test/Modules/Inputs/merge-name-for-linkage/b.h +++ b/test/Modules/Inputs/merge-name-for-linkage/b.h @@ -1 +1,5 @@ typedef union {} pthread_mutex_t; + +// Define then merge with another definition. +typedef struct {} merged_after_definition; +#include "c1.h" diff --git a/test/Modules/Inputs/merge-name-for-linkage/c1.h b/test/Modules/Inputs/merge-name-for-linkage/c1.h new file mode 100644 index 0000000000000..b3fd8aced6eae --- /dev/null +++ b/test/Modules/Inputs/merge-name-for-linkage/c1.h @@ -0,0 +1 @@ +// c1 diff --git a/test/Modules/Inputs/merge-name-for-linkage/c2.h b/test/Modules/Inputs/merge-name-for-linkage/c2.h new file mode 100644 index 0000000000000..3ac835629915a --- /dev/null +++ b/test/Modules/Inputs/merge-name-for-linkage/c2.h @@ -0,0 +1,2 @@ +// c2.h +typedef struct {} merged_after_definition; diff --git a/test/Modules/Inputs/merge-name-for-linkage/module.modulemap b/test/Modules/Inputs/merge-name-for-linkage/module.modulemap index 61578a1865aa5..216add76be2a6 100644 --- a/test/Modules/Inputs/merge-name-for-linkage/module.modulemap +++ b/test/Modules/Inputs/merge-name-for-linkage/module.modulemap @@ -1,2 +1,3 @@ module a { header "a.h" export * } module b { header "b.h" export * } +module c { module c1 { header "c1.h" export * } module c2 { header "c2.h" export * } } diff --git a/test/Modules/Inputs/merge-using-decls/b.h b/test/Modules/Inputs/merge-using-decls/b.h index 359555570a43e..5d112ffbfe96f 100644 --- a/test/Modules/Inputs/merge-using-decls/b.h +++ b/test/Modules/Inputs/merge-using-decls/b.h @@ -29,11 +29,13 @@ template<typename T> struct D : X, T { using typename X::t; }; +#if __cplusplus <= 199711L // C++11 does not allow access declarations template<typename T> struct E : X, T { // Mismatch in using/access-declaration-ness. T::value; X::v; }; +#endif template<typename T> struct F : X, T { // Mismatch in nested-name-specifier. @@ -46,5 +48,9 @@ template<typename T> struct F : X, T { // Force instantiation. typedef C<YB>::type I; typedef D<YBRev>::t I; + +#if __cplusplus <= 199711L // C++11 does not allow access declarations typedef E<YB>::type I; +#endif + typedef F<YB>::type I; diff --git a/test/Modules/Inputs/module.map b/test/Modules/Inputs/module.map index 2beb942861a46..b95eec351e862 100644 --- a/test/Modules/Inputs/module.map +++ b/test/Modules/Inputs/module.map @@ -265,6 +265,11 @@ module diag_pragma { header "diag_pragma.h" } +module pragma_pack { + module set { header "pragma_pack_set.h" } + module empty { header "empty.h" } +} + module dummy { header "dummy.h" } diff --git a/test/Modules/Inputs/outofdate-rebuild/AppKit.h b/test/Modules/Inputs/outofdate-rebuild/AppKit.h new file mode 100644 index 0000000000000..e357918fd45cf --- /dev/null +++ b/test/Modules/Inputs/outofdate-rebuild/AppKit.h @@ -0,0 +1,3 @@ +// AppKit +#import "CoreVideo.h" // CoreVideo +struct B { int i; }; diff --git a/test/Modules/Inputs/outofdate-rebuild/Cocoa.h b/test/Modules/Inputs/outofdate-rebuild/Cocoa.h new file mode 100644 index 0000000000000..d6311405f4e1a --- /dev/null +++ b/test/Modules/Inputs/outofdate-rebuild/Cocoa.h @@ -0,0 +1,5 @@ +// Cocoa +#import "Foundation.h" +#import "AppKit.h" + +struct A { int i; }; diff --git a/test/Modules/Inputs/outofdate-rebuild/CoreText.h b/test/Modules/Inputs/outofdate-rebuild/CoreText.h new file mode 100644 index 0000000000000..7ff0e23af1ba1 --- /dev/null +++ b/test/Modules/Inputs/outofdate-rebuild/CoreText.h @@ -0,0 +1 @@ +struct C { int i; }; diff --git a/test/Modules/Inputs/outofdate-rebuild/CoreVideo.h b/test/Modules/Inputs/outofdate-rebuild/CoreVideo.h new file mode 100644 index 0000000000000..bd249dcbb74cf --- /dev/null +++ b/test/Modules/Inputs/outofdate-rebuild/CoreVideo.h @@ -0,0 +1,3 @@ +// CoreVideo +#import "Foundation.h" // Foundation +struct E { int i; }; diff --git a/test/Modules/Inputs/outofdate-rebuild/Foundation.h b/test/Modules/Inputs/outofdate-rebuild/Foundation.h new file mode 100644 index 0000000000000..b2d053ad057a2 --- /dev/null +++ b/test/Modules/Inputs/outofdate-rebuild/Foundation.h @@ -0,0 +1,3 @@ +// Foundation +#import "CoreText.h" +struct D { int i; }; diff --git a/test/Modules/Inputs/outofdate-rebuild/module.modulemap b/test/Modules/Inputs/outofdate-rebuild/module.modulemap new file mode 100644 index 0000000000000..71c99e81966e6 --- /dev/null +++ b/test/Modules/Inputs/outofdate-rebuild/module.modulemap @@ -0,0 +1,19 @@ +module Cocoa { + header "Cocoa.h" +} + +module AppKit { + header "AppKit.h" +} + +module CoreText { + header "CoreText.h" +} + +module Foundation { + header "Foundation.h" +} + +module CoreVideo { + header "CoreVideo.h" +} diff --git a/test/Modules/Inputs/overloadable-attrs/a.h b/test/Modules/Inputs/overloadable-attrs/a.h new file mode 100644 index 0000000000000..1af769dad3156 --- /dev/null +++ b/test/Modules/Inputs/overloadable-attrs/a.h @@ -0,0 +1,28 @@ +namespace enable_if_attrs { +constexpr int fn1() __attribute__((enable_if(0, ""))) { return 0; } +constexpr int fn1() { return 1; } + +constexpr int fn2() { return 1; } +constexpr int fn2() __attribute__((enable_if(0, ""))) { return 0; } + +constexpr int fn3(int i) __attribute__((enable_if(!i, ""))) { return 0; } +constexpr int fn3(int i) __attribute__((enable_if(i, ""))) { return 1; } + +constexpr int fn4(int i) { return 0; } +constexpr int fn4(int i) __attribute__((enable_if(i, ""))) { return 1; } + +constexpr int fn5(int i) __attribute__((enable_if(i, ""))) { return 1; } +constexpr int fn5(int i) { return 0; } +} + +namespace pass_object_size_attrs { +constexpr int fn1(void *const a __attribute__((pass_object_size(0)))) { + return 1; +} +constexpr int fn1(void *const a) { return 0; } + +constexpr int fn2(void *const a) { return 0; } +constexpr int fn2(void *const a __attribute__((pass_object_size(0)))) { + return 1; +} +} diff --git a/test/Modules/Inputs/overloadable-attrs/module.modulemap b/test/Modules/Inputs/overloadable-attrs/module.modulemap new file mode 100644 index 0000000000000..514d745d1465d --- /dev/null +++ b/test/Modules/Inputs/overloadable-attrs/module.modulemap @@ -0,0 +1,3 @@ +module a { + header "a.h" +} diff --git a/test/Modules/Inputs/pragma_pack_set.h b/test/Modules/Inputs/pragma_pack_set.h new file mode 100644 index 0000000000000..b123c116ea1c6 --- /dev/null +++ b/test/Modules/Inputs/pragma_pack_set.h @@ -0,0 +1,3 @@ + +#pragma pack (1) + diff --git a/test/Modules/Inputs/system-out-of-date/X.h b/test/Modules/Inputs/system-out-of-date/X.h new file mode 100644 index 0000000000000..f26ce7e27d093 --- /dev/null +++ b/test/Modules/Inputs/system-out-of-date/X.h @@ -0,0 +1,2 @@ +// X.h +#import <Y.h> diff --git a/test/Modules/Inputs/system-out-of-date/Y.h b/test/Modules/Inputs/system-out-of-date/Y.h new file mode 100644 index 0000000000000..90fe1bcc58511 --- /dev/null +++ b/test/Modules/Inputs/system-out-of-date/Y.h @@ -0,0 +1 @@ +//empty diff --git a/test/Modules/Inputs/system-out-of-date/Z.h b/test/Modules/Inputs/system-out-of-date/Z.h new file mode 100644 index 0000000000000..5db801a509de1 --- /dev/null +++ b/test/Modules/Inputs/system-out-of-date/Z.h @@ -0,0 +1,2 @@ +// Z.h +#import <Y.h> diff --git a/test/Modules/Inputs/system-out-of-date/module.map b/test/Modules/Inputs/system-out-of-date/module.map new file mode 100644 index 0000000000000..0c0f42a5d01ca --- /dev/null +++ b/test/Modules/Inputs/system-out-of-date/module.map @@ -0,0 +1,12 @@ +module X [system] { + header "X.h" // imports Y + export * +} +module Y { + header "Y.h" + export * +} +module Z { + header "Z.h" // imports Y + export * +} diff --git a/test/Modules/Inputs/warning-mismatch/Mismatch.h b/test/Modules/Inputs/warning-mismatch/Mismatch.h new file mode 100644 index 0000000000000..a07b0ee31eafe --- /dev/null +++ b/test/Modules/Inputs/warning-mismatch/Mismatch.h @@ -0,0 +1 @@ +struct Mismatch { int i; }; diff --git a/test/Modules/Inputs/warning-mismatch/System.h b/test/Modules/Inputs/warning-mismatch/System.h new file mode 100644 index 0000000000000..8e69e704c7534 --- /dev/null +++ b/test/Modules/Inputs/warning-mismatch/System.h @@ -0,0 +1,2 @@ +#import "Mismatch.h" +struct System { int i; }; diff --git a/test/Modules/Inputs/warning-mismatch/module.modulemap b/test/Modules/Inputs/warning-mismatch/module.modulemap new file mode 100644 index 0000000000000..c22cde4597870 --- /dev/null +++ b/test/Modules/Inputs/warning-mismatch/module.modulemap @@ -0,0 +1,7 @@ +module System [system] { + header "System.h" +} + +module Mismatch { + header "Mismatch.h" +} diff --git a/test/Modules/anon-redecl.cpp b/test/Modules/anon-redecl.cpp new file mode 100644 index 0000000000000..c3c5c9e527e47 --- /dev/null +++ b/test/Modules/anon-redecl.cpp @@ -0,0 +1,15 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fmodules-local-submodule-visibility \ +// RUN: -fmodule-map-file=%S/Inputs/anon-redecl/module.modulemap \ +// RUN: -I%S/Inputs/anon-redecl \ +// RUN: -verify -std=c++11 %s + +#include "a.h" +#include "b.h" +#include "c1.h" +#include "c2.h" + +// expected-no-diagnostics +int x = a({}); +int y = b({}); +int z = c({}); diff --git a/test/Modules/builtins.m b/test/Modules/builtins.m index 2480e6379cc85..88a44e7b0aa34 100644 --- a/test/Modules/builtins.m +++ b/test/Modules/builtins.m @@ -8,6 +8,7 @@ // RUN: %clang_cc1 -fmodules-cache-path=%t.pch.cache -fmodules -fimplicit-module-maps -I %S/Inputs %s -include-pch %t.pch %s -verify // expected-no-diagnostics +// REQUIRES: shell void use_constant_string_builtins1(void) { (void)__builtin___CFStringMakeConstantString(""); diff --git a/test/Modules/codegen-flags.test b/test/Modules/codegen-flags.test new file mode 100644 index 0000000000000..4cc62e87358d7 --- /dev/null +++ b/test/Modules/codegen-flags.test @@ -0,0 +1,25 @@ +RUN: rm -rf %t +REQUIRES: x86-registered-target + +RUN: %clang_cc1 -triple=x86_64-linux-gnu -fmodules-codegen -x c++ -fmodules -emit-module -fmodule-name=foo %S/Inputs/codegen-flags/foo.modulemap -o %t/foo-cg.pcm +RUN: %clang_cc1 -triple=x86_64-linux-gnu -fmodules-debuginfo -x c++ -fmodules -emit-module -fmodule-name=foo %S/Inputs/codegen-flags/foo.modulemap -o %t/foo-di.pcm + +RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -debug-info-kind=limited -o - %t/foo-cg.pcm | FileCheck --check-prefix=CG %s +RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -debug-info-kind=limited -o - %t/foo-di.pcm | FileCheck --check-prefix=DI %s + +RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -debug-info-kind=limited -o - -fmodules -fmodule-file=%t/foo-cg.pcm %S/Inputs/codegen-flags/use.cpp | FileCheck --check-prefix=CG-USE %s +RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -debug-info-kind=limited -o - -fmodules -fmodule-file=%t/foo-di.pcm %S/Inputs/codegen-flags/use.cpp | FileCheck --check-prefix=DI-USE %s + +CG: define weak_odr void @_Z2f1v +CG: DICompileUnit +CG-NOT: DICompositeType + +CG-USE: declare void @_Z2f1v +CG-USE: DICompileUnit +CG-USE: distinct !DICompositeType(tag: DW_TAG_structure_type, name: "foo" + +DI-NOT: define +DI: distinct !DICompositeType(tag: DW_TAG_structure_type, name: "foo" + +DI-USE: define linkonce_odr void @_Z2f1v +DI-USE: = !DICompositeType(tag: DW_TAG_structure_type, name: "foo", {{.*}}, flags: DIFlagFwdDecl diff --git a/test/Modules/codegen-nodep.test b/test/Modules/codegen-nodep.test new file mode 100644 index 0000000000000..9b718ca9a3cf0 --- /dev/null +++ b/test/Modules/codegen-nodep.test @@ -0,0 +1,13 @@ +RUN: rm -rf %t +REQUIRES: x86-registered-target + +RUN: %clang_cc1 -triple=x86_64-linux-gnu -fmodules-codegen -fmodules-debuginfo \ +RUN: -x c++ -fmodules -emit-module -fmodule-name=foo \ +RUN: %S/Inputs/codegen-nodep/foo.modulemap -o - \ +RUN: | llvm-bcanalyzer - -dump \ +RUN: | FileCheck %s + +Ensure there are only two modular codegen decls (one for the class, one for the +function - none for the class and function templates). + +CHECK: <MODULAR_CODEGEN_DECLS op0={{[0-9]+}} op1={{[0-9]+}}/> diff --git a/test/Modules/codegen-opt.test b/test/Modules/codegen-opt.test new file mode 100644 index 0000000000000..2f4997a7c73f0 --- /dev/null +++ b/test/Modules/codegen-opt.test @@ -0,0 +1,65 @@ +RUN: rm -rf %t +REQUIRES: x86-registered-target + +RUN: %clang_cc1 -triple=x86_64-linux-gnu -fmodules-codegen -x c++ -fmodules -emit-module -fmodule-name=foo %S/Inputs/codegen-opt/foo.modulemap -o %t/foo.pcm +RUN: %clang_cc1 -triple=x86_64-linux-gnu -fmodules-codegen -x c++ -fmodules -emit-module -fmodule-name=bar %S/Inputs/codegen-opt/bar.modulemap -o %t/bar.pcm -fmodule-file=%t/foo.pcm + +RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %t/foo.pcm | FileCheck --check-prefix=FOO %s +RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %t/bar.pcm -fmodule-file=%t/foo.pcm | FileCheck --check-prefix=BAR-CMN --check-prefix=BAR %s +RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - -fmodules -fmodule-file=%t/foo.pcm -fmodule-file=%t/bar.pcm %S/Inputs/codegen-opt/use.cpp | FileCheck --check-prefix=USE-CMN --check-prefix=USE %s + +RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - -O2 -disable-llvm-passes %t/foo.pcm | FileCheck --check-prefix=FOO %s +RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - -O2 -disable-llvm-passes %t/bar.pcm -fmodule-file=%t/foo.pcm | FileCheck --check-prefix=BAR-CMN --check-prefix=BAR-OPT %s +RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - -O2 -disable-llvm-passes -fmodules -fmodule-file=%t/foo.pcm -fmodule-file=%t/bar.pcm %S/Inputs/codegen-opt/use.cpp | FileCheck --check-prefix=USE-CMN --check-prefix=USE-OPT %s + +FOO-NOT: comdat +FOO: $_Z3foov = comdat any +FOO: $_Z4foo2v = comdat any +FOO: $_ZZ3foovE1i = comdat any +FOO: @_ZZ3foovE1i = linkonce_odr global i32 0, comdat +FOO-NOT: {{comdat|define|declare}} +FOO: define void @_Z7foo_extv() +FOO-NOT: {{define|declare}} +FOO: define weak_odr void @_Z3foov() #{{[0-9]+}} comdat +FOO-NOT: {{define|declare}} +FOO: declare void @_Z2f1Ri(i32* +FOO-NOT: {{define|declare}} + +FIXME: this internal function should be weak_odr, comdat, and with a new mangling +FOO: define internal void @_ZL2f2v() #{{[0-9]+}} +FOO-NOT: {{define|declare}} + +FOO: define weak_odr void @_Z4foo2v() #{{[0-9]+}} comdat +FOO-NOT: {{define|declare}} + + +BAR-CMN-NOT: comdat +BAR-CMN: $_Z3barv = comdat any +BAR-OPT: @_ZZ3foovE1i = linkonce_odr global i32 0, comdat +BAR-CMN-NOT: {{comdat|define|declare}} +BAR-CMN: define weak_odr void @_Z3barv() #{{[0-9]+}} comdat +BAR-CMN-NOT: {{define|declare}} +BAR: declare void @_Z3foov() +Include all the available_externally definitions required for bar (foo -> f2) +BAR-OPT: define available_externally void @_Z3foov() +BAR-CMN-NOT: {{define|declare}} +BAR-OPT: declare void @_Z2f1Ri(i32* +BAR-OPT-NOT: {{define|declare}} +BAR-OPT: define available_externally void @_ZL2f2v() +BAR-OPT-NOT: {{define|declare}} + + +USE-OPT: @_ZZ3foovE1i = linkonce_odr global i32 0, comdat +USE-CMN-NOT: {{comdat|define|declare}} +USE-CMN: define i32 @main() +USE-CMN-NOT: {{define|declare}} +USE: declare void @_Z3barv() +Include all the available_externally definitions required for main (bar -> foo -> f2) +USE-OPT: define available_externally void @_Z3barv() +USE-CMN-NOT: {{define|declare}} +USE-OPT: define available_externally void @_Z3foov() +USE-OPT-NOT: {{define|declare}} +USE-OPT: declare void @_Z2f1Ri(i32* +USE-OPT-NOT: {{define|declare}} +USE-OPT: define available_externally void @_ZL2f2v() +USE-OPT-NOT: {{define|declare}} diff --git a/test/Modules/codegen.test b/test/Modules/codegen.test new file mode 100644 index 0000000000000..1bdea5df43176 --- /dev/null +++ b/test/Modules/codegen.test @@ -0,0 +1,49 @@ +RUN: rm -rf %t +REQUIRES: x86-registered-target + +RUN: %clang_cc1 -triple=x86_64-linux-gnu -fmodules-codegen -fmodules-debuginfo -x c++ -fmodules -emit-module -fmodule-name=foo %S/Inputs/codegen/foo.modulemap -o %t/foo.pcm + +RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -debug-info-kind=limited -o - %t/foo.pcm | FileCheck --check-prefix=FOO --check-prefix=BOTH %s +RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -debug-info-kind=limited -o - -fmodules -fmodule-file=%t/foo.pcm %S/Inputs/codegen/use.cpp | FileCheck --check-prefix=BOTH --check-prefix=USE %s + +For want of any better definition, inline asm goes "everywhere" the same as it +if it were in a header (with the disadvantage that the inline asm will be +included in the program if the module is used, even if the header containing +the inline asm is never included - unlike a non-modular build). + +This is inconsistent with how namespace scope static variables are handled - +where they only appear in the code that includes a header. This functionality +was implemented to workaround/support the initialization of iostreams +(implemented as a namespace scope static in the header - only to be provided +when that specific header is included in the program). + +FOO: module asm "narf" +USE: module asm "narf" + +FOO: $_Z2f1PKcz = comdat any +FOO: $_ZN13implicit_dtorD1Ev = comdat any +USE: $_Z4instIiEvv = comdat any +FOO: $_ZN13implicit_dtorD2Ev = comdat any +FOO: define weak_odr void @_Z2f1PKcz(i8* %fmt, ...) #{{[0-9]+}} comdat +FOO: call void @llvm.va_start(i8* %{{[a-zA-Z0-9]*}}) + +Test that implicit special members are emitted into the FOO module if they're +ODR used there, otherwise emit them linkonce_odr as usual in the use. + +FIXME: Proactively instantiate any valid implicit special members to emit them into the module object. + +FOO: define weak_odr void @_ZN13implicit_dtorD1Ev +FOO: define weak_odr void @_Z4instIfEvv +FOO: define weak_odr void @_ZN13implicit_dtorD2Ev + +USE: define linkonce_odr void @_ZN20uninst_implicit_dtorD1Ev +USE: define linkonce_odr void @_Z4instIiEvv +USE: define linkonce_odr void @_ZN20uninst_implicit_dtorD2Ev + +Modular debug info puts the definition of a class defined in a module in that +module's object. Users of the module only get a declaration. + +'distinct' is used for definition records (the flags field is empty/unspecified) +FOO: = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "implicit_dtor" +Declarations are non-distinct and include the 'DIFlagFwdDecl' flag. +USE: = !DICompositeType(tag: DW_TAG_structure_type, name: "implicit_dtor", {{.*}}, flags: DIFlagFwdDecl diff --git a/test/Modules/cxx-templates.cpp b/test/Modules/cxx-templates.cpp index 59e9136bd142f..401b7704900ba 100644 --- a/test/Modules/cxx-templates.cpp +++ b/test/Modules/cxx-templates.cpp @@ -49,8 +49,14 @@ void g() { // expected-note@Inputs/cxx-templates-a.h:11 {{candidate}} // expected-note@Inputs/cxx-templates-b.h:11 {{candidate}} - template_param_kinds_3<Tmpl_T_T_A>(); - template_param_kinds_3<Tmpl_T_T_B>(); + // FIXME: This should be valid, but we incorrectly match the template template + // argument against both template template parameters. + template_param_kinds_3<Tmpl_T_T_A>(); // expected-error {{ambiguous}} + // expected-note@Inputs/cxx-templates-a.h:12 {{candidate}} + // expected-note@Inputs/cxx-templates-b.h:12 {{candidate}} + template_param_kinds_3<Tmpl_T_T_B>(); // expected-error {{ambiguous}} + // expected-note@Inputs/cxx-templates-a.h:12 {{candidate}} + // expected-note@Inputs/cxx-templates-b.h:12 {{candidate}} // Trigger the instantiation of a template in 'a' that uses a type defined in // 'common'. That type is not visible here. diff --git a/test/Modules/cxx17.cpp b/test/Modules/cxx17.cpp new file mode 100644 index 0000000000000..1efb490828db5 --- /dev/null +++ b/test/Modules/cxx17.cpp @@ -0,0 +1,11 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -x c++ -std=c++1z -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs/cxx17 %s -verify -fno-modules-error-recovery + +// expected-no-diagnostics +struct MergeExceptionSpec { + ~MergeExceptionSpec(); +} mergeExceptionSpec; // trigger evaluation of exception spec + +#include "decls.h" + +MergeExceptionSpec mergeExceptionSpec2; diff --git a/test/Modules/dependency-dump-dependent-module.m b/test/Modules/dependency-dump-dependent-module.m index 2430726d3ae5a..4906986165465 100644 --- a/test/Modules/dependency-dump-dependent-module.m +++ b/test/Modules/dependency-dump-dependent-module.m @@ -1,6 +1,8 @@ // When a module depends on another, check that we dump the dependency header // files for both. +// REQUIRES: shell + // RUN: rm -rf %t // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -module-dependency-dir %t/vfs -F %S/Inputs -I %S/Inputs -verify %s // expected-no-diagnostics diff --git a/test/Modules/dependency-dump.m b/test/Modules/dependency-dump.m index f3a487544b8e9..deb66188e1472 100644 --- a/test/Modules/dependency-dump.m +++ b/test/Modules/dependency-dump.m @@ -1,6 +1,8 @@ // Check that we can dump all of the headers a module depends on, and a VFS map // for the same. +// REQUIRES: shell + // RUN: rm -rf %t // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -module-dependency-dir %t/vfs -F %S/Inputs -I %S/Inputs -verify %s // expected-no-diagnostics diff --git a/test/Modules/diag-pragma.cpp b/test/Modules/diag-pragma.cpp new file mode 100644 index 0000000000000..347401fffc204 --- /dev/null +++ b/test/Modules/diag-pragma.cpp @@ -0,0 +1,47 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -emit-module -fmodules-cache-path=%t -fmodule-name=diag_pragma -x c++ %S/Inputs/module.map -fmodules-ts +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -fmodules-ts +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -emit-module -fmodule-name=diag_pragma -x c++ %S/Inputs/module.map -fmodules-ts -o %t/explicit.pcm -Werror=string-plus-int +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -fmodules-ts -DEXPLICIT_FLAG -fmodule-file=%t/explicit.pcm + +import diag_pragma; + +int foo(int x) { + // Diagnostics from templates in the module follow the diagnostic state from + // when the module was built. +#ifdef EXPLICIT_FLAG + // expected-error@diag_pragma.h:7 {{adding 'int' to a string}} +#else + // expected-warning@diag_pragma.h:7 {{adding 'int' to a string}} +#endif + // expected-note@diag_pragma.h:7 {{use array indexing}} + f(0); // expected-note {{instantiation of}} + + g(0); // ok, warning was ignored when building module + + // Diagnostics from this source file ignore the diagnostic state from the + // module. + void("foo" + x); // expected-warning {{adding 'int' to a string}} + // expected-note@-1 {{use array indexing}} + +#pragma clang diagnostic ignored "-Wstring-plus-int" + + // Diagnostics from the module ignore diagnostic state changes from this + // source file. +#ifdef EXPLICIT_FLAG + // expected-error@diag_pragma.h:7 {{adding 'long' to a string}} +#else + // expected-warning@diag_pragma.h:7 {{adding 'long' to a string}} +#endif + // expected-note@diag_pragma.h:7 {{use array indexing}} + f(0L); // expected-note {{instantiation of}} + + g(0L); + + void("bar" + x); + + if (x = DIAG_PRAGMA_MACRO) // expected-warning {{using the result of an assignment as a condition without parentheses}} \ + // expected-note {{place parentheses}} expected-note {{use '=='}} + return 0; + return 1; +} diff --git a/test/Modules/diagnostic-options-out-of-date.m b/test/Modules/diagnostic-options-out-of-date.m index ed9e8e1fe1830..fd98a8f99d667 100644 --- a/test/Modules/diagnostic-options-out-of-date.m +++ b/test/Modules/diagnostic-options-out-of-date.m @@ -7,6 +7,16 @@ // RUN: %clang_cc1 -Werror -Wconversion -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs %s -fmodules-disable-diagnostic-validation // Make sure we don't error out when using the pch // RUN: %clang_cc1 -Werror -Wno-conversion -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -fsyntax-only -I %S/Inputs -include-pch %t.pch %s -verify -fmodules-disable-diagnostic-validation + +// Build A.pcm +// RUN: %clang_cc1 -Werror -Wno-conversion -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs %s +// Build pch that imports A.pcm +// RUN: %clang_cc1 -Werror -Wno-conversion -emit-pch -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -o %t.pch -I %S/Inputs -x objective-c-header %S/Inputs/pch-import-module-out-of-date.pch +// We will rebuild A.pcm and overwrite the original A.pcm that the pch imports, but the two versions have the same hash. +// RUN: %clang_cc1 -Werror -Wconversion -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs %s +// Make sure we don't error out when using the pch +// RUN: %clang_cc1 -Werror -Wno-conversion -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -fsyntax-only -I %S/Inputs -include-pch %t.pch %s -verify + // expected-no-diagnostics @import DiagOutOfDate; diff --git a/test/Modules/find-privateheaders.m b/test/Modules/find-privateheaders.m new file mode 100644 index 0000000000000..c5e82ac70da2d --- /dev/null +++ b/test/Modules/find-privateheaders.m @@ -0,0 +1,2 @@ +// RUN: %clang_cc1 -fmodules -fsyntax-only -F%S/Inputs %s +#import "Main/Main.h" diff --git a/test/Modules/gnumode-non-benign.cpp b/test/Modules/gnumode-non-benign.cpp new file mode 100644 index 0000000000000..9255dfe24b110 --- /dev/null +++ b/test/Modules/gnumode-non-benign.cpp @@ -0,0 +1,11 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -std=c++11 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I%S/Inputs/gnumode-non-benign -verify %s + +// expected-no-diagnostics + +// This test ensures that submodules have the same GNUMode language option +// setting as the main clang invocation. +// Note that we set GNUMode = 0 with -std=c++11 for this file. + +// This module fails to compile with GNUMode = 1. +#include "module.h" diff --git a/test/Modules/hidden-names.cpp b/test/Modules/hidden-names.cpp new file mode 100644 index 0000000000000..ba945a1d3c8b2 --- /dev/null +++ b/test/Modules/hidden-names.cpp @@ -0,0 +1,13 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs/hidden-names %s -verify +// expected-no-diagnostics + +#include "visible.h" + +using namespace NS; + +namespace { + struct X { void f(); }; +} + +void X::f() {} diff --git a/test/Modules/implicit-built-Werror-using-W.cpp b/test/Modules/implicit-built-Werror-using-W.cpp new file mode 100644 index 0000000000000..9fb7a6bf0b035 --- /dev/null +++ b/test/Modules/implicit-built-Werror-using-W.cpp @@ -0,0 +1,42 @@ +// Check that implicit modules builds give correct diagnostics, even when +// reusing a module built with strong -Werror flags. +// +// Clear the caches. +// RUN: rm -rf %t.cache %t-pragma.cache +// +// Build with -Werror, then with -W, and then with neither. +// RUN: not %clang_cc1 -triple x86_64-apple-darwin16 -fsyntax-only -fmodules \ +// RUN: -Werror=shorten-64-to-32 \ +// RUN: -I%S/Inputs/implicit-built-Werror-using-W -fimplicit-module-maps \ +// RUN: -fmodules-cache-path=%t.cache -x c++ %s 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-ERROR +// RUN: %clang_cc1 -triple x86_64-apple-darwin16 -fsyntax-only -fmodules \ +// RUN: -Wshorten-64-to-32 \ +// RUN: -I%S/Inputs/implicit-built-Werror-using-W -fimplicit-module-maps \ +// RUN: -fdisable-module-hash \ +// RUN: -fmodules-cache-path=%t.cache -x c++ %s 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-WARN +// RUN: %clang_cc1 -triple x86_64-apple-darwin16 -fsyntax-only -fmodules \ +// RUN: -I%S/Inputs/implicit-built-Werror-using-W -fimplicit-module-maps \ +// RUN: -fmodules-cache-path=%t.cache -x c++ %s 2>&1 \ +// RUN: | FileCheck %s -allow-empty +// +// In the presence of a warning pragma, build with -Werror and then without. +// RUN: not %clang_cc1 -triple x86_64-apple-darwin16 -fsyntax-only -fmodules \ +// RUN: -DUSE_PRAGMA -Werror=shorten-64-to-32 \ +// RUN: -I%S/Inputs/implicit-built-Werror-using-W -fimplicit-module-maps \ +// RUN: -fmodules-cache-path=%t-pragma.cache -x c++ %s 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-ERROR +// RUN: %clang_cc1 -triple x86_64-apple-darwin16 -fsyntax-only -fmodules \ +// RUN: -DUSE_PRAGMA \ +// RUN: -I%S/Inputs/implicit-built-Werror-using-W -fimplicit-module-maps \ +// RUN: -fmodules-cache-path=%t-pragma.cache -x c++ %s 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-WARN +#include <convert.h> + +long long foo() { return convert<long long>(0); } + +// CHECK-ERROR: error: implicit conversion +// CHECK-WARN: warning: implicit conversion +// CHECK-NOT: error: implicit conversion +// CHECK-NOT: warning: implicit conversion diff --git a/test/Modules/implicit-private-with-different-name.m b/test/Modules/implicit-private-with-different-name.m index 3d8f937973f06..c09d3979c3e1d 100644 --- a/test/Modules/implicit-private-with-different-name.m +++ b/test/Modules/implicit-private-with-different-name.m @@ -3,7 +3,7 @@ // Build PCH using A, with adjacent private module APrivate, which winds up being implicitly referenced // RUN: %clang_cc1 -verify -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -F %S/Inputs/implicit-private-with-different-name -emit-pch -o %t-A.pch %s -// Use the PCH with no explicit way to resolve PrivateA, still pick it up through MODULE_DIRECTORY reference in PCH control block +// Use the PCH with no explicit way to resolve APrivate, still pick it up by automatic second-chance search for "A" with "Private" appended // RUN: %clang_cc1 -verify -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -F %S/Inputs/implicit-private-with-different-name -include-pch %t-A.pch %s -fsyntax-only // Check the fixit diff --git a/test/Modules/invalid-pch-module-id.m b/test/Modules/invalid-pch-module-id.m new file mode 100644 index 0000000000000..34d9995cef6d8 --- /dev/null +++ b/test/Modules/invalid-pch-module-id.m @@ -0,0 +1,13 @@ +// RUN: rm -rf %t.cache +// +// RUN: %clang_cc1 -x objective-c-header -fmodules -F%S/Inputs/invalid-module-id \ +// RUN: -fmodule-implementation-of NC -fmodules-cache-path=%t.cache \ +// RUN: -fimplicit-module-maps \ +// RUN: -emit-pch %S/Inputs/invalid-module-id/NC-Prefix.pch -o %t.pch +// +// RUN: %clang_cc1 -x objective-c -fmodules -F%S/Inputs/invalid-module-id \ +// RUN: -fmodule-implementation-of NC -fmodules-cache-path=%t.cache \ +// RUN: -fimplicit-module-maps -include-pch %t.pch %s -fsyntax-only + +#import <NC/NULog.h> +#import <NC/NUGeometry.h> diff --git a/test/Modules/localsubmodulevis.m b/test/Modules/localsubmodulevis.m new file mode 100644 index 0000000000000..f8c4b3c755eb3 --- /dev/null +++ b/test/Modules/localsubmodulevis.m @@ -0,0 +1,8 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fmodules -fmodules-local-submodule-visibility -fimplicit-module-maps -fmodules-cache-path=%t.a -I %S/Inputs/preprocess -verify %s +// RUN: %clang_cc1 -fmodules -fmodules-local-submodule-visibility -fimplicit-module-maps -fmodules-cache-path=%t.b -I %S/Inputs/preprocess -x c -verify -x c %s + +// expected-no-diagnostics + +#include "file.h" + diff --git a/test/Modules/merge-function-defs.cpp b/test/Modules/merge-function-defs.cpp new file mode 100644 index 0000000000000..2f08f523c3aaa --- /dev/null +++ b/test/Modules/merge-function-defs.cpp @@ -0,0 +1,11 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -I%S/Inputs/merge-function-defs -fmodules -fmodule-map-file=%S/Inputs/merge-function-defs/map -fmodules-cache-path=%t %s -emit-llvm-only + +#include "b.h" + +struct X { + virtual void f(); +}; +inline void X::f() {} + +X x; diff --git a/test/Modules/merge-name-for-linkage.cpp b/test/Modules/merge-name-for-linkage.cpp index 75534bd661b96..1fd16865ca7b9 100644 --- a/test/Modules/merge-name-for-linkage.cpp +++ b/test/Modules/merge-name-for-linkage.cpp @@ -7,3 +7,4 @@ typedef pthread_mutex_t pthread_mutex_t; pthread_mutex_t x; #include "b.h" pthread_mutex_t y; +merged_after_definition z; diff --git a/test/Modules/merge-using-decls.cpp b/test/Modules/merge-using-decls.cpp index 98989d12f9855..1ec9a9a17bdee 100644 --- a/test/Modules/merge-using-decls.cpp +++ b/test/Modules/merge-using-decls.cpp @@ -1,6 +1,10 @@ // RUN: rm -rf %t // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x c++ -I%S/Inputs/merge-using-decls -verify %s -DORDER=1 +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x c++ -I%S/Inputs/merge-using-decls -verify -std=c++98 %s -DORDER=1 +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x c++ -I%S/Inputs/merge-using-decls -verify -std=c++11 %s -DORDER=1 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x c++ -I%S/Inputs/merge-using-decls -verify %s -DORDER=2 +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x c++ -I%S/Inputs/merge-using-decls -verify -std=c++98 %s -DORDER=2 +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x c++ -I%S/Inputs/merge-using-decls -verify -std=c++11 %s -DORDER=2 #if ORDER == 1 #include "a.h" @@ -24,7 +28,11 @@ template<typename T> int Use() { } template<typename T> int UseAll() { +#if __cplusplus <= 199711L // C++11 does not allow access declarations return Use<C<T> >() + Use<D<T> >() + Use<E<T> >() + Use<F<T> >(); // expected-note 0-2{{instantiation of}} +#else + return Use<C<T> >() + Use<D<T> >() + Use<F<T> >(); // expected-note 0-2{{instantiation of}} +#endif } template int UseAll<YA>(); @@ -37,8 +45,10 @@ template int UseAll<Y>(); // Here, we're instantiating the definition from 'A' and merging the definition // from 'B' into it. +#if __cplusplus <= 199711L // C++11 does not allow access declarations // expected-error@b.h:* {{'E::value' from module 'B' is not present in definition of 'E<T>' in module 'A'}} // expected-error@b.h:* {{'E::v' from module 'B' is not present in definition of 'E<T>' in module 'A'}} +#endif // expected-error@b.h:* {{'F::type' from module 'B' is not present in definition of 'F<T>' in module 'A'}} // expected-error@b.h:* {{'F::t' from module 'B' is not present in definition of 'F<T>' in module 'A'}} @@ -55,11 +65,14 @@ template int UseAll<Y>(); // expected-error@b.h:* 2{{'typename' keyword used on a non-type}} // expected-error@b.h:* 2{{dependent using declaration resolved to type without 'typename'}} +#if __cplusplus <= 199711L // C++11 does not allow access declarations // expected-error@a.h:* {{'E::type' from module 'A' is not present in definition of 'E<T>' in module 'B'}} // expected-error@a.h:* {{'E::t' from module 'A' is not present in definition of 'E<T>' in module 'B'}} // expected-error@a.h:* {{'E::value' from module 'A' is not present in definition of 'E<T>' in module 'B'}} // expected-error@a.h:* {{'E::v' from module 'A' is not present in definition of 'E<T>' in module 'B'}} // expected-note@b.h:* 2{{definition has no member}} +#endif + // expected-error@a.h:* {{'F::type' from module 'A' is not present in definition of 'F<T>' in module 'B'}} // expected-error@a.h:* {{'F::t' from module 'A' is not present in definition of 'F<T>' in module 'B'}} diff --git a/test/Modules/module-impl-with-link.c b/test/Modules/module-impl-with-link.c index 5e5ca83aafd66..3bd4c4abd92b0 100644 --- a/test/Modules/module-impl-with-link.c +++ b/test/Modules/module-impl-with-link.c @@ -1,5 +1,5 @@ // RUN: rm -rf %t -// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -fmodule-name=Clib %s -I %S/Inputs/module-impl-with-link -emit-llvm -o - +// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -fmodule-name=Clib %s -I %S/Inputs/module-impl-with-link -emit-llvm -o - | FileCheck %s #include "foo.h" // CHECK: !{{[0-9]+}} = !{i32 6, !"Linker Options", ![[LINK_OPTIONS:[0-9]+]]} // Make sure we don't generate linker option for module Clib since this TU is diff --git a/test/Modules/module_file_info.m b/test/Modules/module_file_info.m index fa841b75926c0..f2967be6f8ca4 100644 --- a/test/Modules/module_file_info.m +++ b/test/Modules/module_file_info.m @@ -29,13 +29,9 @@ // CHECK: CPU: // CHECK: ABI: -// CHECK: Diagnostic options: -// CHECK: IgnoreWarnings: Yes -// CHECK: Diagnostic flags: -// CHECK: -Wunused - // CHECK: Header search options: // CHECK: System root [-isysroot=]: '/' +// CHECK: Resource dir [ -resource-dir=]: '{{.*}}clang{{.*}}' // CHECK: Use builtin include directories [-nobuiltininc]: Yes // CHECK: Use standard system include directories [-nostdinc]: No // CHECK: Use standard C++ include directories [-nostdinc++]: Yes @@ -47,3 +43,8 @@ // CHECK: Predefined macros: // CHECK: -DBLARG // CHECK: -DWIBBLE=WOBBLE + +// CHECK: Diagnostic options: +// CHECK: IgnoreWarnings: Yes +// CHECK: Diagnostic flags: +// CHECK: -Wunused diff --git a/test/Modules/module_map_cwd.c b/test/Modules/module_map_cwd.c new file mode 100644 index 0000000000000..d76734adeeb52 --- /dev/null +++ b/test/Modules/module_map_cwd.c @@ -0,0 +1,9 @@ +// RUN: rm -rf %t +// RUN: mkdir %t +// RUN: echo 'module X { header "x.h" }' > %t/map +// RUN: echo 'extern int n;' > %t/x.h +// RUN: cd %t +// RUN: %clang_cc1 %s -fmodules -fmodule-map-file=map -fmodules-cache-path=. -verify -I. +// expected-no-diagnostics +#include "x.h" +int *m = &n; diff --git a/test/Modules/modules-cache-path-canonicalization.m b/test/Modules/modules-cache-path-canonicalization.m new file mode 100644 index 0000000000000..9d68cb06faf8e --- /dev/null +++ b/test/Modules/modules-cache-path-canonicalization.m @@ -0,0 +1,30 @@ +// RUN: rm -rf %t/cache %T/rel + +// This testcase reproduces a use-after-free after looking up a PCM in +// a non-canonical modules-cache-path. +// +// Prime the module cache (note the '.' in the path). +// RUN: %clang_cc1 -fdisable-module-hash -fmodules-cache-path=%t/./cache \ +// RUN: -fmodules -fimplicit-module-maps -I %S/Inputs/outofdate-rebuild \ +// RUN: %s -fsyntax-only +// +// Force a module to be rebuilt by creating a conflict. +// RUN: echo "@import CoreText;" > %t.m +// RUN: %clang_cc1 -DMISMATCH -Werror -fdisable-module-hash \ +// RUN: -fmodules-cache-path=%t/./cache -fmodules -fimplicit-module-maps \ +// RUN: -I %S/Inputs/outofdate-rebuild %t.m -fsyntax-only +// +// Rebuild. +// RUN: %clang_cc1 -fdisable-module-hash -fmodules-cache-path=%t/./cache \ +// RUN: -fmodules -fimplicit-module-maps -I %S/Inputs/outofdate-rebuild \ +// RUN: %s -fsyntax-only + + +// Unrelated to the above: Check that a relative path is resolved correctly. +// +// RUN: %clang_cc1 -working-directory %T/rel -fmodules-cache-path=./cache \ +// RUN: -fmodules -fimplicit-module-maps -I %S/Inputs/outofdate-rebuild \ +// RUN: -fdisable-module-hash %t.m -fsyntax-only -Rmodule-build 2>&1 \ +// RUN: | FileCheck %s +// CHECK: {{/|\\}}rel{{/|\\}}cache{{/|\\}}CoreText.pcm +@import Cocoa; diff --git a/test/Modules/objc-categories.m b/test/Modules/objc-categories.m index 42baf352fbf59..fcffe3cc96200 100644 --- a/test/Modules/objc-categories.m +++ b/test/Modules/objc-categories.m @@ -53,6 +53,9 @@ void test_hidden_all_errors(Foo *foo) { p3p = foo.p3_prop; // expected-error{{property 'p3_prop' not found on object of type 'Foo *'}} id p4p = p4.p4_prop; // expected-error{{property 'p4_prop' not found on object of type 'id<P4>'}} p4p = foo.p4_prop; // expected-error{{property 'p4_prop' not found on object of type 'Foo *'}} + + if (foo.hiddenPropertyFromExtension) { // expected-error {{property 'hiddenPropertyFromExtension' not found on object of type 'Foo *'}} + } } @import category_left.sub; @@ -74,6 +77,7 @@ void test_hidden_right_errors(Foo *foo) { id p4p = p4.p4_prop; // expected-error{{property 'p4_prop' not found on object of type 'id<P4>'}} p4p = foo.p4_prop; // expected-error{{property 'p4_prop' not found on object of type 'Foo *'; did you mean 'p3_prop'?}} // expected-note@Inputs/category_left_sub.h:7{{'p3_prop' declared here}} + int hiddenFromExtension = foo.hiddenPropertyFromExtension; // expected-error {{property 'hiddenPropertyFromExtension' not found on object of type 'Foo *'}} } @import category_right.sub; @@ -92,4 +96,6 @@ void test_hidden_okay(Foo *foo) { p3p = foo.p3_prop; id p4p = p4.p4_prop; p4p = foo.p4_prop; + if (foo.hiddenPropertyFromExtension) { + } } diff --git a/test/Modules/odr_hash.cpp b/test/Modules/odr_hash.cpp new file mode 100644 index 0000000000000..75436706200c5 --- /dev/null +++ b/test/Modules/odr_hash.cpp @@ -0,0 +1,953 @@ +// Clear and create directories +// RUN: rm -rf %t +// RUN: mkdir %t +// RUN: mkdir %t/cache +// RUN: mkdir %t/Inputs + +// Build first header file +// RUN: echo "#define FIRST" >> %t/Inputs/first.h +// RUN: cat %s >> %t/Inputs/first.h + +// Build second header file +// RUN: echo "#define SECOND" >> %t/Inputs/second.h +// RUN: cat %s >> %t/Inputs/second.h + +// Build module map file +// RUN: echo "module FirstModule {" >> %t/Inputs/module.map +// RUN: echo " header \"first.h\"" >> %t/Inputs/module.map +// RUN: echo "}" >> %t/Inputs/module.map +// RUN: echo "module SecondModule {" >> %t/Inputs/module.map +// RUN: echo " header \"second.h\"" >> %t/Inputs/module.map +// RUN: echo "}" >> %t/Inputs/module.map + +// Run test +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -x c++ -I%t/Inputs -verify %s -std=c++1z + +#if !defined(FIRST) && !defined(SECOND) +#include "first.h" +#include "second.h" +#endif + +namespace AccessSpecifiers { +#if defined(FIRST) +struct S1 { +}; +#elif defined(SECOND) +struct S1 { + private: +}; +#else +S1 s1; +// expected-error@second.h:* {{'AccessSpecifiers::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}} +// expected-note@first.h:* {{but in 'FirstModule' found end of class}} +#endif + +#if defined(FIRST) +struct S2 { + public: +}; +#elif defined(SECOND) +struct S2 { + protected: +}; +#else +S2 s2; +// expected-error@second.h:* {{'AccessSpecifiers::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found protected access specifier}} +// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}} +#endif +} // namespace AccessSpecifiers + +namespace StaticAssert { +#if defined(FIRST) +struct S1 { + static_assert(1 == 1, "First"); +}; +#elif defined(SECOND) +struct S1 { + static_assert(1 == 1, "Second"); +}; +#else +S1 s1; +// expected-error@second.h:* {{'StaticAssert::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found static assert with message}} +// expected-note@first.h:* {{but in 'FirstModule' found static assert with different message}} +#endif + +#if defined(FIRST) +struct S2 { + static_assert(2 == 2, "Message"); +}; +#elif defined(SECOND) +struct S2 { + static_assert(2 == 2); +}; +#else +S2 s2; +// expected-error@second.h:* {{'StaticAssert::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found static assert with no message}} +// expected-note@first.h:* {{but in 'FirstModule' found static assert with message}} +#endif + +#if defined(FIRST) +struct S3 { + static_assert(3 == 3, "Message"); +}; +#elif defined(SECOND) +struct S3 { + static_assert(3 != 4, "Message"); +}; +#else +S3 s3; +// expected-error@second.h:* {{'StaticAssert::S3' has different definitions in different modules; first difference is definition in module 'SecondModule' found static assert with condition}} +// expected-note@first.h:* {{but in 'FirstModule' found static assert with different condition}} +#endif + +#if defined(FIRST) +struct S4 { + static_assert(4 == 4, "Message"); +}; +#elif defined(SECOND) +struct S4 { + public: +}; +#else +S4 s4; +// expected-error@second.h:* {{'StaticAssert::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}} +// expected-note@first.h:* {{but in 'FirstModule' found static assert}} +#endif +} + +namespace Field { +#if defined(FIRST) +struct S1 { + int x; + private: + int y; +}; +#elif defined(SECOND) +struct S1 { + int x; + int y; +}; +#else +S1 s1; +// expected-error@second.h:* {{'Field::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found field}} +// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}} +#endif + +#if defined(FIRST) +struct S2 { + int x; + int y; +}; +#elif defined(SECOND) +struct S2 { + int y; + int x; +}; +#else +S2 s2; +// expected-error@second.h:* {{'Field::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'y'}} +// expected-note@first.h:* {{but in 'FirstModule' found field 'x'}} +#endif + +#if defined(FIRST) +struct S3 { + double x; +}; +#elif defined(SECOND) +struct S3 { + int x; +}; +#else +S3 s3; +// expected-error@first.h:* {{'Field::S3::x' from module 'FirstModule' is not present in definition of 'Field::S3' in module 'SecondModule'}} +// expected-note@second.h:* {{declaration of 'x' does not match}} +#endif + +#if defined(FIRST) +typedef int A; +struct S4 { + A x; +}; + +struct S5 { + A x; +}; +#elif defined(SECOND) +typedef int B; +struct S4 { + B x; +}; + +struct S5 { + int x; +}; +#else +S4 s4; +// expected-error@second.h:* {{'Field::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with type 'Field::B' (aka 'int')}} +// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'Field::A' (aka 'int')}} + +S5 s5; +// expected-error@second.h:* {{'Field::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with type 'int'}} +// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'Field::A' (aka 'int')}} +#endif + +#if defined(FIRST) +struct S6 { + unsigned x; +}; +#elif defined(SECOND) +struct S6 { + unsigned x : 1; +}; +#else +S6 s6; +// expected-error@second.h:* {{'Field::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found bitfield 'x'}} +// expected-note@first.h:* {{but in 'FirstModule' found non-bitfield 'x'}} +#endif + +#if defined(FIRST) +struct S7 { + unsigned x : 2; +}; +#elif defined(SECOND) +struct S7 { + unsigned x : 1; +}; +#else +S7 s7; +// expected-error@second.h:* {{'Field::S7' has different definitions in different modules; first difference is definition in module 'SecondModule' found bitfield 'x' with one width expression}} +// expected-note@first.h:* {{but in 'FirstModule' found bitfield 'x' with different width expression}} +#endif + +#if defined(FIRST) +struct S8 { + unsigned x : 2; +}; +#elif defined(SECOND) +struct S8 { + unsigned x : 1 + 1; +}; +#else +S8 s8; +// expected-error@second.h:* {{'Field::S8' has different definitions in different modules; first difference is definition in module 'SecondModule' found bitfield 'x' with one width expression}} +// expected-note@first.h:* {{but in 'FirstModule' found bitfield 'x' with different width expression}} +#endif + +#if defined(FIRST) +struct S9 { + mutable int x; +}; +#elif defined(SECOND) +struct S9 { + int x; +}; +#else +S9 s9; +// expected-error@second.h:* {{'Field::S9' has different definitions in different modules; first difference is definition in module 'SecondModule' found non-mutable field 'x'}} +// expected-note@first.h:* {{but in 'FirstModule' found mutable field 'x'}} +#endif + +#if defined(FIRST) +struct S10 { + unsigned x = 5; +}; +#elif defined(SECOND) +struct S10 { + unsigned x; +}; +#else +S10 s10; +// expected-error@second.h:* {{'Field::S10' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with no initalizer}} +// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with an initializer}} +#endif + +#if defined(FIRST) +struct S11 { + unsigned x = 5; +}; +#elif defined(SECOND) +struct S11 { + unsigned x = 7; +}; +#else +S11 s11; +// expected-error@second.h:* {{'Field::S11' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with an initializer}} +// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with a different initializer}} +#endif + +} // namespace Field + +namespace Method { +#if defined(FIRST) +struct S1 { + void A() {} +}; +#elif defined(SECOND) +struct S1 { + private: + void A() {} +}; +#else +S1 s1; +// expected-error@second.h:* {{'Method::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}} +// expected-note@first.h:* {{but in 'FirstModule' found method}} +#endif + +#if defined(FIRST) +struct S2 { + void A() {} + void B() {} +}; +#elif defined(SECOND) +struct S2 { + void B() {} + void A() {} +}; +#else +S2 s2; +// expected-error@second.h:* {{'Method::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'B'}} +// expected-note@first.h:* {{but in 'FirstModule' found method 'A'}} +#endif + +#if defined(FIRST) +struct S3 { + static void A() {} + void A(int) {} +}; +#elif defined(SECOND) +struct S3 { + void A(int) {} + static void A() {} +}; +#else +S3 s3; +// expected-error@second.h:* {{'Method::S3' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' is not static}} +// expected-note@first.h:* {{but in 'FirstModule' found method 'A' is static}} +#endif + +#if defined(FIRST) +struct S4 { + virtual void A() {} + void B() {} +}; +#elif defined(SECOND) +struct S4 { + void A() {} + virtual void B() {} +}; +#else +S4 s4; +// expected-error@second.h:* {{'Method::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' is not virtual}} +// expected-note@first.h:* {{but in 'FirstModule' found method 'A' is virtual}} +#endif + +#if defined(FIRST) +struct S5 { + virtual void A() = 0; + virtual void B() {}; +}; +#elif defined(SECOND) +struct S5 { + virtual void A() {} + virtual void B() = 0; +}; +#else +S5 *s5; +// expected-error@second.h:* {{'Method::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' is virtual}} +// expected-note@first.h:* {{but in 'FirstModule' found method 'A' is pure virtual}} +#endif + +#if defined(FIRST) +struct S6 { + inline void A() {} +}; +#elif defined(SECOND) +struct S6 { + void A() {} +}; +#else +S6 s6; +// expected-error@second.h:* {{'Method::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' is not inline}} +// expected-note@first.h:* {{but in 'FirstModule' found method 'A' is inline}} +#endif + +#if defined(FIRST) +struct S7 { + void A() volatile {} + void A() {} +}; +#elif defined(SECOND) +struct S7 { + void A() {} + void A() volatile {} +}; +#else +S7 s7; +// expected-error@second.h:* {{'Method::S7' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' is not volatile}} +// expected-note@first.h:* {{but in 'FirstModule' found method 'A' is volatile}} +#endif + +#if defined(FIRST) +struct S8 { + void A() const {} + void A() {} +}; +#elif defined(SECOND) +struct S8 { + void A() {} + void A() const {} +}; +#else +S8 s8; +// expected-error@second.h:* {{'Method::S8' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' is not const}} +// expected-note@first.h:* {{but in 'FirstModule' found method 'A' is const}} +#endif + +} // namespace Method + +// Naive parsing of AST can lead to cycles in processing. Ensure +// self-references don't trigger an endless cycles of AST node processing. +namespace SelfReference { +#if defined(FIRST) +template <template <int> class T> class Wrapper {}; + +template <int N> class S { + S(Wrapper<::SelfReference::S> &Ref) {} +}; + +struct Xx { + struct Yy { + }; +}; + +Xx::Xx::Xx::Yy yy; + +namespace NNS { +template <typename> struct Foo; +template <template <class> class T = NNS::Foo> +struct NestedNamespaceSpecifier {}; +} +#endif +} // namespace SelfReference + +namespace TypeDef { +#if defined(FIRST) +struct S1 { + typedef int a; +}; +#elif defined(SECOND) +struct S1 { + typedef double a; +}; +#else +S1 s1; +// expected-error@first.h:* {{'TypeDef::S1::a' from module 'FirstModule' is not present in definition of 'TypeDef::S1' in module 'SecondModule'}} +// expected-note@second.h:* {{declaration of 'a' does not match}} +#endif + +#if defined(FIRST) +struct S2 { + typedef int a; +}; +#elif defined(SECOND) +struct S2 { + typedef int b; +}; +#else +S2 s2; +// expected-error@first.h:* {{'TypeDef::S2::a' from module 'FirstModule' is not present in definition of 'TypeDef::S2' in module 'SecondModule'}} +// expected-note@second.h:* {{definition has no member 'a'}} +#endif + +#if defined(FIRST) +typedef int T; +struct S3 { + typedef T a; +}; +#elif defined(SECOND) +typedef double T; +struct S3 { + typedef T a; +}; +#else +S3 s3; +// expected-error@first.h:* {{'TypeDef::S3::a' from module 'FirstModule' is not present in definition of 'TypeDef::S3' in module 'SecondModule'}} +// expected-note@second.h:* {{declaration of 'a' does not match}} +#endif +} // namespace TypeDef + +namespace Using { +#if defined(FIRST) +struct S1 { + using a = int; +}; +#elif defined(SECOND) +struct S1 { + using a = double; +}; +#else +S1 s1; +// expected-error@first.h:* {{'Using::S1::a' from module 'FirstModule' is not present in definition of 'Using::S1' in module 'SecondModule'}} +// expected-note@second.h:* {{declaration of 'a' does not match}} +#endif + +#if defined(FIRST) +struct S2 { + using a = int; +}; +#elif defined(SECOND) +struct S2 { + using b = int; +}; +#else +S2 s2; +// expected-error@first.h:* {{'Using::S2::a' from module 'FirstModule' is not present in definition of 'Using::S2' in module 'SecondModule'}} +// expected-note@second.h:* {{definition has no member 'a'}} +#endif + +#if defined(FIRST) +typedef int T; +struct S3 { + using a = T; +}; +#elif defined(SECOND) +typedef double T; +struct S3 { + using a = T; +}; +#else +S3 s3; +// expected-error@first.h:* {{'Using::S3::a' from module 'FirstModule' is not present in definition of 'Using::S3' in module 'SecondModule'}} +// expected-note@second.h:* {{declaration of 'a' does not match}} +#endif +} // namespace Using + + +// Interesting cases that should not cause errors. struct S should not error +// while struct T should error at the access specifier mismatch at the end. +namespace AllDecls { +#if defined(FIRST) +typedef int INT; +struct S { + public: + private: + protected: + + static_assert(1 == 1, "Message"); + static_assert(2 == 2); + + int x; + double y; + + INT z; + + unsigned a : 1; + unsigned b : 2*2 + 5/2; + + mutable int c = sizeof(x + y); + + void method() {} + static void static_method() {} + virtual void virtual_method() {} + virtual void pure_virtual_method() = 0; + inline void inline_method() {} + void volatile_method() volatile {} + void const_method() const {} + + typedef int typedef_int; + using using_int = int; +}; +#elif defined(SECOND) +typedef int INT; +struct S { + public: + private: + protected: + + static_assert(1 == 1, "Message"); + static_assert(2 == 2); + + int x; + double y; + + INT z; + + unsigned a : 1; + unsigned b : 2 * 2 + 5 / 2; + + mutable int c = sizeof(x + y); + + void method() {} + static void static_method() {} + virtual void virtual_method() {} + virtual void pure_virtual_method() = 0; + inline void inline_method() {} + void volatile_method() volatile {} + void const_method() const {} + + typedef int typedef_int; + using using_int = int; +}; +#else +S *s; +#endif + +#if defined(FIRST) +typedef int INT; +struct T { + public: + private: + protected: + + static_assert(1 == 1, "Message"); + static_assert(2 == 2); + + int x; + double y; + + INT z; + + unsigned a : 1; + unsigned b : 2 * 2 + 5 / 2; + + mutable int c = sizeof(x + y); + + void method() {} + static void static_method() {} + virtual void virtual_method() {} + virtual void pure_virtual_method() = 0; + inline void inline_method() {} + void volatile_method() volatile {} + void const_method() const {} + + typedef int typedef_int; + using using_int = int; + + private: +}; +#elif defined(SECOND) +typedef int INT; +struct T { + public: + private: + protected: + + static_assert(1 == 1, "Message"); + static_assert(2 == 2); + + int x; + double y; + + INT z; + + unsigned a : 1; + unsigned b : 2 * 2 + 5 / 2; + + mutable int c = sizeof(x + y); + + void method() {} + static void static_method() {} + virtual void virtual_method() {} + virtual void pure_virtual_method() = 0; + inline void inline_method() {} + void volatile_method() volatile {} + void const_method() const {} + + typedef int typedef_int; + using using_int = int; + + public: +}; +#else +T *t; +// expected-error@second.h:* {{'AllDecls::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}} +// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}} +#endif +} + +namespace FriendFunction { +#if defined(FIRST) +void F(int = 0); +struct S { friend void F(int); }; +#elif defined(SECOND) +void F(int); +struct S { friend void F(int); }; +#else +S s; +#endif + +#if defined(FIRST) +void G(int = 0); +struct T { + friend void G(int); + + private: +}; +#elif defined(SECOND) +void G(int); +struct T { + friend void G(int); + + public: +}; +#else +T t; +// expected-error@second.h:* {{'FriendFunction::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}} +// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}} +#endif +} // namespace FriendFunction + +namespace ImplicitDecl { +#if defined(FIRST) +struct S { }; +void S_Constructors() { + // Trigger creation of implicit contructors + S foo; + S bar = foo; + S baz(bar); +} +#elif defined(SECOND) +struct S { }; +#else +S s; +#endif + +#if defined(FIRST) +struct T { + private: +}; +void T_Constructors() { + // Trigger creation of implicit contructors + T foo; + T bar = foo; + T baz(bar); +} +#elif defined(SECOND) +struct T { + public: +}; +#else +T t; +// expected-error@first.h:* {{'ImplicitDecl::T' has different definitions in different modules; first difference is definition in module 'FirstModule' found private access specifier}} +// expected-note@second.h:* {{but in 'SecondModule' found public access specifier}} +#endif + +} // namespace ImplicitDelc + +namespace TemplatedClass { +#if defined(FIRST) +template <class> +struct S {}; +#elif defined(SECOND) +template <class> +struct S {}; +#else +S<int> s; +#endif + +#if defined(FIRST) +template <class> +struct T { + private: +}; +#elif defined(SECOND) +template <class> +struct T { + public: +}; +#else +T<int> t; +// expected-error@second.h:* {{'TemplatedClass::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}} +// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}} +#endif +} // namespace TemplatedClass + +namespace TemplateClassWithField { +#if defined(FIRST) +template <class A> +struct S { + A a; +}; +#elif defined(SECOND) +template <class A> +struct S { + A a; +}; +#else +S<int> s; +#endif + +#if defined(FIRST) +template <class A> +struct T { + A a; + + private: +}; +#elif defined(SECOND) +template <class A> +struct T { + A a; + + public: +}; +#else +T<int> t; +// expected-error@second.h:* {{'TemplateClassWithField::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}} +// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}} +#endif +} // namespace TemplateClassWithField + +namespace TemplateClassWithTemplateField { +#if defined(FIRST) +template <class A> +class WrapperS; +template <class A> +struct S { + WrapperS<A> a; +}; +#elif defined(SECOND) +template <class A> +class WrapperS; +template <class A> +struct S { + WrapperS<A> a; +}; +#else +template <class A> +class WrapperS{}; +S<int> s; +#endif + +#if defined(FIRST) +template <class A> +class WrapperT; +template <class A> +struct T { + WrapperT<A> a; + + public: +}; +#elif defined(SECOND) +template <class A> +class WrapperT; +template <class A> +struct T { + WrapperT<A> a; + + private: +}; +#else +template <class A> +class WrapperT{}; +T<int> t; +// expected-error@second.h:* {{'TemplateClassWithTemplateField::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}} +// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}} +#endif +} // namespace TemplateClassWithTemplateField + +namespace EnumWithForwardDeclaration { +#if defined(FIRST) +enum E : int; +struct S { + void get(E) {} +}; +#elif defined(SECOND) +enum E : int { A, B }; +struct S { + void get(E) {} +}; +#else +S s; +#endif + +#if defined(FIRST) +struct T { + void get(E) {} + public: +}; +#elif defined(SECOND) +struct T { + void get(E) {} + private: +}; +#else +T t; +// expected-error@second.h:* {{'EnumWithForwardDeclaration::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}} +// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}} +#endif +} // namespace EnumWithForwardDeclaration + +namespace StructWithForwardDeclaration { +#if defined(FIRST) +struct P {}; +struct S { + struct P *ptr; +}; +#elif defined(SECOND) +struct S { + struct P *ptr; +}; +#else +S s; +#endif + +#if defined(FIRST) +struct Q {}; +struct T { + struct Q *ptr; + public: +}; +#elif defined(SECOND) +struct T { + struct Q *ptr; + private: +}; +#else +T t; +// expected-error@second.h:* {{'StructWithForwardDeclaration::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}} +// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}} +#endif +} // namespace StructWithForwardDeclaration + +namespace StructWithForwardDeclarationNoDefinition { +#if defined(FIRST) +struct P; +struct S { + struct P *ptr; +}; +#elif defined(SECOND) +struct S { + struct P *ptr; +}; +#else +S s; +#endif + +#if defined(FIRST) +struct Q; +struct T { + struct Q *ptr; + + public: +}; +#elif defined(SECOND) +struct T { + struct Q *ptr; + + private: +}; +#else +T t; +// expected-error@second.h:* {{'StructWithForwardDeclarationNoDefinition::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}} +// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}} +#endif +} // namespace StructWithForwardDeclarationNoDefinition + +// Keep macros contained to one file. +#ifdef FIRST +#undef FIRST +#endif +#ifdef SECOND +#undef SECOND +#endif diff --git a/test/Modules/outofdate-rebuild.m b/test/Modules/outofdate-rebuild.m new file mode 100644 index 0000000000000..510325f62dcb2 --- /dev/null +++ b/test/Modules/outofdate-rebuild.m @@ -0,0 +1,15 @@ +// RUN: rm -rf %t.cache +// RUN: echo "@import CoreText;" > %t.m +// RUN: %clang_cc1 -fdisable-module-hash -fmodules-cache-path=%t.cache \ +// RUN: -fmodules -fimplicit-module-maps -I%S/Inputs/outofdate-rebuild %s \ +// RUN: -fsyntax-only +// RUN: %clang_cc1 -DMISMATCH -Werror -fdisable-module-hash \ +// RUN: -fmodules-cache-path=%t.cache -fmodules -fimplicit-module-maps \ +// RUN: -I%S/Inputs/outofdate-rebuild %t.m -fsyntax-only +// RUN: %clang_cc1 -fdisable-module-hash -fmodules-cache-path=%t.cache \ +// RUN: -fmodules -fimplicit-module-maps -I%S/Inputs/outofdate-rebuild %s \ +// RUN: -fsyntax-only + +// This testcase reproduces a use-after-free in when ModuleManager removes an +// entry from the PCMCache without notifying its parent ASTReader. +@import Cocoa; diff --git a/test/Modules/overloadable-attrs.cpp b/test/Modules/overloadable-attrs.cpp new file mode 100644 index 0000000000000..38c9558fe8821 --- /dev/null +++ b/test/Modules/overloadable-attrs.cpp @@ -0,0 +1,22 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -I%S/Inputs/overloadable-attrs -fmodules \ +// RUN: -fmodule-map-file=%S/Inputs/overloadable-attrs/module.modulemap \ +// RUN: -fmodules-cache-path=%t -verify %s -std=c++11 +// +// Ensures that we don't merge decls with attrs that we allow overloading on. +// +// expected-no-diagnostics + +#include "a.h" + +static_assert(enable_if_attrs::fn1() == 1, ""); +static_assert(enable_if_attrs::fn2() == 1, ""); +static_assert(enable_if_attrs::fn3(0) == 0, ""); +static_assert(enable_if_attrs::fn3(1) == 1, ""); +static_assert(enable_if_attrs::fn4(0) == 0, ""); +static_assert(enable_if_attrs::fn4(1) == 1, ""); +static_assert(enable_if_attrs::fn5(0) == 0, ""); +static_assert(enable_if_attrs::fn5(1) == 1, ""); + +static_assert(pass_object_size_attrs::fn1(nullptr) == 1, ""); +static_assert(pass_object_size_attrs::fn2(nullptr) == 1, ""); diff --git a/test/Modules/pragma-pack.cpp b/test/Modules/pragma-pack.cpp new file mode 100644 index 0000000000000..96a880c6307b0 --- /dev/null +++ b/test/Modules/pragma-pack.cpp @@ -0,0 +1,25 @@ +// RUN: rm -rf %t.cache %tlocal.cache +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fmodules \ +// RUN: -fimplicit-module-maps -x c++ -emit-module \ +// RUN: -fmodules-cache-path=%t.cache \ +// RUN: -fmodule-name=pragma_pack %S/Inputs/module.map +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fmodules \ +// RUN: -fimplicit-module-maps -x c++ -verify \ +// RUN: -fmodules-cache-path=%t.cache \ +// RUN: -I%S/Inputs %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fmodules \ +// RUN: -fmodules-local-submodule-visibility \ +// RUN: -fimplicit-module-maps -x c++ -emit-module \ +// RUN: -fmodules-cache-path=%tlocal.cache \ +// RUN: -fmodule-name=pragma_pack %S/Inputs/module.map +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fmodules \ +// RUN: -fmodules-local-submodule-visibility \ +// RUN: -fimplicit-module-maps -x c++ -verify \ +// RUN: -fmodules-cache-path=%tlocal.cache \ +// RUN: -I%S/Inputs %s + +// Check that we don't serialize pragma pack state until/unless including an +// empty file from the same module (but different submodule) has no effect. +#pragma pack (show) // expected-warning {{value of #pragma pack(show) == 8}} +#include "empty.h" +#pragma pack (show) // expected-warning {{value of #pragma pack(show) == 8}} diff --git a/test/Modules/rebuild.m b/test/Modules/rebuild.m index 40f2d47e09e82..150c2ce266e49 100644 --- a/test/Modules/rebuild.m +++ b/test/Modules/rebuild.m @@ -19,11 +19,10 @@ // RUN: diff %t/Module.size %t/Module.size.saved // RUN: cp %t/Module.pcm %t/Module.pcm.saved.2 -// But the signature at least is expected to change, so we rebuild DependsOnModule. -// NOTE: if we change how the signature is created, this test may need updating. +// The signature is the hash of the PCM content, we will not rebuild rebuild DependsOnModule. // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -fdisable-module-hash -fsyntax-only -F %S/Inputs %s // RUN: diff %t/Module.pcm %t/Module.pcm.saved.2 -// RUN: not diff %t/DependsOnModule.pcm %t/DependsOnModule.pcm.saved +// RUN: diff %t/DependsOnModule.pcm %t/DependsOnModule.pcm.saved // Rebuild Module, reset its timestamp, and verify its size hasn't changed // RUN: rm %t/Module.pcm @@ -34,10 +33,9 @@ // RUN: cp %t/Module.pcm %t/Module.pcm.saved.2 // Verify again with Module pre-imported. -// NOTE: if we change how the signature is created, this test may need updating. // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -fdisable-module-hash -fsyntax-only -F %S/Inputs %s // RUN: diff %t/Module.pcm %t/Module.pcm.saved.2 -// RUN: not diff %t/DependsOnModule.pcm %t/DependsOnModule.pcm.saved +// RUN: diff %t/DependsOnModule.pcm %t/DependsOnModule.pcm.saved #ifdef PREIMPORT @import Module; diff --git a/test/Modules/system-out-of-date-test.m b/test/Modules/system-out-of-date-test.m new file mode 100644 index 0000000000000..e78df7b3b3e71 --- /dev/null +++ b/test/Modules/system-out-of-date-test.m @@ -0,0 +1,17 @@ +// RUN: rm -rf %t.cache +// RUN: echo '@import X;' | \ +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps \ +// RUN: -fmodules-cache-path=%t.cache -I%S/Inputs/system-out-of-date \ +// RUN: -fsyntax-only -x objective-c - +// +// Build something with different diagnostic options. +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps \ +// RUN: -fmodules-cache-path=%t.cache -I%S/Inputs/system-out-of-date \ +// RUN: -fsyntax-only %s -Wnon-modular-include-in-framework-module \ +// RUN: -Werror=non-modular-include-in-framework-module 2>&1 \ +// RUN: | FileCheck %s +@import X; + +#import <Z.h> +// CHECK: While building module 'Z' imported from +// CHECK: {{.*}}Y-{{.*}}pcm' was validated as a system module and is now being imported as a non-system module diff --git a/test/Modules/system_version.m b/test/Modules/system_version.m deleted file mode 100644 index b1bc3609272e4..0000000000000 --- a/test/Modules/system_version.m +++ /dev/null @@ -1,31 +0,0 @@ -// Test checking that we're hashing a system version file in the -// module hash. - -// First, build a system root. -// RUN: rm -rf %t -// RUN: mkdir -p %t/usr/include -// RUN: cp %S/Inputs/Modified/A.h %t/usr/include -// RUN: cp %S/Inputs/Modified/B.h %t/usr/include -// RUN: cp %S/Inputs/Modified/module.map %t/usr/include - -// Run once with no system version file. We should end up with one module. -// RUN: %clang_cc1 -fmodules-cache-path=%t/cache -fmodules -fimplicit-module-maps -isysroot %t -I %t/usr/include %s -verify -// RUN: ls -R %t | grep -c "ModA.*pcm" | grep 1 - -// Add a system version file and run again. We should now have two -// module variants. -// RUN: mkdir -p %t/System/Library/CoreServices -// RUN: echo "hello" > %t/System/Library/CoreServices/SystemVersion.plist -// RUN: %clang_cc1 -fmodules-cache-path=%t/cache -fmodules -fimplicit-module-maps -isysroot %t -I %t/usr/include %s -verify -// RUN: ls -R %t | grep -c "ModA.*pcm" | grep 2 - -// Change the system version file and run again. We should now have three -// module variants. -// RUN: mkdir -p %t/System/Library/CoreServices -// RUN: echo "modules" > %t/System/Library/CoreServices/SystemVersion.plist -// RUN: %clang_cc1 -fmodules-cache-path=%t/cache -fmodules -fimplicit-module-maps -isysroot %t -I %t/usr/include %s -verify -// RUN: ls -R %t | grep -c "ModA.*pcm" | grep 3 - -// expected-no-diagnostics -@import ModA; - diff --git a/test/Modules/warning-mismatch.m b/test/Modules/warning-mismatch.m new file mode 100644 index 0000000000000..dd7c7f82ec696 --- /dev/null +++ b/test/Modules/warning-mismatch.m @@ -0,0 +1,13 @@ +// RUN: rm -rf %t.cache +// RUN: echo "@import Mismatch;" >%t.m +// RUN: %clang_cc1 -Wno-system-headers -fdisable-module-hash \ +// RUN: -fmodules-cache-path=%t.cache -fmodules -fimplicit-module-maps \ +// RUN: -I%S/Inputs/warning-mismatch %t.m -fsyntax-only +// RUN: %clang_cc1 -Wsystem-headers -fdisable-module-hash \ +// RUN: -fmodules-cache-path=%t.cache -fmodules -fimplicit-module-maps \ +// RUN: -I%S/Inputs/warning-mismatch %s -fsyntax-only + +// This testcase triggers a warning flag mismatch in an already validated +// header. +@import Mismatch; +@import System; |