summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2018-08-02 17:33:11 +0000
committerDimitry Andric <dim@FreeBSD.org>2018-08-02 17:33:11 +0000
commitc7e70c433efc6953dc3888b9fbf9f3512d7da2b0 (patch)
tree27425930fc0c91650a7f3527fcac8e0f92907b90 /test
parent486754660bb926339aefcf012a3f848592babb8b (diff)
downloadsrc-test2-c7e70c433efc6953dc3888b9fbf9f3512d7da2b0.tar.gz
src-test2-c7e70c433efc6953dc3888b9fbf9f3512d7da2b0.zip
Notes
Diffstat (limited to 'test')
-rw-r--r--test/Analysis/Checkers/RunLoopAutoreleaseLeakChecker.m22
-rw-r--r--test/Analysis/casts.c7
-rw-r--r--test/Analysis/cfg-rich-constructors.cpp75
-rw-r--r--test/Analysis/cfg-rich-constructors.mm66
-rw-r--r--test/Analysis/copy-elision.cpp (renamed from test/Analysis/cxx17-mandatory-elision.cpp)0
-rw-r--r--test/Analysis/cstring-ranges.c15
-rw-r--r--test/Analysis/inner-pointer.cpp94
-rw-r--r--test/Analysis/lifetime-extension.mm64
-rw-r--r--test/Analysis/temporaries.cpp49
-rw-r--r--test/Analysis/temporaries.mm23
-rw-r--r--test/CodeGen/aapcs-align.cc141
-rw-r--r--test/CodeGen/aapcs64-align.cc103
-rw-r--r--test/CodeGen/arm-arguments.c17
-rw-r--r--test/CodeGen/builtin-memfns.c17
-rw-r--r--test/CodeGen/catch-implicit-integer-truncations.c395
-rw-r--r--test/CodeGen/exceptions-seh-finally.c1
-rw-r--r--test/CodeGen/exceptions-seh.c14
-rw-r--r--test/CodeGen/mips-unsigned-ext-var.c6
-rw-r--r--test/CodeGen/mips-varargs.c8
-rw-r--r--test/CodeGen/mips-vector-arg.c4
-rw-r--r--test/CodeGenCUDA/device-var-init.cu6
-rw-r--r--test/CodeGenCXX/Inputs/override-layout-nameless-struct-union.layout16
-rw-r--r--test/CodeGenCXX/Inputs/override-layout-packed-base.layout18
-rw-r--r--test/CodeGenCXX/castexpr-basepathsize-threshold.cpp27
-rw-r--r--test/CodeGenCXX/catch-implicit-integer-truncations.cpp256
-rw-r--r--test/CodeGenCXX/ctor-dtor-alias.cpp41
-rw-r--r--test/CodeGenCXX/float16-declarations.cpp2
-rw-r--r--test/CodeGenCXX/override-layout-nameless-struct-union.cpp33
-rw-r--r--test/CodeGenCXX/override-layout-packed-base.cpp26
-rw-r--r--test/CodeGenCXX/ubsan-new-checks.cpp146
-rw-r--r--test/CodeGenOpenCL/blocks.cl12
-rw-r--r--test/CodeGenOpenCL/builtins-amdgcn-dl-insts-err-clamp.cl25
-rw-r--r--test/CodeGenOpenCL/builtins-amdgcn-dl-insts-err.cl24
-rw-r--r--test/CodeGenOpenCL/builtins-amdgcn-dl-insts.cl48
-rwxr-xr-xtest/Driver/Inputs/basic_riscv32_tree/bin/riscv32-unknown-elf-ld1
-rw-r--r--test/Driver/Inputs/basic_riscv32_tree/lib/gcc/riscv32-unknown-elf/8.0.1/crtbegin.o (renamed from test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.asan_ios_dynamic.dylib)0
-rw-r--r--test/Driver/Inputs/basic_riscv32_tree/lib/gcc/riscv32-unknown-elf/8.0.1/crtend.o (renamed from test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.asan_iossim_dynamic.dylib)0
-rw-r--r--test/Driver/Inputs/basic_riscv32_tree/riscv32-unknown-elf/include/c++/8.0.1/.keep (renamed from test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.asan_osx_dynamic.dylib)0
-rw-r--r--test/Driver/Inputs/basic_riscv32_tree/riscv32-unknown-elf/lib/crt0.o (renamed from test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.asan_tvos_dynamic.dylib)0
-rw-r--r--test/Driver/Inputs/openembedded_aarch64_linux_tree/usr/include/c++/6.3.0/backward/.keep (renamed from test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.asan_tvossim_dynamic.dylib)0
-rw-r--r--test/Driver/Inputs/openembedded_aarch64_linux_tree/usr/lib64/aarch64-oe-linux/6.3.0/crtbegin.o (renamed from test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.asan_watchos_dynamic.dylib)0
-rw-r--r--test/Driver/Inputs/openembedded_aarch64_linux_tree/usr/lib64/aarch64-oe-linux/6.3.0/crtend.o (renamed from test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.asan_watchossim_dynamic.dylib)0
-rw-r--r--test/Driver/Inputs/openembedded_aarch64_linux_tree/usr/lib64/crt1.o (renamed from test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.fuzzer_osx.a)0
-rw-r--r--test/Driver/Inputs/openembedded_aarch64_linux_tree/usr/lib64/crti.o (renamed from test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.lsan_ios_dynamic.dylib)0
-rw-r--r--test/Driver/Inputs/openembedded_aarch64_linux_tree/usr/lib64/crtn.o (renamed from test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.lsan_iossim_dynamic.dylib)0
-rw-r--r--test/Driver/Inputs/openembedded_arm_linux_tree/usr/include/c++/6.3.0/backward/.keep (renamed from test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.lsan_osx_dynamic.dylib)0
-rw-r--r--test/Driver/Inputs/openembedded_arm_linux_tree/usr/lib/arm-oe-linux-gnueabi/6.3.0/crtbegin.o (renamed from test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.lsan_tvossim_dynamic.dylib)0
-rw-r--r--test/Driver/Inputs/openembedded_arm_linux_tree/usr/lib/arm-oe-linux-gnueabi/6.3.0/crtend.o (renamed from test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.tsan_iossim_dynamic.dylib)0
-rw-r--r--test/Driver/Inputs/openembedded_arm_linux_tree/usr/lib/crt1.o (renamed from test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.tsan_osx_dynamic.dylib)0
-rw-r--r--test/Driver/Inputs/openembedded_arm_linux_tree/usr/lib/crti.o (renamed from test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.tsan_tvossim_dynamic.dylib)0
-rw-r--r--test/Driver/Inputs/openembedded_arm_linux_tree/usr/lib/crtn.o0
-rw-r--r--test/Driver/aarch64-cpus.c73
-rw-r--r--test/Driver/arm-cortex-cpus.c49
-rw-r--r--test/Driver/baremetal.cpp10
-rw-r--r--test/Driver/cuda-dwarf-2.cu3
-rw-r--r--test/Driver/cuda-unsupported-debug-options.cu22
-rw-r--r--test/Driver/darwin-asan-nofortify.c2
-rw-r--r--test/Driver/darwin-sanitizer-ld.c19
-rw-r--r--test/Driver/fsanitize.c43
-rw-r--r--test/Driver/fuzzer.c10
-rw-r--r--test/Driver/linux-header-search.cpp22
-rw-r--r--test/Driver/linux-ld.c38
-rw-r--r--test/Driver/openmp-offload-gpu.c3
-rw-r--r--test/Driver/openmp-unsupported-debug-options.c22
-rw-r--r--test/Driver/riscv32-toolchain.c30
-rw-r--r--test/Driver/sanitizer-ld.c3
-rw-r--r--test/Frontend/clang-abi-compat.cpp2
-rw-r--r--test/Index/complete-access-checks-crash.cpp13
-rw-r--r--test/Modules/resolution-change.m2
-rw-r--r--test/OpenMP/declare_target_codegen.cpp9
-rw-r--r--test/OpenMP/nvptx_declare_target_var_ctor_dtor_codegen.cpp2
-rw-r--r--test/OpenMP/target_codegen.cpp4
-rw-r--r--test/OpenMP/target_codegen_registration.cpp4
-rw-r--r--test/OpenMP/target_depend_codegen.cpp4
-rw-r--r--test/OpenMP/target_parallel_codegen.cpp4
-rw-r--r--test/OpenMP/target_parallel_codegen_registration.cpp4
-rw-r--r--test/OpenMP/target_parallel_depend_codegen.cpp4
-rw-r--r--test/OpenMP/target_parallel_for_codegen.cpp4
-rw-r--r--test/OpenMP/target_parallel_for_codegen_registration.cpp4
-rw-r--r--test/OpenMP/target_parallel_for_depend_codegen.cpp4
-rw-r--r--test/OpenMP/target_parallel_for_simd_codegen.cpp4
-rw-r--r--test/OpenMP/target_parallel_for_simd_codegen_registration.cpp4
-rw-r--r--test/OpenMP/target_parallel_for_simd_depend_codegen.cpp4
-rw-r--r--test/OpenMP/target_parallel_if_codegen.cpp4
-rw-r--r--test/OpenMP/target_parallel_num_threads_codegen.cpp4
-rw-r--r--test/OpenMP/target_simd_codegen.cpp4
-rw-r--r--test/OpenMP/target_simd_codegen_registration.cpp4
-rw-r--r--test/OpenMP/target_simd_depend_codegen.cpp4
-rw-r--r--test/OpenMP/target_teams_codegen.cpp4
-rw-r--r--test/OpenMP/target_teams_codegen_registration.cpp4
-rw-r--r--test/OpenMP/target_teams_depend_codegen.cpp4
-rw-r--r--test/OpenMP/target_teams_distribute_codegen.cpp4
-rw-r--r--test/OpenMP/target_teams_distribute_codegen_registration.cpp4
-rw-r--r--test/OpenMP/target_teams_distribute_depend_codegen.cpp4
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_depend_codegen.cpp4
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_simd_codegen_registration.cpp4
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_simd_depend_codegen.cpp4
-rw-r--r--test/OpenMP/target_teams_distribute_simd_codegen.cpp4
-rw-r--r--test/OpenMP/target_teams_distribute_simd_codegen_registration.cpp4
-rw-r--r--test/OpenMP/target_teams_distribute_simd_depend_codegen.cpp4
-rw-r--r--test/OpenMP/target_teams_num_teams_codegen.cpp4
-rw-r--r--test/OpenMP/target_teams_thread_limit_codegen.cpp4
-rw-r--r--test/PCH/coroutines.cpp8
-rw-r--r--test/PCH/cxx-templates.cpp16
-rw-r--r--test/PCH/cxx-templates.h35
-rw-r--r--test/Parser/cxx1z-fold-expressions.cpp26
-rw-r--r--test/SemaCUDA/device-var-init.cu13
-rw-r--r--test/SemaCXX/attr-lifetimebound.cpp115
-rw-r--r--test/SemaCXX/constexpr-string.cpp148
-rw-r--r--test/SemaCXX/cxx1z-class-template-argument-deduction.cpp29
-rw-r--r--test/SemaCXX/warn-dangling-local.cpp6
-rw-r--r--test/SemaObjCXX/class-templ-error-null-init.mm7
-rw-r--r--test/SemaObjCXX/noescape.mm39
-rw-r--r--test/SemaOpenCL/invalid-kernel-parameters.cl43
114 files changed, 2566 insertions, 222 deletions
diff --git a/test/Analysis/Checkers/RunLoopAutoreleaseLeakChecker.m b/test/Analysis/Checkers/RunLoopAutoreleaseLeakChecker.m
index 4dde40e210a0..b00d71b1a4d0 100644
--- a/test/Analysis/Checkers/RunLoopAutoreleaseLeakChecker.m
+++ b/test/Analysis/Checkers/RunLoopAutoreleaseLeakChecker.m
@@ -29,6 +29,17 @@ void runloop_init_before() { // Warning: object created before the loop.
}
}
+void runloop_init_before_separate_pool() { // No warning: separate autorelease pool.
+ @autoreleasepool {
+ NSObject *object;
+ @autoreleasepool {
+ object = [[NSObject alloc] init]; // no-warning
+ }
+ (void) object;
+ [[NSRunLoop mainRunLoop] run];
+ }
+}
+
void xpcmain_init_before() { // Warning: object created before the loop.
@autoreleasepool {
NSObject *object = [[NSObject alloc] init]; // expected-warning{{Temporary objects allocated in the autorelease pool followed by the launch of xpc_main may never get released; consider moving them to a separate autorelease pool}}
@@ -43,7 +54,7 @@ void runloop_init_before_two_objects() { // Warning: object created before the l
NSObject *object2 = [[NSObject alloc] init]; // no-warning, warning on the first one is enough.
(void) object;
(void) object2;
- [[NSRunLoop mainRunLoop] run];
+ [[NSRunLoop mainRunLoop] run];
}
}
@@ -61,6 +72,15 @@ void runloop_init_after() { // No warning: objects created after the loop
}
}
+void no_crash_on_empty_children() {
+ @autoreleasepool {
+ for (;;) {}
+ NSObject *object = [[NSObject alloc] init]; // expected-warning{{Temporary objects allocated in the autorelease pool followed by the launch of main run loop may never get released; consider moving them to a separate autorelease pool}}
+ [[NSRunLoop mainRunLoop] run];
+ (void) object;
+ }
+}
+
#endif
#ifdef AP1
diff --git a/test/Analysis/casts.c b/test/Analysis/casts.c
index eccb67812a02..86fb7da58ec2 100644
--- a/test/Analysis/casts.c
+++ b/test/Analysis/casts.c
@@ -175,3 +175,10 @@ void testCastVoidPtrToIntPtrThroughUIntTypedAssignment() {
void testLocNonLocSymbolAssume(int a, int *b) {
if ((int)b < a) {} // no-crash
}
+
+void testLocNonLocSymbolRemainder(int a, int *b) {
+ int c = ((int)b) % a;
+ if (a == 1) {
+ c += 1;
+ }
+}
diff --git a/test/Analysis/cfg-rich-constructors.cpp b/test/Analysis/cfg-rich-constructors.cpp
index 6780cf1a7be9..88b03788da43 100644
--- a/test/Analysis/cfg-rich-constructors.cpp
+++ b/test/Analysis/cfg-rich-constructors.cpp
@@ -817,25 +817,58 @@ public:
~D();
};
+class E {
+public:
+ E(D d);
+};
+
void useC(C c);
void useCByReference(const C &c);
void useD(D d);
void useDByReference(const D &d);
+void useCAndD(C c, D d);
-// FIXME: Find construction context for the argument.
// CHECK: void passArgument()
// CHECK: 1: useC
// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(class C))
-// CXX11-NEXT: 3: C() (CXXConstructExpr, [B1.4], class C)
+// CXX11-ELIDE-NEXT: 3: C() (CXXConstructExpr, [B1.4], [B1.5], class C)
+// CXX11-NOELIDE-NEXT: 3: C() (CXXConstructExpr, [B1.4], class C)
// CXX11-NEXT: 4: [B1.3]
-// CXX11-NEXT: 5: [B1.4] (CXXConstructExpr, class C)
+// CXX11-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.6]+0, class C)
// CXX11-NEXT: 6: [B1.2]([B1.5])
-// CXX17-NEXT: 3: C() (CXXConstructExpr, class C)
+// CXX17-NEXT: 3: C() (CXXConstructExpr, [B1.4]+0, class C)
// CXX17-NEXT: 4: [B1.2]([B1.3])
void passArgument() {
useC(C());
}
+// CHECK: void passTwoArguments()
+// CHECK: [B1]
+// CHECK-NEXT: 1: useCAndD
+// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(class C, class argument_constructors::D))
+// CXX11-ELIDE-NEXT: 3: C() (CXXConstructExpr, [B1.4], [B1.5], class C)
+// CXX11-NOELIDE-NEXT: 3: C() (CXXConstructExpr, [B1.4], class C)
+// CXX11-NEXT: 4: [B1.3]
+// CXX11-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.12]+0, class C)
+// CXX11-ELIDE-NEXT: 6: argument_constructors::D() (CXXConstructExpr, [B1.7], [B1.9], [B1.10], class argument_constructors::D)
+// CXX11-NOELIDE-NEXT: 6: argument_constructors::D() (CXXConstructExpr, [B1.7], [B1.9], class argument_constructors::D)
+// CXX11-NEXT: 7: [B1.6] (BindTemporary)
+// CXX11-NEXT: 8: [B1.7] (ImplicitCastExpr, NoOp, const class argument_constructors::D)
+// CXX11-NEXT: 9: [B1.8]
+// CXX11-NEXT: 10: [B1.9] (CXXConstructExpr, [B1.11], [B1.12]+1, class argument_constructors::D)
+// CXX11-NEXT: 11: [B1.10] (BindTemporary)
+// CXX11-NEXT: 12: [B1.2]([B1.5], [B1.11])
+// CXX11-NEXT: 13: ~argument_constructors::D() (Temporary object destructor)
+// CXX11-NEXT: 14: ~argument_constructors::D() (Temporary object destructor)
+// CXX17-NEXT: 3: C() (CXXConstructExpr, [B1.6]+0, class C)
+// CXX17-NEXT: 4: argument_constructors::D() (CXXConstructExpr, [B1.5], [B1.6]+1, class argument_co
+// CXX17-NEXT: 5: [B1.4] (BindTemporary)
+// CXX17-NEXT: 6: [B1.2]([B1.3], [B1.5])
+// CXX17-NEXT: 7: ~argument_constructors::D() (Temporary object destructor)
+void passTwoArguments() {
+ useCAndD(C(), D());
+}
+
// CHECK: void passArgumentByReference()
// CHECK: 1: useCByReference
// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(const class C &))
@@ -847,20 +880,20 @@ void passArgumentByReference() {
useCByReference(C());
}
-// FIXME: Find construction context for the argument.
// CHECK: void passArgumentWithDestructor()
// CHECK: 1: useD
// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(class argument_constructors::D))
-// CXX11-NEXT: 3: argument_constructors::D() (CXXConstructExpr, [B1.4], [B1.6], class argument_constructors::D)
+// CXX11-ELIDE-NEXT: 3: argument_constructors::D() (CXXConstructExpr, [B1.4], [B1.6], [B1.7], class argument_constructors::D)
+// CXX11-NOELIDE-NEXT: 3: argument_constructors::D() (CXXConstructExpr, [B1.4], [B1.6], class argument_constructors::D)
// CXX11-NEXT: 4: [B1.3] (BindTemporary)
// CXX11-NEXT: 5: [B1.4] (ImplicitCastExpr, NoOp, const class argument_constructors::D)
// CXX11-NEXT: 6: [B1.5]
-// CXX11-NEXT: 7: [B1.6] (CXXConstructExpr, class argument_constructors::D)
+// CXX11-NEXT: 7: [B1.6] (CXXConstructExpr, [B1.8], [B1.9]+0, class argument_constructors::D)
// CXX11-NEXT: 8: [B1.7] (BindTemporary)
// CXX11-NEXT: 9: [B1.2]([B1.8])
// CXX11-NEXT: 10: ~argument_constructors::D() (Temporary object destructor)
// CXX11-NEXT: 11: ~argument_constructors::D() (Temporary object destructor)
-// CXX17-NEXT: 3: argument_constructors::D() (CXXConstructExpr, class argument_constructors::D)
+// CXX17-NEXT: 3: argument_constructors::D() (CXXConstructExpr, [B1.4], [B1.5]+0, class argument_constructors::D)
// CXX17-NEXT: 4: [B1.3] (BindTemporary)
// CXX17-NEXT: 5: [B1.2]([B1.4])
// CXX17-NEXT: 6: ~argument_constructors::D() (Temporary object destructor)
@@ -880,6 +913,32 @@ void passArgumentWithDestructor() {
void passArgumentWithDestructorByReference() {
useDByReference(D());
}
+
+// CHECK: void passArgumentIntoAnotherConstructor()
+// CXX11-ELIDE: 1: argument_constructors::D() (CXXConstructExpr, [B1.2], [B1.4], [B1.5], class argument_constructors::D)
+// CXX11-NOELIDE: 1: argument_constructors::D() (CXXConstructExpr, [B1.2], [B1.4], class argument_constructors::D)
+// CXX11-NEXT: 2: [B1.1] (BindTemporary)
+// CXX11-NEXT: 3: [B1.2] (ImplicitCastExpr, NoOp, const class argument_constructors::D)
+// CXX11-NEXT: 4: [B1.3]
+// CXX11-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.6], [B1.7]+0, class argument_constructors::D)
+// CXX11-NEXT: 6: [B1.5] (BindTemporary)
+// CXX11-ELIDE-NEXT: 7: [B1.6] (CXXConstructExpr, [B1.9], [B1.10], class argument_constructors::E)
+// CXX11-NOELIDE-NEXT: 7: [B1.6] (CXXConstructExpr, [B1.9], class argument_constructors::E)
+// CXX11-NEXT: 8: argument_constructors::E([B1.7]) (CXXFunctionalCastExpr, ConstructorConversion, class argument_constructors::E)
+// CXX11-NEXT: 9: [B1.8]
+// CXX11-NEXT: 10: [B1.9] (CXXConstructExpr, [B1.11], class argument_constructors::E)
+// CXX11-NEXT: 11: argument_constructors::E e = argument_constructors::E(argument_constructors::D());
+// CXX11-NEXT: 12: ~argument_constructors::D() (Temporary object destructor)
+// CXX11-NEXT: 13: ~argument_constructors::D() (Temporary object destructor)
+// CXX17: 1: argument_constructors::D() (CXXConstructExpr, [B1.2], [B1.3]+0, class argument_constructors::D)
+// CXX17-NEXT: 2: [B1.1] (BindTemporary)
+// CXX17-NEXT: 3: [B1.2] (CXXConstructExpr, [B1.5], class argument_constructors::E)
+// CXX17-NEXT: 4: argument_constructors::E([B1.3]) (CXXFunctionalCastExpr, ConstructorConversion, class argument_constructors::E)
+// CXX17-NEXT: 5: argument_constructors::E e = argument_constructors::E(argument_constructors::D());
+// CXX17-NEXT: 6: ~argument_constructors::D() (Temporary object destructor)
+void passArgumentIntoAnotherConstructor() {
+ E e = E(D());
+}
} // end namespace argument_constructors
namespace copy_elision_with_extra_arguments {
diff --git a/test/Analysis/cfg-rich-constructors.mm b/test/Analysis/cfg-rich-constructors.mm
new file mode 100644
index 000000000000..289094293eb5
--- /dev/null
+++ b/test/Analysis/cfg-rich-constructors.mm
@@ -0,0 +1,66 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -std=c++11 -w %s > %t 2>&1
+// RUN: FileCheck --input-file=%t -check-prefixes=CHECK,CXX11,ELIDE,CXX11-ELIDE %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -std=c++17 -w %s > %t 2>&1
+// RUN: FileCheck --input-file=%t -check-prefixes=CHECK,CXX17,ELIDE,CXX17-ELIDE %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -std=c++11 -w -analyzer-config elide-constructors=false %s > %t 2>&1
+// RUN: FileCheck --input-file=%t -check-prefixes=CHECK,CXX11,NOELIDE,CXX11-NOELIDE %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -std=c++17 -w -analyzer-config elide-constructors=false %s > %t 2>&1
+// RUN: FileCheck --input-file=%t -check-prefixes=CHECK,CXX17,NOELIDE,CXX17-NOELIDE %s
+
+class D {
+public:
+ D();
+ ~D();
+};
+
+@interface E {}
+-(void) foo: (D) d;
+-(D) bar;
+@end
+
+// CHECK: void passArgumentIntoMessage(E *e)
+// CHECK: 1: e
+// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, LValueToRValue, E *)
+// CXX11-ELIDE-NEXT: 3: D() (CXXConstructExpr, [B1.4], [B1.6], [B1.7], class D)
+// CXX11-NOELIDE-NEXT: 3: D() (CXXConstructExpr, [B1.4], [B1.6], class D)
+// CXX11-NEXT: 4: [B1.3] (BindTemporary)
+// CXX11-NEXT: 5: [B1.4] (ImplicitCastExpr, NoOp, const class D)
+// CXX11-NEXT: 6: [B1.5]
+// CXX11-NEXT: 7: [B1.6] (CXXConstructExpr, [B1.8], [B1.9]+0, class D)
+// CXX11-NEXT: 8: [B1.7] (BindTemporary)
+// Double brackets trigger FileCheck variables, escape.
+// CXX11-NEXT: 9: {{\[}}[B1.2] foo:[B1.8]]
+// CXX11-NEXT: 10: ~D() (Temporary object destructor)
+// CXX11-NEXT: 11: ~D() (Temporary object destructor)
+// CXX17-NEXT: 3: D() (CXXConstructExpr, [B1.4], [B1.5]+0, class D)
+// CXX17-NEXT: 4: [B1.3] (BindTemporary)
+// Double brackets trigger FileCheck variables, escape.
+// CXX17-NEXT: 5: {{\[}}[B1.2] foo:[B1.4]]
+// CXX17-NEXT: 6: ~D() (Temporary object destructor)
+void passArgumentIntoMessage(E *e) {
+ [e foo: D()];
+}
+
+// CHECK: void returnObjectFromMessage(E *e)
+// CHECK: [B1]
+// CHECK-NEXT: 1: e
+// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, LValueToRValue, E *)
+// Double brackets trigger FileCheck variables, escape.
+// CXX11-ELIDE-NEXT: 3: {{\[}}[B1.2] bar] (CXXRecordTypedCall, [B1.4], [B1.6], [B1.7])
+// CXX11-NOELIDE-NEXT: 3: {{\[}}[B1.2] bar] (CXXRecordTypedCall, [B1.4], [B1.6])
+// CXX11-NEXT: 4: [B1.3] (BindTemporary)
+// CXX11-NEXT: 5: [B1.4] (ImplicitCastExpr, NoOp, const class D)
+// CXX11-NEXT: 6: [B1.5]
+// CXX11-NEXT: 7: [B1.6] (CXXConstructExpr, [B1.8], class D)
+// CXX11-NEXT: 8: D d = [e bar];
+// CXX11-NEXT: 9: ~D() (Temporary object destructor)
+// CXX11-NEXT: 10: [B1.8].~D() (Implicit destructor)
+// Double brackets trigger FileCheck variables, escape.
+// CXX17-NEXT: 3: {{\[}}[B1.2] bar] (CXXRecordTypedCall, [B1.5], [B1.4])
+// CXX17-NEXT: 4: [B1.3] (BindTemporary)
+// CXX17-NEXT: 5: D d = [e bar];
+// CXX17-NEXT: 6: ~D() (Temporary object destructor)
+// CXX17-NEXT: 7: [B1.5].~D() (Implicit destructor)
+void returnObjectFromMessage(E *e) {
+ D d = [e bar];
+}
diff --git a/test/Analysis/cxx17-mandatory-elision.cpp b/test/Analysis/copy-elision.cpp
index cf77912ea6c4..cf77912ea6c4 100644
--- a/test/Analysis/cxx17-mandatory-elision.cpp
+++ b/test/Analysis/copy-elision.cpp
diff --git a/test/Analysis/cstring-ranges.c b/test/Analysis/cstring-ranges.c
new file mode 100644
index 000000000000..4fcd7eaa8bee
--- /dev/null
+++ b/test/Analysis/cstring-ranges.c
@@ -0,0 +1,15 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=unix.cstring -analyzer-output=text %s 2>&1 | FileCheck %s
+
+// This test verifies argument source range highlighting.
+// Otherwise we've no idea which of the arguments is null.
+
+char *strcpy(char *, const char *);
+
+void foo() {
+ char *a = 0, *b = 0;
+ strcpy(a, b);
+}
+
+// CHECK: warning: Null pointer argument in call to string copy function
+// CHECK-NEXT: strcpy(a, b);
+// CHECK-NEXT: ^ ~
diff --git a/test/Analysis/inner-pointer.cpp b/test/Analysis/inner-pointer.cpp
index db9bf43109b2..230e3396c59e 100644
--- a/test/Analysis/inner-pointer.cpp
+++ b/test/Analysis/inner-pointer.cpp
@@ -1,4 +1,4 @@
-//RUN: %clang_analyze_cc1 -analyzer-checker=alpha.cplusplus.InnerPointer %s -analyzer-output=text -verify
+//RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.InnerPointer %s -analyzer-output=text -verify
namespace std {
@@ -38,6 +38,18 @@ typedef basic_string<wchar_t> wstring;
typedef basic_string<char16_t> u16string;
typedef basic_string<char32_t> u32string;
+template <typename T>
+void func_ref(T &a);
+
+template <typename T>
+void func_const_ref(const T &a);
+
+template <typename T>
+void func_value(T a);
+
+string my_string = "default";
+void default_arg(int a = 42, string &b = my_string);
+
} // end namespace std
void consume(const char *) {}
@@ -45,6 +57,10 @@ void consume(const wchar_t *) {}
void consume(const char16_t *) {}
void consume(const char32_t *) {}
+//=--------------------------------------=//
+// `std::string` member functions //
+//=--------------------------------------=//
+
void deref_after_scope_char(bool cond) {
const char *c, *d;
{
@@ -151,6 +167,19 @@ void multiple_symbols(bool cond) {
} // expected-note@-1 {{Use of memory after it is freed}}
}
+void deref_after_scope_ok(bool cond) {
+ const char *c, *d;
+ std::string s;
+ {
+ c = s.c_str();
+ d = s.data();
+ }
+ if (cond)
+ consume(c); // no-warning
+ else
+ consume(d); // no-warning
+}
+
void deref_after_equals() {
const char *c;
std::string s = "hello";
@@ -277,15 +306,58 @@ void deref_after_swap() {
// expected-note@-1 {{Use of memory after it is freed}}
}
-void deref_after_scope_ok(bool cond) {
- const char *c, *d;
+//=---------------------------=//
+// Other STL functions //
+//=---------------------------=//
+
+void STL_func_ref() {
+ const char *c;
std::string s;
- {
- c = s.c_str();
- d = s.data();
- }
- if (cond)
- consume(c); // no-warning
- else
- consume(d); // no-warning
+ c = s.c_str(); // expected-note {{Dangling inner pointer obtained here}}
+ std::func_ref(s); // expected-note {{Inner pointer invalidated by call to 'func_ref'}}
+ consume(c); // expected-warning {{Use of memory after it is freed}}
+ // expected-note@-1 {{Use of memory after it is freed}}
+}
+
+void STL_func_const_ref() {
+ const char *c;
+ std::string s;
+ c = s.c_str();
+ std::func_const_ref(s);
+ consume(c); // no-warning
+}
+
+void STL_func_value() {
+ const char *c;
+ std::string s;
+ c = s.c_str();
+ std::func_value(s);
+ consume(c); // no-warning
+}
+
+void func_ptr_known() {
+ const char *c;
+ std::string s;
+ void (*func_ptr)(std::string &) = std::func_ref<std::string>;
+ c = s.c_str(); // expected-note {{Dangling inner pointer obtained here}}
+ func_ptr(s); // expected-note {{Inner pointer invalidated by call to 'func_ref'}}
+ consume(c); // expected-warning {{Use of memory after it is freed}}
+ // expected-note@-1 {{Use of memory after it is freed}}
+}
+
+void func_ptr_unknown(void (*func_ptr)(std::string &)) {
+ const char *c;
+ std::string s;
+ c = s.c_str();
+ func_ptr(s);
+ consume(c); // no-warning
+}
+
+void func_default_arg() {
+ const char *c;
+ std::string s;
+ c = s.c_str(); // expected-note {{Dangling inner pointer obtained here}}
+ default_arg(3, s); // expected-note {{Inner pointer invalidated by call to 'default_arg'}}
+ consume(c); // expected-warning {{Use of memory after it is freed}}
+ // expected-note@-1 {{Use of memory after it is freed}}
}
diff --git a/test/Analysis/lifetime-extension.mm b/test/Analysis/lifetime-extension.mm
new file mode 100644
index 000000000000..6fb2e04f1018
--- /dev/null
+++ b/test/Analysis/lifetime-extension.mm
@@ -0,0 +1,64 @@
+// RUN: %clang_analyze_cc1 -Wno-unused -std=c++11 -analyzer-checker=core,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -Wno-unused -std=c++17 -analyzer-checker=core,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -Wno-unused -std=c++11 -analyzer-checker=core,debug.ExprInspection -DMOVES -verify %s
+// RUN: %clang_analyze_cc1 -Wno-unused -std=c++17 -analyzer-checker=core,debug.ExprInspection -DMOVES -verify %s
+
+void clang_analyzer_eval(bool);
+void clang_analyzer_checkInlined(bool);
+
+template <typename T> struct AddressVector {
+ T *buf[10];
+ int len;
+
+ AddressVector() : len(0) {}
+
+ void push(T *t) {
+ buf[len] = t;
+ ++len;
+ }
+};
+
+class C {
+ AddressVector<C> &v;
+
+public:
+ C(AddressVector<C> &v) : v(v) { v.push(this); }
+ ~C() { v.push(this); }
+
+#ifdef MOVES
+ C(C &&c) : v(c.v) { v.push(this); }
+#endif
+
+ // Note how return-statements prefer move-constructors when available.
+ C(const C &c) : v(c.v) {
+#ifdef MOVES
+ clang_analyzer_checkInlined(false); // no-warning
+#else
+ v.push(this);
+#endif
+ } // no-warning
+};
+
+@interface NSObject {}
+@end;
+@interface Foo: NSObject {}
+ -(C) make: (AddressVector<C> &)v;
+@end
+
+@implementation Foo
+-(C) make: (AddressVector<C> &)v {
+ return C(v);
+}
+@end
+
+void testReturnByValueFromMessage(Foo *foo) {
+ AddressVector<C> v;
+ {
+ const C &c = [foo make: v];
+ }
+ // 0. Construct the return value of -make (copy/move elided) and
+ // lifetime-extend it directly via reference 'c',
+ // 1. Destroy the temporary lifetime-extended by 'c'.
+ clang_analyzer_eval(v.len == 2); // expected-warning{{TRUE}}
+ clang_analyzer_eval(v.buf[0] == v.buf[1]); // expected-warning{{TRUE}}
+}
diff --git a/test/Analysis/temporaries.cpp b/test/Analysis/temporaries.cpp
index de3420e70891..e760d7ea283a 100644
--- a/test/Analysis/temporaries.cpp
+++ b/test/Analysis/temporaries.cpp
@@ -1,7 +1,7 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config cfg-temporary-dtors=false -verify -w -std=c++03 %s
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config cfg-temporary-dtors=false -verify -w -std=c++11 %s
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -DTEMPORARY_DTORS -verify -w -analyzer-config cfg-temporary-dtors=true,c++-temp-dtor-inlining=true %s -std=c++11
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -DTEMPORARY_DTORS -w -analyzer-config cfg-temporary-dtors=true,c++-temp-dtor-inlining=true %s -std=c++17
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus,debug.ExprInspection -analyzer-config cfg-temporary-dtors=false -verify -w -std=c++03 %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus,debug.ExprInspection -analyzer-config cfg-temporary-dtors=false -verify -w -std=c++11 %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus,debug.ExprInspection -DTEMPORARY_DTORS -verify -w -analyzer-config cfg-temporary-dtors=true,c++-temp-dtor-inlining=true %s -std=c++11
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus,debug.ExprInspection -DTEMPORARY_DTORS -w -analyzer-config cfg-temporary-dtors=true,c++-temp-dtor-inlining=true %s -std=c++17
// Note: The C++17 run-line doesn't -verify yet - it is a no-crash test.
@@ -458,6 +458,21 @@ namespace destructors {
#endif // TEMPORARY_DTORS
}
+namespace default_param_elided_destructors {
+struct a {
+ ~a();
+};
+struct F {
+ a d;
+ F(char *, a = a());
+};
+void g() {
+ char h[1];
+ for (int i = 0;;)
+ F j(i ? j : h);
+}
+} // namespace default_param_elided_destructors
+
void testStaticMaterializeTemporaryExpr() {
static const Trivial &ref = getTrivial();
clang_analyzer_eval(ref.value == 42); // expected-warning{{TRUE}}
@@ -945,3 +960,29 @@ C &&foo2();
const C &bar1() { return foo1(); } // no-crash
C &&bar2() { return foo2(); } // no-crash
} // end namespace pass_references_through
+
+
+namespace ctor_argument {
+// Stripped down unique_ptr<int>
+struct IntPtr {
+ IntPtr(): i(new int) {}
+ IntPtr(IntPtr &&o): i(o.i) { o.i = 0; }
+ ~IntPtr() { delete i; }
+
+ int *i;
+};
+
+struct Foo {
+ Foo(IntPtr);
+ void bar();
+
+ IntPtr i;
+};
+
+void bar() {
+ IntPtr ptr;
+ int *i = ptr.i;
+ Foo f(static_cast<IntPtr &&>(ptr));
+ *i = 99; // no-warning
+}
+} // namespace ctor_argument
diff --git a/test/Analysis/temporaries.mm b/test/Analysis/temporaries.mm
new file mode 100644
index 000000000000..3b6166db6e30
--- /dev/null
+++ b/test/Analysis/temporaries.mm
@@ -0,0 +1,23 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker core,cplusplus -verify %s
+
+// expected-no-diagnostics
+
+// Stripped down unique_ptr<int>
+struct IntPtr {
+ IntPtr(): i(new int) {}
+ IntPtr(IntPtr &&o): i(o.i) { o.i = nullptr; }
+ ~IntPtr() { delete i; }
+
+ int *i;
+};
+
+@interface Foo {}
+ -(void) foo: (IntPtr)arg;
+@end
+
+void bar(Foo *f) {
+ IntPtr ptr;
+ int *i = ptr.i;
+ [f foo: static_cast<IntPtr &&>(ptr)];
+ *i = 99; // no-warning
+}
diff --git a/test/CodeGen/aapcs-align.cc b/test/CodeGen/aapcs-align.cc
new file mode 100644
index 000000000000..40fba7823524
--- /dev/null
+++ b/test/CodeGen/aapcs-align.cc
@@ -0,0 +1,141 @@
+// REQUIRES: arm-registered-target
+// RUN: %clang_cc1 -triple arm-none-none-eabi \
+// RUN: -O2 \
+// RUN: -target-cpu cortex-a8 \
+// RUN: -emit-llvm -o - %s | FileCheck %s
+
+extern "C" {
+
+// Base case, nothing interesting.
+struct S {
+ int x, y;
+};
+
+void f0(int, S);
+void f0m(int, int, int, int, int, S);
+void g0() {
+ S s = {6, 7};
+ f0(1, s);
+ f0m(1, 2, 3, 4, 5, s);
+}
+// CHECK: define void @g0
+// CHECK: call void @f0(i32 1, [2 x i32] [i32 6, i32 7]
+// CHECK: call void @f0m(i32 1, i32 2, i32 3, i32 4, i32 5, [2 x i32] [i32 6, i32 7]
+// CHECK: declare void @f0(i32, [2 x i32])
+// CHECK: declare void @f0m(i32, i32, i32, i32, i32, [2 x i32])
+
+// Aligned struct, passed according to its natural alignment.
+struct __attribute__((aligned(8))) S8 {
+ int x, y;
+} s8;
+
+void f1(int, S8);
+void f1m(int, int, int, int, int, S8);
+void g1() {
+ S8 s = {6, 7};
+ f1(1, s);
+ f1m(1, 2, 3, 4, 5, s);
+}
+// CHECK: define void @g1
+// CHECK: call void @f1(i32 1, [2 x i32] [i32 6, i32 7]
+// CHECK: call void @f1m(i32 1, i32 2, i32 3, i32 4, i32 5, [2 x i32] [i32 6, i32 7]
+// CHECK: declare void @f1(i32, [2 x i32])
+// CHECK: declare void @f1m(i32, i32, i32, i32, i32, [2 x i32])
+
+// Aligned struct, passed according to its natural alignment.
+struct alignas(16) S16 {
+ int x, y;
+};
+
+extern "C" void f2(int, S16);
+extern "C" void f2m(int, int, int, int, int, S16);
+
+void g2() {
+ S16 s = {6, 7};
+ f2(1, s);
+ f2m(1, 2, 3, 4, 5, s);
+}
+// CHECK: define void @g2
+// CHECK: call void @f2(i32 1, [4 x i32] [i32 6, i32 7
+// CHECK: call void @f2m(i32 1, i32 2, i32 3, i32 4, i32 5, [4 x i32] [i32 6, i32 7
+// CHECK: declare void @f2(i32, [4 x i32])
+// CHECK: declare void @f2m(i32, i32, i32, i32, i32, [4 x i32])
+
+// Increased natural alignment.
+struct SF8 {
+ int x __attribute__((aligned(8)));
+ int y;
+};
+
+void f3(int, SF8);
+void f3m(int, int, int, int, int, SF8);
+void g3() {
+ SF8 s = {6, 7};
+ f3(1, s);
+ f3m(1, 2, 3, 4, 5, s);
+}
+// CHECK: define void @g3
+// CHECK: call void @f3(i32 1, [1 x i64] [i64 30064771078]
+// CHECK: call void @f3m(i32 1, i32 2, i32 3, i32 4, i32 5, [1 x i64] [i64 30064771078]
+// CHECK: declare void @f3(i32, [1 x i64])
+// CHECK: declare void @f3m(i32, i32, i32, i32, i32, [1 x i64])
+
+// Increased natural alignment, capped to 8 though.
+struct SF16 {
+ int x;
+ int y alignas(16);
+ int z, a, b, c, d, e, f, g, h, i, j, k;
+};
+
+void f4(int, SF16);
+void f4m(int, int, int, int, int, SF16);
+void g4() {
+ SF16 s = {6, 7};
+ f4(1, s);
+ f4m(1, 2, 3, 4, 5, s);
+}
+// CHECK: define void @g4
+// CHECK: call void @f4(i32 1, %struct.SF16* byval nonnull align 8
+// CHECK: call void @f4m(i32 1, i32 2, i32 3, i32 4, i32 5, %struct.SF16* byval nonnull align 8
+// CHECK: declare void @f4(i32, %struct.SF16* byval align 8)
+// CHECK: declare void @f4m(i32, i32, i32, i32, i32, %struct.SF16* byval align 8)
+
+// Packed structure.
+struct __attribute__((packed)) P {
+ int x;
+ long long u;
+};
+
+void f5(int, P);
+void f5m(int, int, int, int, int, P);
+void g5() {
+ P s = {6, 7};
+ f5(1, s);
+ f5m(1, 2, 3, 4, 5, s);
+}
+// CHECK: define void @g5
+// CHECK: call void @f5(i32 1, [3 x i32] [i32 6, i32 7, i32 0])
+// CHECK: call void @f5m(i32 1, i32 2, i32 3, i32 4, i32 5, [3 x i32] [i32 6, i32 7, i32 0])
+// CHECK: declare void @f5(i32, [3 x i32])
+// CHECK: declare void @f5m(i32, i32, i32, i32, i32, [3 x i32])
+
+
+// Packed and aligned, alignement causes padding at the end.
+struct __attribute__((packed, aligned(8))) P8 {
+ int x;
+ long long u;
+};
+
+void f6(int, P8);
+void f6m(int, int, int, int, int, P8);
+void g6() {
+ P8 s = {6, 7};
+ f6(1, s);
+ f6m(1, 2, 3, 4, 5, s);
+}
+// CHECK: define void @g6
+// CHECK: call void @f6(i32 1, [4 x i32] [i32 6, i32 7, i32 0, i32 0])
+// CHECK: call void @f6m(i32 1, i32 2, i32 3, i32 4, i32 5, [4 x i32] [i32 6, i32 7, i32 0, i32 0])
+// CHECK: declare void @f6(i32, [4 x i32])
+// CHECK: declare void @f6m(i32, i32, i32, i32, i32, [4 x i32])
+}
diff --git a/test/CodeGen/aapcs64-align.cc b/test/CodeGen/aapcs64-align.cc
new file mode 100644
index 000000000000..1b7c99ea8719
--- /dev/null
+++ b/test/CodeGen/aapcs64-align.cc
@@ -0,0 +1,103 @@
+// REQUIRES: arm-registered-target
+// RUN: %clang_cc1 -triple aarch64-none-none-eabi \
+// RUN: -O2 \
+// RUN: -emit-llvm -o - %s | FileCheck %s
+
+extern "C" {
+
+// Base case, nothing interesting.
+struct S {
+ long x, y;
+};
+
+void f0(long, S);
+void f0m(long, long, long, long, long, S);
+void g0() {
+ S s = {6, 7};
+ f0(1, s);
+ f0m(1, 2, 3, 4, 5, s);
+}
+// CHECK: define void @g0
+// CHECK: call void @f0(i64 1, [2 x i64] [i64 6, i64 7]
+// CHECK: call void @f0m{{.*}}[2 x i64] [i64 6, i64 7]
+// CHECK: declare void @f0(i64, [2 x i64])
+// CHECK: declare void @f0m(i64, i64, i64, i64, i64, [2 x i64])
+
+// Aligned struct, passed according to its natural alignment.
+struct __attribute__((aligned(16))) S16 {
+ long x, y;
+} s16;
+
+void f1(long, S16);
+void f1m(long, long, long, long, long, S16);
+void g1() {
+ S16 s = {6, 7};
+ f1(1, s);
+ f1m(1, 2, 3, 4, 5, s);
+}
+// CHECK: define void @g1
+// CHECK: call void @f1{{.*}}[2 x i64] [i64 6, i64 7]
+// CHECK: call void @f1m{{.*}}[2 x i64] [i64 6, i64 7]
+// CHECK: declare void @f1(i64, [2 x i64])
+// CHECK: declare void @f1m(i64, i64, i64, i64, i64, [2 x i64])
+
+// Increased natural alignment.
+struct SF16 {
+ long x __attribute__((aligned(16)));
+ long y;
+};
+
+void f3(long, SF16);
+void f3m(long, long, long, long, long, SF16);
+void g3() {
+ SF16 s = {6, 7};
+ f3(1, s);
+ f3m(1, 2, 3, 4, 5, s);
+}
+// CHECK: define void @g3
+// CHECK: call void @f3(i64 1, i128 129127208515966861318)
+// CHECK: call void @f3m(i64 1, i64 2, i64 3, i64 4, i64 5, i128 129127208515966861318)
+// CHECK: declare void @f3(i64, i128)
+// CHECK: declare void @f3m(i64, i64, i64, i64, i64, i128)
+
+
+// Packed structure.
+struct __attribute__((packed)) P {
+ int x;
+ long u;
+};
+
+void f4(int, P);
+void f4m(int, int, int, int, int, P);
+void g4() {
+ P s = {6, 7};
+ f4(1, s);
+ f4m(1, 2, 3, 4, 5, s);
+}
+// CHECK: define void @g4()
+// CHECK: call void @f4(i32 1, [2 x i64] [i64 30064771078, i64 0])
+// CHECK: void @f4m(i32 1, i32 2, i32 3, i32 4, i32 5, [2 x i64] [i64 30064771078, i64 0])
+// CHECK: declare void @f4(i32, [2 x i64])
+// CHECK: declare void @f4m(i32, i32, i32, i32, i32, [2 x i64])
+
+
+// Packed structure, overaligned, same as above.
+struct __attribute__((packed, aligned(16))) P16 {
+ int x;
+ long y;
+};
+
+void f5(int, P16);
+void f5m(int, int, int, int, int, P16);
+ void g5() {
+ P16 s = {6, 7};
+ f5(1, s);
+ f5m(1, 2, 3, 4, 5, s);
+}
+// CHECK: define void @g5()
+// CHECK: call void @f5(i32 1, [2 x i64] [i64 30064771078, i64 0])
+// CHECK: void @f5m(i32 1, i32 2, i32 3, i32 4, i32 5, [2 x i64] [i64 30064771078, i64 0])
+// CHECK: declare void @f5(i32, [2 x i64])
+// CHECK: declare void @f5m(i32, i32, i32, i32, i32, [2 x i64])
+
+}
diff --git a/test/CodeGen/arm-arguments.c b/test/CodeGen/arm-arguments.c
index ef4e76054ff8..ca6b70b44621 100644
--- a/test/CodeGen/arm-arguments.c
+++ b/test/CodeGen/arm-arguments.c
@@ -211,10 +211,13 @@ float32x4_t f35(int i, s35_with_align s1, s35_with_align s2) {
// APCS-GNU: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align {{[0-9]+}} %[[b]], i8* align {{[0-9]+}} %[[c]]
// APCS-GNU: %[[d:.*]] = bitcast %struct.s35* %[[a]] to <4 x float>*
// APCS-GNU: load <4 x float>, <4 x float>* %[[d]], align 16
-// AAPCS-LABEL: define arm_aapcscc <4 x float> @f35(i32 %i, %struct.s35* byval align 8, %struct.s35* byval align 8)
-// AAPCS: %[[a:.*]] = alloca %struct.s35, align 16
-// AAPCS: %[[b:.*]] = bitcast %struct.s35* %[[a]] to i8*
-// AAPCS: %[[c:.*]] = bitcast %struct.s35* %0 to i8*
-// AAPCS: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 16 %[[b]], i8* align 8 %[[c]]
-// AAPCS: %[[d:.*]] = bitcast %struct.s35* %[[a]] to <4 x float>*
-// AAPCS: load <4 x float>, <4 x float>* %[[d]], align 16
+
+// AAPCS-LABEL: define arm_aapcscc <4 x float> @f35(i32 %i, %struct.s35* byval align 4 %s1, %struct.s35* byval align 4 %s2)
+// AAPCS: %[[a_addr:.*]] = alloca <4 x float>, align 16
+// AAPCS: %[[b_addr:.*]] = alloca <4 x float>, align 16
+// AAPCS: %[[p1:.*]] = bitcast %struct.s35* %s1 to <4 x float>*
+// AAPCS: %[[a:.*]] = load <4 x float>, <4 x float>* %[[p1]], align 4
+// AAPCS: %[[p2:.*]] = bitcast %struct.s35* %s2 to <4 x float>*
+// AAPCS: %[[b:.*]] = load <4 x float>, <4 x float>* %[[p2]], align 4
+// AAPCS: store <4 x float> %[[a]], <4 x float>* %[[a_addr]], align 16
+// AAPCS: store <4 x float> %[[b]], <4 x float>* %[[b_addr]], align 16
diff --git a/test/CodeGen/builtin-memfns.c b/test/CodeGen/builtin-memfns.c
index d93a5aadae27..48626774531d 100644
--- a/test/CodeGen/builtin-memfns.c
+++ b/test/CodeGen/builtin-memfns.c
@@ -1,5 +1,8 @@
// RUN: %clang_cc1 -triple i386-pc-linux-gnu -emit-llvm < %s| FileCheck %s
+typedef __WCHAR_TYPE__ wchar_t;
+typedef __SIZE_TYPE__ size_t;
+
// CHECK: @test1
// CHECK: call void @llvm.memset.p0i8.i32
// CHECK: call void @llvm.memset.p0i8.i32
@@ -83,3 +86,17 @@ void test9() {
// CHECK: call void @llvm.memcpy{{.*}} align 16 {{.*}} align 16 {{.*}} 16, i1 false)
__builtin_memcpy(x, y, sizeof(y));
}
+
+wchar_t dest;
+wchar_t src;
+
+// CHECK-LABEL: @test10
+// FIXME: Consider lowering these to llvm.memcpy / llvm.memmove.
+void test10() {
+ // CHECK: call i32* @wmemcpy(i32* @dest, i32* @src, i32 4)
+ __builtin_wmemcpy(&dest, &src, 4);
+
+ // CHECK: call i32* @wmemmove(i32* @dest, i32* @src, i32 4)
+ __builtin_wmemmove(&dest, &src, 4);
+}
+
diff --git a/test/CodeGen/catch-implicit-integer-truncations.c b/test/CodeGen/catch-implicit-integer-truncations.c
new file mode 100644
index 000000000000..b09f7ddfaedf
--- /dev/null
+++ b/test/CodeGen/catch-implicit-integer-truncations.c
@@ -0,0 +1,395 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK
+// RUN: %clang_cc1 -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-NORECOVER
+// RUN: %clang_cc1 -fsanitize=implicit-integer-truncation -fsanitize-recover=implicit-integer-truncation -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-RECOVER
+// RUN: %clang_cc1 -fsanitize=implicit-integer-truncation -fsanitize-trap=implicit-integer-truncation -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-TRAP
+
+// CHECK-SANITIZE-ANYRECOVER: @[[UNSIGNED_INT:.*]] = {{.*}} c"'unsigned int'\00" }
+// CHECK-SANITIZE-ANYRECOVER: @[[UNSIGNED_CHAR:.*]] = {{.*}} c"'unsigned char'\00" }
+
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_100:.*]] = {{.*}}, i32 100, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 0 }
+// CHECK-SANITIZE-ANYRECOVER: @[[SIGNED_INT:.*]] = {{.*}} c"'int'\00" }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_200:.*]] = {{.*}}, i32 200, i32 10 }, {{.*}}* @[[SIGNED_INT]], {{.*}}* @[[UNSIGNED_CHAR]], i8 0 }
+// CHECK-SANITIZE-ANYRECOVER: @[[SIGNED_CHAR:.*]] = {{.*}} c"'signed char'\00" }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_300:.*]] = {{.*}}, i32 300, i32 10 }, {{.*}}* @[[UNSIGNED_INT]], {{.*}}* @[[SIGNED_CHAR]], i8 0 }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_400:.*]] = {{.*}}, i32 400, i32 10 }, {{.*}}* @[[SIGNED_INT]], {{.*}}* @[[SIGNED_CHAR]], i8 0 }
+
+// CHECK-SANITIZE-ANYRECOVER: @[[UINT32:.*]] = {{.*}} c"'uint32_t' (aka 'unsigned int')\00" }
+// CHECK-SANITIZE-ANYRECOVER: @[[UINT8:.*]] = {{.*}} c"'uint8_t' (aka 'unsigned char')\00" }
+// CHECK-SANITIZE-ANYRECOVER: @[[LINE_500:.*]] = {{.*}}, i32 500, i32 10 }, {{.*}}* @[[UINT32]], {{.*}}* @[[UINT8]], i8 0 }
+
+// ========================================================================== //
+// The expected true-positives. These are implicit conversions, and they truncate.
+// ========================================================================== //
+
+// CHECK-LABEL: @unsigned_int_to_unsigned_char
+unsigned char unsigned_int_to_unsigned_char(unsigned int src) {
+ // CHECK: %[[DST:.*]] = trunc i32 %[[SRC:.*]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_100]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_100]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK: ret i8 %[[DST]]
+#line 100
+ return src;
+}
+
+// CHECK-LABEL: @signed_int_to_unsigned_char
+unsigned char signed_int_to_unsigned_char(signed int src) {
+ // CHECK: %[[DST:.*]] = trunc i32 %[[SRC:.*]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_200]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_200]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK: ret i8 %[[DST]]
+#line 200
+ return src;
+}
+
+// CHECK-LABEL: @unsigned_int_to_signed_char
+signed char unsigned_int_to_signed_char(unsigned int src) {
+ // CHECK: %[[DST:.*]] = trunc i32 %[[SRC:.*]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_300]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_300]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK: ret i8 %[[DST]]
+#line 300
+ return src;
+}
+
+// CHECK-LABEL: @signed_int_to_signed_char
+signed char signed_int_to_signed_char(signed int src) {
+ // CHECK: %[[DST:.*]] = trunc i32 %[[SRC:.*]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = sext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_400]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_400]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK: ret i8 %[[DST]]
+#line 400
+ return src;
+}
+
+// ========================================================================== //
+// Check canonical type stuff
+// ========================================================================== //
+
+typedef unsigned int uint32_t;
+typedef unsigned char uint8_t;
+
+// CHECK-LABEL: @uint32_to_uint8
+uint8_t uint32_to_uint8(uint32_t src) {
+ // CHECK: %[[DST:.*]] = trunc i32 %[[SRC:.*]] to i8
+ // CHECK-SANITIZE-NEXT: %[[ANYEXT:.*]] = zext i8 %[[DST]] to i32, !nosanitize
+ // CHECK-SANITIZE-NEXT: %[[TRUNCHECK:.*]] = icmp eq i32 %[[ANYEXT]], %[[SRC]], !nosanitize
+ // CHECK-SANITIZE-NEXT: br i1 %[[TRUNCHECK]], label %[[CONT:.*]], label %[[HANDLER_IMPLICIT_CONVERSION:[^,]+]],{{.*}} !nosanitize
+ // CHECK-SANITIZE: [[HANDLER_IMPLICIT_CONVERSION]]:
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTSRC:.*]] = zext i32 %[[SRC]] to i64, !nosanitize
+ // CHECK-SANITIZE-ANYRECOVER-NEXT: %[[EXTDST:.*]] = zext i8 %[[DST]] to i64, !nosanitize
+ // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_implicit_conversion_abort(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_500]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_500]] to i8*), i64 %[[EXTSRC]], i64 %[[EXTDST]]){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.trap(){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: unreachable, !nosanitize
+ // CHECK-SANITIZE: [[CONT]]:
+ // CHECK: ret i8 %[[DST]]
+#line 500
+ return src;
+}
+
+// ========================================================================== //
+// Check that explicit conversion does not interfere with implicit conversion
+// ========================================================================== //
+// These contain one implicit truncating conversion, and one explicit truncating conversion.
+// We want to make sure that we still diagnose the implicit conversion.
+
+// Implicit truncation after explicit truncation.
+// CHECK-LABEL: @explicit_conversion_interference0
+unsigned char explicit_conversion_interference0(unsigned int c) {
+ // CHECK-SANITIZE: %[[ANYEXT:.*]] = zext i8 %[[DST:.*]] to i16, !nosanitize
+ // CHECK-SANITIZE: call
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return (unsigned short)c;
+}
+
+// Implicit truncation before explicit truncation.
+// CHECK-LABEL: @explicit_conversion_interference1
+unsigned char explicit_conversion_interference1(unsigned int c) {
+ // CHECK-SANITIZE: %[[ANYEXT:.*]] = zext i16 %[[DST:.*]] to i32, !nosanitize
+ // CHECK-SANITIZE: call
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ unsigned short b;
+ return (unsigned char)(b = c);
+}
+
+// ========================================================================== //
+// The expected true-negatives.
+// ========================================================================== //
+
+// Sanitization is explicitly disabled.
+// ========================================================================== //
+
+// CHECK-LABEL: @blacklist_0
+__attribute__((no_sanitize("undefined"))) unsigned char blacklist_0(unsigned int src) {
+ // We are not in "undefined" group, so that doesn't work.
+ // CHECK-SANITIZE: call
+ // CHECK: }
+ return src;
+}
+
+// CHECK-LABEL: @blacklist_1
+__attribute__((no_sanitize("implicit-conversion"))) unsigned char blacklist_1(unsigned int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return src;
+}
+
+// CHECK-LABEL: @blacklist_2
+__attribute__((no_sanitize("implicit-integer-truncation"))) unsigned char blacklist_2(unsigned int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return src;
+}
+
+// Explicit truncating conversions.
+// ========================================================================== //
+
+// CHECK-LABEL: @explicit_unsigned_int_to_unsigned_char
+unsigned char explicit_unsigned_int_to_unsigned_char(unsigned int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return (unsigned char)src;
+}
+
+// CHECK-LABEL: @explicit_signed_int_to_unsigned_char
+unsigned char explicit_signed_int_to_unsigned_char(signed int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return (unsigned char)src;
+}
+
+// CHECK-LABEL: @explicit_unsigned_int_to_signed_char
+signed char explicit_unsigned_int_to_signed_char(unsigned int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return (signed char)src;
+}
+
+// CHECK-LABEL: @explicit_signed_int_to_signed_char
+signed char explicit_signed_int_to_signed_char(signed int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return (signed char)src;
+}
+
+// Explicit NOP conversions.
+// ========================================================================== //
+
+// CHECK-LABEL: @explicit_unsigned_int_to_unsigned_int
+unsigned int explicit_unsigned_int_to_unsigned_int(unsigned int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return (unsigned int)src;
+}
+
+// CHECK-LABEL: @explicit_signed_int_to_signed_int
+signed int explicit_signed_int_to_signed_int(signed int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return (signed int)src;
+}
+
+// CHECK-LABEL: @explicit_unsigned_char_to_signed_char
+unsigned char explicit_unsigned_char_to_signed_char(unsigned char src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return (unsigned char)src;
+}
+
+// CHECK-LABEL: @explicit_signed_char_to_signed_char
+signed char explicit_signed_char_to_signed_char(signed char src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return (signed char)src;
+}
+
+// upcasts.
+// ========================================================================== //
+
+// CHECK-LABEL: @unsigned_char_to_unsigned_int
+unsigned int unsigned_char_to_unsigned_int(unsigned char src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return src;
+}
+
+// CHECK-LABEL: @signed_char_to_unsigned_int
+unsigned int signed_char_to_unsigned_int(signed char src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return src;
+}
+
+// CHECK-LABEL: @unsigned_char_to_signed_int
+signed int unsigned_char_to_signed_int(unsigned char src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return src;
+}
+
+// CHECK-LABEL: @signed_char_to_signed_int
+signed int signed_char_to_signed_int(signed char src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return src;
+}
+
+// Explicit upcasts.
+// ========================================================================== //
+
+// CHECK-LABEL: @explicit_unsigned_char_to_unsigned_int
+unsigned int explicit_unsigned_char_to_unsigned_int(unsigned char src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return (unsigned int)src;
+}
+
+// CHECK-LABEL: @explicit_signed_char_to_unsigned_int
+unsigned int explicit_signed_char_to_unsigned_int(signed char src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return (unsigned int)src;
+}
+
+// CHECK-LABEL: @explicit_unsigned_char_to_signed_int
+signed int explicit_unsigned_char_to_signed_int(unsigned char src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return (signed int)src;
+}
+
+// CHECK-LABEL: @explicit_signed_char_to_signed_int
+signed int explicit_signed_char_to_signed_int(signed char src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return (signed int)src;
+}
+
+// conversions to to boolean type are not counted as truncation.
+// ========================================================================== //
+
+// CHECK-LABEL: @unsigned_int_to_bool
+_Bool unsigned_int_to_bool(unsigned int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return src;
+}
+
+// CHECK-LABEL: @signed_int_to_bool
+_Bool signed_int_to_bool(signed int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return src;
+}
+
+// CHECK-LABEL: @explicit_unsigned_int_to_bool
+_Bool explicit_unsigned_int_to_bool(unsigned int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return (_Bool)src;
+}
+
+// CHECK-LABEL: @explicit_signed_int_to_bool
+_Bool explicit_signed_int_to_bool(signed int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return (_Bool)src;
+}
+
+// Explicit truncating conversions from pointer to a much-smaller integer.
+// Can not have an implicit conversion from pointer to an integer.
+// Can not have an implicit conversion between two enums.
+// ========================================================================== //
+
+// CHECK-LABEL: @explicit_voidptr_to_unsigned_char
+unsigned char explicit_voidptr_to_unsigned_char(void *src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return (unsigned char)src;
+}
+
+// CHECK-LABEL: @explicit_voidptr_to_signed_char
+signed char explicit_voidptr_to_signed_char(void *src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return (signed char)src;
+}
+
+// Implicit truncating conversions from floating-point may result in precision loss.
+// ========================================================================== //
+
+// CHECK-LABEL: @float_to_unsigned_int
+unsigned int float_to_unsigned_int(float src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return src;
+}
+
+// CHECK-LABEL: @float_to_signed_int
+signed int float_to_signed_int(float src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return src;
+}
+
+// CHECK-LABEL: @double_to_unsigned_int
+unsigned int double_to_unsigned_int(double src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return src;
+}
+
+// CHECK-LABEL: @double_to_signed_int
+signed int double_to_signed_int(double src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return src;
+}
+
+// Implicit truncating conversions between fp may result in precision loss.
+// ========================================================================== //
+
+// CHECK-LABEL: @double_to_float
+float double_to_float(double src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return src;
+}
diff --git a/test/CodeGen/exceptions-seh-finally.c b/test/CodeGen/exceptions-seh-finally.c
index d863eb1bb47e..655f0a782f54 100644
--- a/test/CodeGen/exceptions-seh-finally.c
+++ b/test/CodeGen/exceptions-seh-finally.c
@@ -1,5 +1,6 @@
// RUN: %clang_cc1 %s -triple x86_64-pc-win32 -fms-extensions -emit-llvm -o - | FileCheck %s
// RUN: %clang_cc1 %s -triple i686-pc-win32 -fms-extensions -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple aarch64-windows -fms-extensions -emit-llvm -o - | FileCheck %s
void abort(void) __attribute__((noreturn));
void might_crash(void);
diff --git a/test/CodeGen/exceptions-seh.c b/test/CodeGen/exceptions-seh.c
index b38c7a2490c0..1e3e2236ac6d 100644
--- a/test/CodeGen/exceptions-seh.c
+++ b/test/CodeGen/exceptions-seh.c
@@ -2,6 +2,8 @@
// RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=X64
// RUN: %clang_cc1 %s -triple i686-pc-win32 -fms-extensions -emit-llvm -o - \
// RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=X86
+// RUN: %clang_cc1 %s -triple aarch64-windows -fms-extensions -emit-llvm -o - \
+// RUN: | FileCheck %s --check-prefixes=CHECK,ARM64
// RUN: %clang_cc1 %s -triple i686-pc-windows-gnu -fms-extensions -emit-llvm -o - \
// RUN: | FileCheck %s --check-prefix=X86-GNU
// RUN: %clang_cc1 %s -triple x86_64-pc-windows-gnu -fms-extensions -emit-llvm -o - \
@@ -29,12 +31,14 @@ int safe_div(int numerator, int denominator, int *res) {
// CHECK-LABEL: define dso_local i32 @safe_div(i32 %numerator, i32 %denominator, i32* %res)
// X64-SAME: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
+// ARM64-SAME: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
// X86-SAME: personality i8* bitcast (i32 (...)* @_except_handler3 to i8*)
// CHECK: invoke void @try_body(i32 %{{.*}}, i32 %{{.*}}, i32* %{{.*}}) #[[NOINLINE:[0-9]+]]
// CHECK: to label %{{.*}} unwind label %[[catchpad:[^ ]*]]
//
// CHECK: [[catchpad]]
// X64: %[[padtoken:[^ ]*]] = catchpad within %{{[^ ]*}} [i8* null]
+// ARM64: %[[padtoken:[^ ]*]] = catchpad within %{{[^ ]*}} [i8* null]
// X86: %[[padtoken:[^ ]*]] = catchpad within %{{[^ ]*}} [i8* bitcast (i32 ()* @"?filt$0@0@safe_div@@" to i8*)]
// CHECK-NEXT: catchret from %[[padtoken]] to label %[[except:[^ ]*]]
//
@@ -76,8 +80,10 @@ int filter_expr_capture(void) {
// CHECK-LABEL: define dso_local i32 @filter_expr_capture()
// X64-SAME: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
+// ARM64-SAME: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
// X86-SAME: personality i8* bitcast (i32 (...)* @_except_handler3 to i8*)
// X64: call void (...) @llvm.localescape(i32* %[[r:[^ ,]*]])
+// ARM64: call void (...) @llvm.localescape(i32* %[[r:[^ ,]*]])
// X86: call void (...) @llvm.localescape(i32* %[[r:[^ ,]*]], i32* %[[code:[^ ,]*]])
// CHECK: store i32 42, i32* %[[r]]
// CHECK: invoke void @j() #[[NOINLINE]]
@@ -92,6 +98,10 @@ int filter_expr_capture(void) {
// X64: %[[fp:[^ ]*]] = call i8* @llvm.x86.seh.recoverfp(i8* bitcast (i32 ()* @filter_expr_capture to i8*), i8* %frame_pointer)
// X64: call i8* @llvm.localrecover(i8* bitcast (i32 ()* @filter_expr_capture to i8*), i8* %[[fp]], i32 0)
//
+// ARM64-LABEL: define internal i32 @"?filt$0@0@filter_expr_capture@@"(i8* %exception_pointers, i8* %frame_pointer)
+// ARM64: %[[fp:[^ ]*]] = call i8* @llvm.x86.seh.recoverfp(i8* bitcast (i32 ()* @filter_expr_capture to i8*), i8* %frame_pointer)
+// ARM64: call i8* @llvm.localrecover(i8* bitcast (i32 ()* @filter_expr_capture to i8*), i8* %[[fp]], i32 0)
+//
// X86-LABEL: define internal i32 @"?filt$0@0@filter_expr_capture@@"()
// X86: %[[ebp:[^ ]*]] = call i8* @llvm.frameaddress(i32 1)
// X86: %[[fp:[^ ]*]] = call i8* @llvm.x86.seh.recoverfp(i8* bitcast (i32 ()* @filter_expr_capture to i8*), i8* %[[ebp]])
@@ -116,6 +126,7 @@ int nested_try(void) {
}
// CHECK-LABEL: define dso_local i32 @nested_try()
// X64-SAME: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
+// ARM64-SAME: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
// X86-SAME: personality i8* bitcast (i32 (...)* @_except_handler3 to i8*)
// CHECK: store i32 42, i32* %[[r:[^ ,]*]]
// CHECK: invoke void @j() #[[NOINLINE]]
@@ -176,6 +187,7 @@ int basic_finally(int g) {
}
// CHECK-LABEL: define dso_local i32 @basic_finally(i32 %g)
// X64-SAME: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
+// ARM64-SAME: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
// X86-SAME: personality i8* bitcast (i32 (...)* @_except_handler3 to i8*)
// CHECK: %[[g_addr:[^ ]*]] = alloca i32, align 4
// CHECK: call void (...) @llvm.localescape(i32* %[[g_addr]])
@@ -275,6 +287,8 @@ int exception_code_in_except(void) {
// CHECK: catchret from %[[pad]]
// X64: %[[code:[^ ]*]] = call i32 @llvm.eh.exceptioncode(token %[[pad]])
// X64: store i32 %[[code]], i32* %[[code_slot]]
+// ARM64: %[[code:[^ ]*]] = call i32 @llvm.eh.exceptioncode(token %[[pad]])
+// ARM64: store i32 %[[code]], i32* %[[code_slot]]
// CHECK: %[[ret1:[^ ]*]] = load i32, i32* %[[code_slot]]
// CHECK: store i32 %[[ret1]], i32* %[[ret_slot]]
// CHECK: %[[ret2:[^ ]*]] = load i32, i32* %[[ret_slot]]
diff --git a/test/CodeGen/mips-unsigned-ext-var.c b/test/CodeGen/mips-unsigned-ext-var.c
index 2e04792cf375..a4dae53c184b 100644
--- a/test/CodeGen/mips-unsigned-ext-var.c
+++ b/test/CodeGen/mips-unsigned-ext-var.c
@@ -17,6 +17,6 @@ void foo1() {
foo(1,f);
}
-//N64: call i32 (i32, ...) @foo(i32 signext undef, i32 signext -32)
-//N32: call i32 (i32, ...) @foo(i32 signext undef, i32 signext -32)
-//O32: call i32 (i32, ...) @foo(i32 signext undef, i32 signext -32) \ No newline at end of file
+//N64: call signext i32 (i32, ...) @foo(i32 signext undef, i32 signext -32)
+//N32: call signext i32 (i32, ...) @foo(i32 signext undef, i32 signext -32)
+//O32: call i32 (i32, ...) @foo(i32 signext undef, i32 signext -32)
diff --git a/test/CodeGen/mips-varargs.c b/test/CodeGen/mips-varargs.c
index 343914ad8df1..8f1a633b7df8 100644
--- a/test/CodeGen/mips-varargs.c
+++ b/test/CodeGen/mips-varargs.c
@@ -19,7 +19,9 @@ int test_i32(char *fmt, ...) {
return v;
}
-// ALL-LABEL: define i32 @test_i32(i8*{{.*}} %fmt, ...)
+// O32-LABEL: define i32 @test_i32(i8*{{.*}} %fmt, ...)
+// N32-LABEL: define signext i32 @test_i32(i8*{{.*}} %fmt, ...)
+// N64-LABEL: define signext i32 @test_i32(i8*{{.*}} %fmt, ...)
//
// O32: %va = alloca i8*, align [[$PTRALIGN:4]]
// N32: %va = alloca i8*, align [[$PTRALIGN:4]]
@@ -133,7 +135,9 @@ int test_v4i32(char *fmt, ...) {
return v[0];
}
-// ALL-LABEL: define i32 @test_v4i32(i8*{{.*}} %fmt, ...)
+// O32-LABEL: define i32 @test_v4i32(i8*{{.*}} %fmt, ...)
+// N32-LABEL: define signext i32 @test_v4i32(i8*{{.*}} %fmt, ...)
+// N64-LABEL: define signext i32 @test_v4i32(i8*{{.*}} %fmt, ...)
//
// ALL: %va = alloca i8*, align [[$PTRALIGN]]
// ALL: [[V:%.+]] = alloca <4 x i32>, align 16
diff --git a/test/CodeGen/mips-vector-arg.c b/test/CodeGen/mips-vector-arg.c
index 1b9d7abe4d58..c9eafc958b1b 100644
--- a/test/CodeGen/mips-vector-arg.c
+++ b/test/CodeGen/mips-vector-arg.c
@@ -11,7 +11,7 @@ typedef int v4i32 __attribute__ ((__vector_size__ (16)));
// O32: define void @test_v4sf(i32 inreg %a1.coerce0, i32 inreg %a1.coerce1, i32 inreg %a1.coerce2, i32 inreg %a1.coerce3, i32 signext %a2, i32, i32 inreg %a3.coerce0, i32 inreg %a3.coerce1, i32 inreg %a3.coerce2, i32 inreg %a3.coerce3) local_unnamed_addr [[NUW:#[0-9]+]]
// O32: declare i32 @test_v4sf_2(i32 inreg, i32 inreg, i32 inreg, i32 inreg, i32 signext, i32, i32 inreg, i32 inreg, i32 inreg, i32 inreg)
// N64: define void @test_v4sf(i64 inreg %a1.coerce0, i64 inreg %a1.coerce1, i32 signext %a2, i64, i64 inreg %a3.coerce0, i64 inreg %a3.coerce1) local_unnamed_addr [[NUW:#[0-9]+]]
-// N64: declare i32 @test_v4sf_2(i64 inreg, i64 inreg, i32 signext, i64, i64 inreg, i64 inreg)
+// N64: declare signext i32 @test_v4sf_2(i64 inreg, i64 inreg, i32 signext, i64, i64 inreg, i64 inreg)
extern test_v4sf_2(v4sf, int, v4sf);
void test_v4sf(v4sf a1, int a2, v4sf a3) {
test_v4sf_2(a3, a2, a1);
@@ -20,7 +20,7 @@ void test_v4sf(v4sf a1, int a2, v4sf a3) {
// O32: define void @test_v4i32(i32 inreg %a1.coerce0, i32 inreg %a1.coerce1, i32 inreg %a1.coerce2, i32 inreg %a1.coerce3, i32 signext %a2, i32, i32 inreg %a3.coerce0, i32 inreg %a3.coerce1, i32 inreg %a3.coerce2, i32 inreg %a3.coerce3) local_unnamed_addr [[NUW]]
// O32: declare i32 @test_v4i32_2(i32 inreg, i32 inreg, i32 inreg, i32 inreg, i32 signext, i32, i32 inreg, i32 inreg, i32 inreg, i32 inreg)
// N64: define void @test_v4i32(i64 inreg %a1.coerce0, i64 inreg %a1.coerce1, i32 signext %a2, i64, i64 inreg %a3.coerce0, i64 inreg %a3.coerce1) local_unnamed_addr [[NUW]]
-// N64: declare i32 @test_v4i32_2(i64 inreg, i64 inreg, i32 signext, i64, i64 inreg, i64 inreg)
+// N64: declare signext i32 @test_v4i32_2(i64 inreg, i64 inreg, i32 signext, i64, i64 inreg, i64 inreg)
extern test_v4i32_2(v4i32, int, v4i32);
void test_v4i32(v4i32 a1, int a2, v4i32 a3) {
test_v4i32_2(a3, a2, a1);
diff --git a/test/CodeGenCUDA/device-var-init.cu b/test/CodeGenCUDA/device-var-init.cu
index 9f788b764fbc..f96e42d9711c 100644
--- a/test/CodeGenCUDA/device-var-init.cu
+++ b/test/CodeGenCUDA/device-var-init.cu
@@ -112,6 +112,9 @@ __constant__ EC_I_EC c_ec_i_ec;
// CHECK: @_ZZ2dfvE4s_ec = internal addrspace(3) global %struct.EC undef
// CHECK: @_ZZ2dfvE5s_etc = internal addrspace(3) global %struct.ETC undef
+// CHECK: @_ZZ2dfvE11const_array = internal addrspace(4) constant [5 x i32] [i32 1, i32 2, i32 3, i32 4, i32 5]
+// CHECK: @_ZZ2dfvE9const_int = internal addrspace(4) constant i32 123
+
// We should not emit global initializers for device-side variables.
// CHECK-NOT: @__cxx_global_var_init
@@ -234,6 +237,9 @@ __device__ void df() {
static __shared__ ETC s_etc;
// CHECK-NOT: call void @_ZN3ETCC1IJEEEDpT_(%struct.ETC* addrspacecast (%struct.ETC addrspace(3)* @_ZZ2dfvE5s_etc to %struct.ETC*))
+ static const int const_array[] = {1, 2, 3, 4, 5};
+ static const int const_int = 123;
+
// anchor point separating constructors and destructors
df(); // CHECK: call void @_Z2dfv()
diff --git a/test/CodeGenCXX/Inputs/override-layout-nameless-struct-union.layout b/test/CodeGenCXX/Inputs/override-layout-nameless-struct-union.layout
new file mode 100644
index 000000000000..9eb4d244bd70
--- /dev/null
+++ b/test/CodeGenCXX/Inputs/override-layout-nameless-struct-union.layout
@@ -0,0 +1,16 @@
+
+*** Dumping AST Record Layout
+Type: struct S
+
+Layout: <ASTRecordLayout
+ Size:64
+ Alignment:32
+ FieldOffsets: [0, 32, 32]>
+
+*** Dumping AST Record Layout
+Type: union U
+
+Layout: <ASTRecordLayout
+ Size:96
+ Alignment:32
+ FieldOffsets: [0, 0, 32, 64, 68, 73]>
diff --git a/test/CodeGenCXX/Inputs/override-layout-packed-base.layout b/test/CodeGenCXX/Inputs/override-layout-packed-base.layout
new file mode 100644
index 000000000000..949215ab849d
--- /dev/null
+++ b/test/CodeGenCXX/Inputs/override-layout-packed-base.layout
@@ -0,0 +1,18 @@
+
+*** Dumping AST Record Layout
+Type: class B<0>
+
+Layout: <ASTRecordLayout
+ FieldOffsets: [0, 32]>
+
+*** Dumping AST Record Layout
+Type: class B<1>
+
+Layout: <ASTRecordLayout
+ FieldOffsets: [0, 32]>
+
+*** Dumping AST Record Layout
+Type: class C
+
+Layout: <ASTRecordLayout
+ FieldOffsets: [80]>
diff --git a/test/CodeGenCXX/castexpr-basepathsize-threshold.cpp b/test/CodeGenCXX/castexpr-basepathsize-threshold.cpp
new file mode 100644
index 000000000000..d5c1f603ff3f
--- /dev/null
+++ b/test/CodeGenCXX/castexpr-basepathsize-threshold.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 %s -emit-llvm -o -
+
+// https://bugs.llvm.org/show_bug.cgi?id=38356
+// We only check that we do not crash.
+
+template <typename a, a b(unsigned), int c, unsigned...>
+struct d : d<a, b, c - 1> {};
+template <typename a, a b(unsigned), unsigned... e>
+struct d<a, b, 0, e...> {
+ a f[0];
+};
+struct g {
+ static g h(unsigned);
+};
+struct i {
+ void j() const;
+ // Current maximum depth of recursive template instantiation is 1024,
+ // thus, this \/ threshold value is used here. BasePathSize in CastExpr might
+ // not fit it, so we are testing that we do fit it.
+ // If -ftemplate-depth= is provided, larger values (4096 and up) cause crashes
+ // elsewhere.
+ d<g, g::h, (1U << 10U) - 2U> f;
+};
+void i::j() const {
+ const void *k{f.f};
+ (void)k;
+}
diff --git a/test/CodeGenCXX/catch-implicit-integer-truncations.cpp b/test/CodeGenCXX/catch-implicit-integer-truncations.cpp
new file mode 100644
index 000000000000..ba7676a3504a
--- /dev/null
+++ b/test/CodeGenCXX/catch-implicit-integer-truncations.cpp
@@ -0,0 +1,256 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK
+// RUN: %clang_cc1 -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-NORECOVER
+// RUN: %clang_cc1 -fsanitize=implicit-integer-truncation -fsanitize-recover=implicit-integer-truncation -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-RECOVER
+// RUN: %clang_cc1 -fsanitize=implicit-integer-truncation -fsanitize-trap=implicit-integer-truncation -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-TRAP
+
+extern "C" { // Disable name mangling.
+
+// ========================================================================== //
+// Check that explicit cast does not interfere with implicit conversion
+// ========================================================================== //
+// These contain one implicit truncating conversion, and one explicit truncating cast.
+// We want to make sure that we still diagnose the implicit conversion.
+
+// Implicit truncation after explicit truncation.
+// CHECK-LABEL: @explicit_cast_interference0
+unsigned char explicit_cast_interference0(unsigned int c) {
+ // CHECK-SANITIZE: %[[ANYEXT:.*]] = zext i8 %[[DST:.*]] to i16, !nosanitize
+ // CHECK-SANITIZE: call
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return (unsigned short)c;
+}
+
+// Implicit truncation before explicit truncation.
+// CHECK-LABEL: @explicit_cast_interference1
+unsigned char explicit_cast_interference1(unsigned int c) {
+ // CHECK-SANITIZE: %[[ANYEXT:.*]] = zext i16 %[[DST:.*]] to i32, !nosanitize
+ // CHECK-SANITIZE: call
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ unsigned short b;
+ return (unsigned char)(b = c);
+}
+
+// ========================================================================== //
+// The expected true-negatives.
+// ========================================================================== //
+
+// Explicit truncating casts.
+// ========================================================================== //
+
+// CHECK-LABEL: @explicit_unsigned_int_to_unsigned_char
+unsigned char explicit_unsigned_int_to_unsigned_char(unsigned int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return (unsigned char)src;
+}
+
+// CHECK-LABEL: @explicit_signed_int_to_unsigned_char
+unsigned char explicit_signed_int_to_unsigned_char(signed int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return (unsigned char)src;
+}
+
+// CHECK-LABEL: @explicit_unsigned_int_to_signed_char
+signed char explicit_unsigned_int_to_signed_char(unsigned int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return (signed char)src;
+}
+
+// CHECK-LABEL: @explicit_signed_int_to_signed_char
+signed char explicit_signed_int_to_signed_char(signed int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return (signed char)src;
+}
+
+// Explicit NOP casts.
+// ========================================================================== //
+
+// CHECK-LABEL: @explicit_unsigned_int_to_unsigned_int
+unsigned int explicit_unsigned_int_to_unsigned_int(unsigned int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return (unsigned int)src;
+}
+
+// CHECK-LABEL: @explicit_signed_int_to_signed_int
+signed int explicit_signed_int_to_signed_int(signed int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return (signed int)src;
+}
+
+// CHECK-LABEL: @explicit_unsigned_char_to_signed_char
+unsigned char explicit_unsigned_char_to_signed_char(unsigned char src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return (unsigned char)src;
+}
+
+// CHECK-LABEL: @explicit_signed_char_to_signed_char
+signed char explicit_signed_char_to_signed_char(signed char src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return (signed char)src;
+}
+
+// Explicit functional truncating casts.
+// ========================================================================== //
+
+using UnsignedChar = unsigned char;
+using SignedChar = signed char;
+using UnsignedInt = unsigned int;
+using SignedInt = signed int;
+
+// CHECK-LABEL: @explicit_functional_unsigned_int_to_unsigned_char
+unsigned char explicit_functional_unsigned_int_to_unsigned_char(unsigned int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return UnsignedChar(src);
+}
+
+// CHECK-LABEL: @explicit_functional_signed_int_to_unsigned_char
+unsigned char explicit_functional_signed_int_to_unsigned_char(signed int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return UnsignedChar(src);
+}
+
+// CHECK-LABEL: @explicit_functional_unsigned_int_to_signed_char
+signed char explicit_functional_unsigned_int_to_signed_char(unsigned int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return SignedChar(src);
+}
+
+// CHECK-LABEL: @explicit_functional_signed_int_to_signed_char
+signed char explicit_functional_signed_int_to_signed_char(signed int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return SignedChar(src);
+}
+
+// Explicit functional NOP casts.
+// ========================================================================== //
+
+// CHECK-LABEL: @explicit_functional_unsigned_int_to_unsigned_int
+unsigned int explicit_functional_unsigned_int_to_unsigned_int(unsigned int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return UnsignedInt(src);
+}
+
+// CHECK-LABEL: @explicit_functional_signed_int_to_signed_int
+signed int explicit_functional_signed_int_to_signed_int(signed int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return SignedInt(src);
+}
+
+// CHECK-LABEL: @explicit_functional_unsigned_char_to_signed_char
+unsigned char explicit_functional_unsigned_char_to_signed_char(unsigned char src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return UnsignedChar(src);
+}
+
+// CHECK-LABEL: @explicit_functional_signed_char_to_signed_char
+signed char explicit_functional_signed_char_to_signed_char(signed char src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return SignedChar(src);
+}
+
+// Explicit C++-style casts truncating casts.
+// ========================================================================== //
+
+// CHECK-LABEL: @explicit_cppstyleunsigned_int_to_unsigned_char
+unsigned char explicit_cppstyleunsigned_int_to_unsigned_char(unsigned int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return static_cast<unsigned char>(src);
+}
+
+// CHECK-LABEL: @explicit_cppstylesigned_int_to_unsigned_char
+unsigned char explicit_cppstylesigned_int_to_unsigned_char(signed int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return static_cast<unsigned char>(src);
+}
+
+// CHECK-LABEL: @explicit_cppstyleunsigned_int_to_signed_char
+signed char explicit_cppstyleunsigned_int_to_signed_char(unsigned int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return static_cast<signed char>(src);
+}
+
+// CHECK-LABEL: @explicit_cppstylesigned_int_to_signed_char
+signed char explicit_cppstylesigned_int_to_signed_char(signed int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return static_cast<signed char>(src);
+}
+
+// Explicit C++-style casts NOP casts.
+// ========================================================================== //
+
+// CHECK-LABEL: @explicit_cppstyleunsigned_int_to_unsigned_int
+unsigned int explicit_cppstyleunsigned_int_to_unsigned_int(unsigned int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return static_cast<unsigned int>(src);
+}
+
+// CHECK-LABEL: @explicit_cppstylesigned_int_to_signed_int
+signed int explicit_cppstylesigned_int_to_signed_int(signed int src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return static_cast<signed int>(src);
+}
+
+// CHECK-LABEL: @explicit_cppstyleunsigned_char_to_signed_char
+unsigned char explicit_cppstyleunsigned_char_to_signed_char(unsigned char src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return static_cast<unsigned char>(src);
+}
+
+// CHECK-LABEL: @explicit_cppstylesigned_char_to_signed_char
+signed char explicit_cppstylesigned_char_to_signed_char(signed char src) {
+ // CHECK-SANITIZE-NOT: call
+ // CHECK: }
+ return static_cast<signed char>(src);
+}
+
+} // extern "C"
+
+// ---------------------------------------------------------------------------//
+// A problematic true-negative involving simple C++ code.
+// The problem is tha the NoOp ExplicitCast is directly within MaterializeTemporaryExpr(),
+// so a special care is neeeded.
+// See https://reviews.llvm.org/D48958#1161345
+template <typename a>
+a b(a c, const a &d) {
+ if (d)
+ ;
+ return c;
+}
+
+extern "C" { // Disable name mangling.
+
+// CHECK-LABEL: @false_positive_with_MaterializeTemporaryExpr
+int false_positive_with_MaterializeTemporaryExpr() {
+ // CHECK-SANITIZE-NOT: call{{.*}}ubsan
+ // CHECK: }
+ int e = b<unsigned>(4, static_cast<unsigned>(4294967296));
+ return e;
+}
+
+// ---------------------------------------------------------------------------//
+
+} // extern "C"
diff --git a/test/CodeGenCXX/ctor-dtor-alias.cpp b/test/CodeGenCXX/ctor-dtor-alias.cpp
index 4715111a1439..89244cc105b2 100644
--- a/test/CodeGenCXX/ctor-dtor-alias.cpp
+++ b/test/CodeGenCXX/ctor-dtor-alias.cpp
@@ -1,7 +1,5 @@
-// RUN: %clang_cc1 %s -triple i686-linux -emit-llvm -o - -mconstructor-aliases > %t
-// RUN: FileCheck --check-prefix=NOOPT1 --input-file=%t %s
-// RUN: FileCheck --check-prefix=NOOPT2 --input-file=%t %s
-// RUN: FileCheck --check-prefix=NOOPT3 --input-file=%t %s
+// RUN: %clang_cc1 %s -triple i686-linux -emit-llvm -o - -mconstructor-aliases | FileCheck --check-prefix=NOOPT %s
+
// RUN: %clang_cc1 %s -triple i686-linux -emit-llvm -o - -mconstructor-aliases -O1 -disable-llvm-passes > %t
// RUN: FileCheck --check-prefix=CHECK1 --input-file=%t %s
// RUN: FileCheck --check-prefix=CHECK2 --input-file=%t %s
@@ -23,13 +21,6 @@ namespace test1 {
// CHECK1: define weak_odr void @_ZN5test16foobarIvED0Ev({{.*}} comdat($_ZN5test16foobarIvED5Ev)
// CHECK1-NOT: comdat
-// This should happen regardless of the opt level.
-// NOOPT1: @_ZN5test16foobarIvEC1Ev = weak_odr unnamed_addr alias void {{.*}} @_ZN5test16foobarIvEC2Ev
-// NOOPT1: @_ZN5test16foobarIvED1Ev = weak_odr unnamed_addr alias void (%"struct.test1::foobar"*), void (%"struct.test1::foobar"*)* @_ZN5test16foobarIvED2Ev
-// NOOPT1: define weak_odr void @_ZN5test16foobarIvEC2Ev({{.*}} comdat($_ZN5test16foobarIvEC5Ev)
-// NOOPT1: define weak_odr void @_ZN5test16foobarIvED2Ev({{.*}} comdat($_ZN5test16foobarIvED5Ev)
-// NOOPT1: define weak_odr void @_ZN5test16foobarIvED0Ev({{.*}} comdat($_ZN5test16foobarIvED5Ev)
-
// COFF doesn't support comdats with arbitrary names (C5/D5).
// COFF: define weak_odr {{.*}} void @_ZN5test16foobarIvEC2Ev({{.*}} comdat align
// COFF: define weak_odr {{.*}} void @_ZN5test16foobarIvEC1Ev({{.*}} comdat align
@@ -46,17 +37,12 @@ template struct foobar<void>;
}
namespace test2 {
-// test that when the destructor is linkonce_odr we just replace every use of
+// test that when the destrucor is linkonce_odr we just replace every use of
// C1 with C2.
// CHECK1: define internal void @__cxx_global_var_init()
// CHECK1: call void @_ZN5test26foobarIvEC2Ev
// CHECK1: define linkonce_odr void @_ZN5test26foobarIvEC2Ev({{.*}} comdat align
-
-// At -O0, we should still emit the complete constructor.
-// NOOPT1: define internal void @__cxx_global_var_init()
-// NOOPT1: call void @_ZN5test26foobarIvEC1Ev
-// NOOPT1: define linkonce_odr void @_ZN5test26foobarIvEC1Ev({{.*}} comdat align
void g();
template <typename T> struct foobar {
foobar() { g(); }
@@ -71,11 +57,6 @@ namespace test3 {
// CHECK1: define internal void @__cxx_global_var_init.1()
// CHECK1: call i32 @__cxa_atexit{{.*}}_ZN5test312_GLOBAL__N_11AD2Ev
// CHECK1: define internal void @_ZN5test312_GLOBAL__N_11AD2Ev(
-
-// We can use an alias for internal symbols at -O0.
-// NOOPT2: _ZN5test312_GLOBAL__N_11BD1Ev = internal unnamed_addr alias void {{.*}} @_ZN5test312_GLOBAL__N_11BD2Ev
-// NOOPT2: define internal void @__cxx_global_var_init.1()
-// NOOPT2: call i32 @__cxa_atexit{{.*}}_ZN5test312_GLOBAL__N_11BD1Ev
namespace {
struct A {
~A() {}
@@ -96,12 +77,11 @@ namespace test4 {
// CHECK1: call i32 @__cxa_atexit{{.*}}_ZN5test41AD2Ev
// CHECK1: define linkonce_odr void @_ZN5test41AD2Ev({{.*}} comdat align
- // Test that we don't do this optimization at -O0 and call the complete
- // destructor for B instead. This enables the debugger to see both
- // destructors.
- // NOOPT2: define internal void @__cxx_global_var_init.2()
- // NOOPT2: call i32 @__cxa_atexit{{.*}}@_ZN5test41BD1Ev
- // NOOPT2: define linkonce_odr void @_ZN5test41BD1Ev({{.*}} comdat align
+ // test that we don't do this optimization at -O0 so that the debugger can
+ // see both destructors.
+ // NOOPT: define internal void @__cxx_global_var_init.2()
+ // NOOPT: call i32 @__cxa_atexit{{.*}}@_ZN5test41BD2Ev
+ // NOOPT: define linkonce_odr void @_ZN5test41BD2Ev({{.*}} comdat align
struct A {
virtual ~A() {}
};
@@ -149,11 +129,6 @@ namespace test7 {
// out if we should).
// pr17875.
// CHECK3: define void @_ZN5test71BD2Ev
-
- // At -O0, we should emit both destructors, the complete can be an alias to
- // the base one.
- // NOOPT3: @_ZN5test71BD1Ev = unnamed_addr alias void {{.*}} @_ZN5test71BD2Ev
- // NOOPT3: define void @_ZN5test71BD2Ev
template <typename> struct A {
~A() {}
};
diff --git a/test/CodeGenCXX/float16-declarations.cpp b/test/CodeGenCXX/float16-declarations.cpp
index 1d6999fef073..e82c05ec8c81 100644
--- a/test/CodeGenCXX/float16-declarations.cpp
+++ b/test/CodeGenCXX/float16-declarations.cpp
@@ -103,7 +103,7 @@ int main(void) {
C1 c1(f1l);
// CHECK-DAG: [[F1L:%[a-z0-9]+]] = load half, half* %{{.*}}, align 2
-// CHECK-DAG: call void @_ZN2C1C1EDF16_(%class.C1* %{{.*}}, half %{{.*}})
+// CHECK-DAG: call void @_ZN2C1C2EDF16_(%class.C1* %{{.*}}, half %{{.*}})
S1<_Float16> s1 = { 132.f16 };
// CHECK-DAG: @_ZZ4mainE2s1 = private unnamed_addr constant %struct.S1 { half 0xH5820 }, align 2
diff --git a/test/CodeGenCXX/override-layout-nameless-struct-union.cpp b/test/CodeGenCXX/override-layout-nameless-struct-union.cpp
new file mode 100644
index 000000000000..acc1ff715c69
--- /dev/null
+++ b/test/CodeGenCXX/override-layout-nameless-struct-union.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -w -fdump-record-layouts-simple -foverride-record-layout=%S/Inputs/override-layout-nameless-struct-union.layout %s | FileCheck %s
+
+// CHECK: Type: struct S
+// CHECK: Size:64
+// CHECK: Alignment:32
+// CHECK: FieldOffsets: [0, 32, 32]
+struct S {
+ short _s;
+//union {
+ int _su0;
+ char _su1;
+//};
+};
+
+// CHECK: Type: union U
+// CHECK: Size:96
+// CHECK: Alignment:32
+// CHECK: FieldOffsets: [0, 0, 32, 64, 68, 73]
+union U {
+ short _u;
+//struct {
+ char _us0;
+ int _us1;
+ unsigned _us20 : 4;
+ unsigned _us21 : 5;
+ unsigned _us22 : 6;
+//};
+};
+
+void use_structs() {
+ S ss[sizeof(S)];
+ U us[sizeof(U)];
+}
diff --git a/test/CodeGenCXX/override-layout-packed-base.cpp b/test/CodeGenCXX/override-layout-packed-base.cpp
new file mode 100644
index 000000000000..26ed4b5d815a
--- /dev/null
+++ b/test/CodeGenCXX/override-layout-packed-base.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -w -fdump-record-layouts-simple -foverride-record-layout=%S/Inputs/override-layout-packed-base.layout %s | FileCheck %s
+
+// CHECK: Type: class B<0>
+// CHECK: FieldOffsets: [0, 32]
+
+// CHECK: Type: class B<1>
+// CHECK: FieldOffsets: [0, 32]
+
+//#pragma pack(push, 1)
+template<int I>
+class B {
+ int _b1;
+ char _b2;
+};
+//#pragma pack(pop)
+
+// CHECK: Type: class C
+// CHECK: FieldOffsets: [80]
+
+class C : B<0>, B<1> {
+ char _c;
+};
+
+void use_structs() {
+ C cs[sizeof(C)];
+}
diff --git a/test/CodeGenCXX/ubsan-new-checks.cpp b/test/CodeGenCXX/ubsan-new-checks.cpp
new file mode 100644
index 000000000000..019fcf15a2ab
--- /dev/null
+++ b/test/CodeGenCXX/ubsan-new-checks.cpp
@@ -0,0 +1,146 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -S -emit-llvm -fsanitize=alignment %s -o - | FileCheck %s
+
+struct alignas(32) S1 {
+ int x;
+ S1();
+};
+
+struct alignas(32) S2 {
+ int x;
+};
+
+struct alignas(32) S3 {
+ int x;
+ S3(int *p = new int[4]);
+};
+
+struct S4 : public S3 {
+ S4() : S3() {}
+};
+
+typedef __attribute__((ext_vector_type(2), aligned(32))) float float32x2_t;
+
+struct S5 {
+ float32x2_t x;
+};
+
+void *operator new (unsigned long, void *p) { return p; }
+void *operator new[] (unsigned long, void *p) { return p; }
+
+S1 *func_01() {
+ // CHECK-LABEL: define {{.*}} @_Z7func_01v
+ // CHECK: and i64 %{{.*}}, 31, !nosanitize
+ // CHECK: icmp eq i64 %{{.*}}, 0, !nosanitize
+ // CHECK: call void @_ZN2S1C1Ev(
+ // CHECK-NOT: and i64 %{{.*}}, 31
+ // CHECK: ret %struct.S1*
+ return new S1[20];
+}
+
+S2 *func_02() {
+ // CHECK-LABEL: define {{.*}} @_Z7func_02v
+ // CHECK: and i64 %{{.*}}, 31, !nosanitize
+ // CHECK: icmp eq i64 %{{.*}}, 0, !nosanitize
+ // CHECK: ret %struct.S2*
+ return new S2;
+}
+
+S2 *func_03() {
+ // CHECK-LABEL: define {{.*}} @_Z7func_03v
+ // CHECK: and i64 %{{.*}}, 31, !nosanitize
+ // CHECK: icmp eq i64 %{{.*}}, 0, !nosanitize
+ // CHECK-NOT: and i64 %{{.*}}, 31
+ // CHECK: ret %struct.S2*
+ return new S2[20];
+}
+
+float32x2_t *func_04() {
+ // CHECK-LABEL: define {{.*}} @_Z7func_04v
+ // CHECK: and i64 %{{.*}}, 31, !nosanitize
+ // CHECK: icmp eq i64 %{{.*}}, 0, !nosanitize
+ // CHECK: ret <2 x float>*
+ return new float32x2_t;
+}
+
+float32x2_t *func_05() {
+ // CHECK-LABEL: define {{.*}} @_Z7func_05v
+ // CHECK: and i64 %{{.*}}, 31, !nosanitize
+ // CHECK: icmp eq i64 %{{.*}}, 0, !nosanitize
+ // CHECK-NOT: and i64 %{{.*}}, 31
+ // CHECK: ret <2 x float>*
+ return new float32x2_t[20];
+}
+
+S3 *func_07() {
+ // CHECK-LABEL: define {{.*}} @_Z7func_07v
+ // CHECK: and i64 %{{.*}}, 31, !nosanitize
+ // CHECK: icmp eq i64 %{{.*}}, 0, !nosanitize
+ // CHECK: and i64 %{{.*}}, 3, !nosanitize
+ // CHECK: icmp eq i64 %{{.*}}, 0, !nosanitize
+ // CHECK: ret %struct.S3*
+ return new S3;
+}
+
+S3 *func_08() {
+ // CHECK-LABEL: define {{.*}} @_Z7func_08v
+ // CHECK: and i64 %{{.*}}, 31, !nosanitize
+ // CHECK: icmp eq i64 %{{.*}}, 0, !nosanitize
+ // CHECK: and i64 %{{.*}}, 3, !nosanitize
+ // CHECK: icmp eq i64 %{{.*}}, 0, !nosanitize
+ // CHECK: ret %struct.S3*
+ return new S3[10];
+}
+
+
+S2 *func_10(void *p) {
+ // CHECK-LABEL: define {{.*}} @_Z7func_10Pv
+ // CHECK: and i64 %{{.*}}, 31, !nosanitize
+ // CHECK: icmp eq i64 %{{.*}}, 0, !nosanitize
+ // CHECK: ret %struct.S2*
+ return new(p) S2;
+}
+
+S2 *func_11(void *p) {
+ // CHECK-LABEL: define {{.*}} @_Z7func_11Pv
+ // CHECK: and i64 %{{.*}}, 31, !nosanitize
+ // CHECK: icmp eq i64 %{{.*}}, 0, !nosanitize
+ // CHECK-NOT: and i64 %{{.*}}, 31, !nosanitize
+ // CHECK-NOT: icmp eq i64 %{{.*}}, 0, !nosanitize
+ // CHECK: ret %struct.S2*
+ return new(p) S2[10];
+}
+
+float32x2_t *func_12() {
+ // CHECK-LABEL: define {{.*}} @_Z7func_12v
+ // CHECK: and i64 %{{.*}}, 31, !nosanitize
+ // CHECK: icmp eq i64 %{{.*}}, 0, !nosanitize
+ // CHECK: ret <2 x float>*
+ return new float32x2_t;
+}
+
+float32x2_t *func_13() {
+ // CHECK-LABEL: define {{.*}} @_Z7func_13v
+ // CHECK: and i64 %{{.*}}, 31, !nosanitize
+ // CHECK: icmp eq i64 %{{.*}}, 0, !nosanitize
+ // CHECK-NOT: and i64 %{{.*}}, 31
+ // CHECK: ret <2 x float>*
+ return new float32x2_t[20];
+}
+
+S4 *func_14() {
+ // CHECK-LABEL: define {{.*}} @_Z7func_14v
+ // CHECK: and i64 %{{.*}}, 31, !nosanitize
+ // CHECK: icmp eq i64 %{{.*}}, 0, !nosanitize
+ // CHECK-NOT: and i64 %{{.*}}, 31
+ // CHECK: ret %struct.S4*
+ return new S4;
+}
+
+S5 *func_15(const S5 *ptr) {
+ // CHECK-LABEL: define {{.*}} @_Z7func_15PK2S5
+ // CHECK: and i64 %{{.*}}, 31, !nosanitize
+ // CHECK: icmp eq i64 %{{.*}}, 0, !nosanitize
+ // CHECK-NOT: and i64
+ // CHECK: ret %struct.S5*
+ return new S5(*ptr);
+}
diff --git a/test/CodeGenOpenCL/blocks.cl b/test/CodeGenOpenCL/blocks.cl
index 0e125fd703f5..80ac5727b094 100644
--- a/test/CodeGenOpenCL/blocks.cl
+++ b/test/CodeGenOpenCL/blocks.cl
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-llvm -o - -O0 -triple spir-unknown-unknown | FileCheck -check-prefixes=COMMON,SPIR %s
-// RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-llvm -o - -O0 -triple amdgcn-amd-amdhsa | FileCheck -check-prefixes=COMMON,AMDGCN %s
+// RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-llvm -o - -O0 -debug-info-kind=limited -triple spir-unknown-unknown | FileCheck -check-prefixes=COMMON,SPIR %s
+// RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-llvm -o - -O0 -debug-info-kind=limited -triple amdgcn-amd-amdhsa | FileCheck -check-prefixes=COMMON,AMDGCN %s
// COMMON: @__block_literal_global = internal addrspace(1) constant { i32, i32 } { i32 8, i32 4 }
// COMMON-NOT: .str
@@ -60,3 +60,11 @@ void foo(){
// AMDGCN: %[[block_capture:.*]] = load i32, i32* %[[block_capture_addr]]
// COMMON-NOT: define{{.*}}@__foo_block_invoke_kernel
+
+// COMMON: !DIDerivedType(tag: DW_TAG_member, name: "__size"
+// COMMON: !DIDerivedType(tag: DW_TAG_member, name: "__align"
+
+// COMMON-NOT: !DIDerivedType(tag: DW_TAG_member, name: "__isa"
+// COMMON-NOT: !DIDerivedType(tag: DW_TAG_member, name: "__flags"
+// COMMON-NOT: !DIDerivedType(tag: DW_TAG_member, name: "__reserved"
+// COMMON-NOT: !DIDerivedType(tag: DW_TAG_member, name: "__FuncPtr"
diff --git a/test/CodeGenOpenCL/builtins-amdgcn-dl-insts-err-clamp.cl b/test/CodeGenOpenCL/builtins-amdgcn-dl-insts-err-clamp.cl
new file mode 100644
index 000000000000..f8356feb5112
--- /dev/null
+++ b/test/CodeGenOpenCL/builtins-amdgcn-dl-insts-err-clamp.cl
@@ -0,0 +1,25 @@
+// REQUIRES: amdgpu-registered-target
+
+// RUN: %clang_cc1 -triple amdgcn-unknown-unknown -target-cpu gfx906 -verify -S -emit-llvm -o - %s
+
+typedef unsigned int uint;
+typedef half __attribute__((ext_vector_type(2))) half2;
+typedef short __attribute__((ext_vector_type(2))) short2;
+typedef unsigned short __attribute__((ext_vector_type(2))) ushort2;
+
+kernel void builtins_amdgcn_dl_insts_err(
+ global float *fOut, global int *siOut, global uint *uiOut,
+ half2 v2hA, half2 v2hB, float fC,
+ short2 v2ssA, short2 v2ssB, int siA, int siB, int siC,
+ ushort2 v2usA, ushort2 v2usB, uint uiA, uint uiB, uint uiC, uint isClamp) {
+ fOut[0] = __builtin_amdgcn_fdot2(v2hA, v2hB, fC, isClamp == 0 ? false : true); // expected-error {{'__builtin_amdgcn_fdot2' must be a constant integer}}
+
+ siOut[0] = __builtin_amdgcn_sdot2(v2ssA, v2ssB, siC, isClamp == 0 ? false : true); // expected-error {{'__builtin_amdgcn_sdot2' must be a constant integer}}
+ uiOut[0] = __builtin_amdgcn_udot2(v2usA, v2usB, uiC, isClamp == 0 ? false : true); // expected-error {{'__builtin_amdgcn_udot2' must be a constant integer}}
+
+ siOut[1] = __builtin_amdgcn_sdot4(siA, siB, siC, isClamp == 0 ? false : true); // expected-error {{'__builtin_amdgcn_sdot4' must be a constant integer}}
+ uiOut[1] = __builtin_amdgcn_udot4(uiA, uiB, uiC, isClamp == 0 ? false : true); // expected-error {{'__builtin_amdgcn_udot4' must be a constant integer}}
+
+ siOut[2] = __builtin_amdgcn_sdot8(siA, siB, siC, isClamp == 0 ? false : true); // expected-error {{'__builtin_amdgcn_sdot8' must be a constant integer}}
+ uiOut[2] = __builtin_amdgcn_udot8(uiA, uiB, uiC, isClamp == 0 ? false : true); // expected-error {{'__builtin_amdgcn_udot8' must be a constant integer}}
+}
diff --git a/test/CodeGenOpenCL/builtins-amdgcn-dl-insts-err.cl b/test/CodeGenOpenCL/builtins-amdgcn-dl-insts-err.cl
index bfc811e29556..ca3f4006e300 100644
--- a/test/CodeGenOpenCL/builtins-amdgcn-dl-insts-err.cl
+++ b/test/CodeGenOpenCL/builtins-amdgcn-dl-insts-err.cl
@@ -12,14 +12,24 @@ kernel void builtins_amdgcn_dl_insts_err(
half2 v2hA, half2 v2hB, float fC,
short2 v2ssA, short2 v2ssB, int siA, int siB, int siC,
ushort2 v2usA, ushort2 v2usB, uint uiA, uint uiB, uint uiC) {
- fOut[0] = __builtin_amdgcn_fdot2(v2hA, v2hB, fC); // expected-error {{'__builtin_amdgcn_fdot2' needs target feature dl-insts}}
+ fOut[0] = __builtin_amdgcn_fdot2(v2hA, v2hB, fC, false); // expected-error {{'__builtin_amdgcn_fdot2' needs target feature dl-insts}}
+ fOut[1] = __builtin_amdgcn_fdot2(v2hA, v2hB, fC, true); // expected-error {{'__builtin_amdgcn_fdot2' needs target feature dl-insts}}
- siOut[0] = __builtin_amdgcn_sdot2(v2ssA, v2ssB, siC); // expected-error {{'__builtin_amdgcn_sdot2' needs target feature dl-insts}}
- uiOut[0] = __builtin_amdgcn_udot2(v2usA, v2usB, uiC); // expected-error {{'__builtin_amdgcn_udot2' needs target feature dl-insts}}
+ siOut[0] = __builtin_amdgcn_sdot2(v2ssA, v2ssB, siC, false); // expected-error {{'__builtin_amdgcn_sdot2' needs target feature dl-insts}}
+ siOut[1] = __builtin_amdgcn_sdot2(v2ssA, v2ssB, siC, true); // expected-error {{'__builtin_amdgcn_sdot2' needs target feature dl-insts}}
- siOut[1] = __builtin_amdgcn_sdot4(siA, siB, siC); // expected-error {{'__builtin_amdgcn_sdot4' needs target feature dl-insts}}
- uiOut[1] = __builtin_amdgcn_udot4(uiA, uiB, uiC); // expected-error {{'__builtin_amdgcn_udot4' needs target feature dl-insts}}
+ uiOut[0] = __builtin_amdgcn_udot2(v2usA, v2usB, uiC, false); // expected-error {{'__builtin_amdgcn_udot2' needs target feature dl-insts}}
+ uiOut[1] = __builtin_amdgcn_udot2(v2usA, v2usB, uiC, true); // expected-error {{'__builtin_amdgcn_udot2' needs target feature dl-insts}}
- siOut[2] = __builtin_amdgcn_sdot8(siA, siB, siC); // expected-error {{'__builtin_amdgcn_sdot8' needs target feature dl-insts}}
- uiOut[2] = __builtin_amdgcn_udot8(uiA, uiB, uiC); // expected-error {{'__builtin_amdgcn_udot8' needs target feature dl-insts}}
+ siOut[2] = __builtin_amdgcn_sdot4(siA, siB, siC, false); // expected-error {{'__builtin_amdgcn_sdot4' needs target feature dl-insts}}
+ siOut[3] = __builtin_amdgcn_sdot4(siA, siB, siC, true); // expected-error {{'__builtin_amdgcn_sdot4' needs target feature dl-insts}}
+
+ uiOut[2] = __builtin_amdgcn_udot4(uiA, uiB, uiC, false); // expected-error {{'__builtin_amdgcn_udot4' needs target feature dl-insts}}
+ uiOut[3] = __builtin_amdgcn_udot4(uiA, uiB, uiC, true); // expected-error {{'__builtin_amdgcn_udot4' needs target feature dl-insts}}
+
+ siOut[4] = __builtin_amdgcn_sdot8(siA, siB, siC, false); // expected-error {{'__builtin_amdgcn_sdot8' needs target feature dl-insts}}
+ siOut[5] = __builtin_amdgcn_sdot8(siA, siB, siC, true); // expected-error {{'__builtin_amdgcn_sdot8' needs target feature dl-insts}}
+
+ uiOut[4] = __builtin_amdgcn_udot8(uiA, uiB, uiC, false); // expected-error {{'__builtin_amdgcn_udot8' needs target feature dl-insts}}
+ uiOut[5] = __builtin_amdgcn_udot8(uiA, uiB, uiC, true); // expected-error {{'__builtin_amdgcn_udot8' needs target feature dl-insts}}
}
diff --git a/test/CodeGenOpenCL/builtins-amdgcn-dl-insts.cl b/test/CodeGenOpenCL/builtins-amdgcn-dl-insts.cl
index c407bd6fe155..e5633fb8f400 100644
--- a/test/CodeGenOpenCL/builtins-amdgcn-dl-insts.cl
+++ b/test/CodeGenOpenCL/builtins-amdgcn-dl-insts.cl
@@ -8,29 +8,49 @@ typedef short __attribute__((ext_vector_type(2))) short2;
typedef unsigned short __attribute__((ext_vector_type(2))) ushort2;
// CHECK-LABEL: @builtins_amdgcn_dl_insts
-// CHECK: call float @llvm.amdgcn.fdot2
+// CHECK: call float @llvm.amdgcn.fdot2(<2 x half> %v2hA, <2 x half> %v2hB, float %fC, i1 false)
+// CHECK: call float @llvm.amdgcn.fdot2(<2 x half> %v2hA, <2 x half> %v2hB, float %fC, i1 true)
-// CHECK: call i32 @llvm.amdgcn.sdot2
-// CHECK: call i32 @llvm.amdgcn.udot2
+// CHECK: call i32 @llvm.amdgcn.sdot2(<2 x i16> %v2ssA, <2 x i16> %v2ssB, i32 %siC, i1 false)
+// CHECK: call i32 @llvm.amdgcn.sdot2(<2 x i16> %v2ssA, <2 x i16> %v2ssB, i32 %siC, i1 true)
-// CHECK: call i32 @llvm.amdgcn.sdot4
-// CHECK: call i32 @llvm.amdgcn.udot4
+// CHECK: call i32 @llvm.amdgcn.udot2(<2 x i16> %v2usA, <2 x i16> %v2usB, i32 %uiC, i1 false)
+// CHECK: call i32 @llvm.amdgcn.udot2(<2 x i16> %v2usA, <2 x i16> %v2usB, i32 %uiC, i1 true)
-// CHECK: call i32 @llvm.amdgcn.sdot8
-// CHECK: call i32 @llvm.amdgcn.udot8
+// CHECK: call i32 @llvm.amdgcn.sdot4(i32 %siA, i32 %siB, i32 %siC, i1 false)
+// CHECK: call i32 @llvm.amdgcn.sdot4(i32 %siA, i32 %siB, i32 %siC, i1 true)
+
+// CHECK: call i32 @llvm.amdgcn.udot4(i32 %uiA, i32 %uiB, i32 %uiC, i1 false)
+// CHECK: call i32 @llvm.amdgcn.udot4(i32 %uiA, i32 %uiB, i32 %uiC, i1 true)
+
+// CHECK: call i32 @llvm.amdgcn.sdot8(i32 %siA, i32 %siB, i32 %siC, i1 false)
+// CHECK: call i32 @llvm.amdgcn.sdot8(i32 %siA, i32 %siB, i32 %siC, i1 true)
+
+// CHECK: call i32 @llvm.amdgcn.udot8(i32 %uiA, i32 %uiB, i32 %uiC, i1 false)
+// CHECK: call i32 @llvm.amdgcn.udot8(i32 %uiA, i32 %uiB, i32 %uiC, i1 true)
kernel void builtins_amdgcn_dl_insts(
global float *fOut, global int *siOut, global uint *uiOut,
half2 v2hA, half2 v2hB, float fC,
short2 v2ssA, short2 v2ssB, int siA, int siB, int siC,
ushort2 v2usA, ushort2 v2usB, uint uiA, uint uiB, uint uiC) {
- fOut[0] = __builtin_amdgcn_fdot2(v2hA, v2hB, fC);
+ fOut[0] = __builtin_amdgcn_fdot2(v2hA, v2hB, fC, false);
+ fOut[1] = __builtin_amdgcn_fdot2(v2hA, v2hB, fC, true);
+
+ siOut[0] = __builtin_amdgcn_sdot2(v2ssA, v2ssB, siC, false);
+ siOut[1] = __builtin_amdgcn_sdot2(v2ssA, v2ssB, siC, true);
+
+ uiOut[0] = __builtin_amdgcn_udot2(v2usA, v2usB, uiC, false);
+ uiOut[1] = __builtin_amdgcn_udot2(v2usA, v2usB, uiC, true);
+
+ siOut[2] = __builtin_amdgcn_sdot4(siA, siB, siC, false);
+ siOut[3] = __builtin_amdgcn_sdot4(siA, siB, siC, true);
- siOut[0] = __builtin_amdgcn_sdot2(v2ssA, v2ssB, siC);
- uiOut[0] = __builtin_amdgcn_udot2(v2usA, v2usB, uiC);
+ uiOut[2] = __builtin_amdgcn_udot4(uiA, uiB, uiC, false);
+ uiOut[3] = __builtin_amdgcn_udot4(uiA, uiB, uiC, true);
- siOut[1] = __builtin_amdgcn_sdot4(siA, siB, siC);
- uiOut[1] = __builtin_amdgcn_udot4(uiA, uiB, uiC);
+ siOut[4] = __builtin_amdgcn_sdot8(siA, siB, siC, false);
+ siOut[5] = __builtin_amdgcn_sdot8(siA, siB, siC, true);
- siOut[2] = __builtin_amdgcn_sdot8(siA, siB, siC);
- uiOut[2] = __builtin_amdgcn_udot8(uiA, uiB, uiC);
+ uiOut[4] = __builtin_amdgcn_udot8(uiA, uiB, uiC, false);
+ uiOut[5] = __builtin_amdgcn_udot8(uiA, uiB, uiC, true);
}
diff --git a/test/Driver/Inputs/basic_riscv32_tree/bin/riscv32-unknown-elf-ld b/test/Driver/Inputs/basic_riscv32_tree/bin/riscv32-unknown-elf-ld
new file mode 100755
index 000000000000..b23e55619b2f
--- /dev/null
+++ b/test/Driver/Inputs/basic_riscv32_tree/bin/riscv32-unknown-elf-ld
@@ -0,0 +1 @@
+#!/bin/true
diff --git a/test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.asan_ios_dynamic.dylib b/test/Driver/Inputs/basic_riscv32_tree/lib/gcc/riscv32-unknown-elf/8.0.1/crtbegin.o
index e69de29bb2d1..e69de29bb2d1 100644
--- a/test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.asan_ios_dynamic.dylib
+++ b/test/Driver/Inputs/basic_riscv32_tree/lib/gcc/riscv32-unknown-elf/8.0.1/crtbegin.o
diff --git a/test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.asan_iossim_dynamic.dylib b/test/Driver/Inputs/basic_riscv32_tree/lib/gcc/riscv32-unknown-elf/8.0.1/crtend.o
index e69de29bb2d1..e69de29bb2d1 100644
--- a/test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.asan_iossim_dynamic.dylib
+++ b/test/Driver/Inputs/basic_riscv32_tree/lib/gcc/riscv32-unknown-elf/8.0.1/crtend.o
diff --git a/test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.asan_osx_dynamic.dylib b/test/Driver/Inputs/basic_riscv32_tree/riscv32-unknown-elf/include/c++/8.0.1/.keep
index e69de29bb2d1..e69de29bb2d1 100644
--- a/test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.asan_osx_dynamic.dylib
+++ b/test/Driver/Inputs/basic_riscv32_tree/riscv32-unknown-elf/include/c++/8.0.1/.keep
diff --git a/test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.asan_tvos_dynamic.dylib b/test/Driver/Inputs/basic_riscv32_tree/riscv32-unknown-elf/lib/crt0.o
index e69de29bb2d1..e69de29bb2d1 100644
--- a/test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.asan_tvos_dynamic.dylib
+++ b/test/Driver/Inputs/basic_riscv32_tree/riscv32-unknown-elf/lib/crt0.o
diff --git a/test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.asan_tvossim_dynamic.dylib b/test/Driver/Inputs/openembedded_aarch64_linux_tree/usr/include/c++/6.3.0/backward/.keep
index e69de29bb2d1..e69de29bb2d1 100644
--- a/test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.asan_tvossim_dynamic.dylib
+++ b/test/Driver/Inputs/openembedded_aarch64_linux_tree/usr/include/c++/6.3.0/backward/.keep
diff --git a/test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.asan_watchos_dynamic.dylib b/test/Driver/Inputs/openembedded_aarch64_linux_tree/usr/lib64/aarch64-oe-linux/6.3.0/crtbegin.o
index e69de29bb2d1..e69de29bb2d1 100644
--- a/test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.asan_watchos_dynamic.dylib
+++ b/test/Driver/Inputs/openembedded_aarch64_linux_tree/usr/lib64/aarch64-oe-linux/6.3.0/crtbegin.o
diff --git a/test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.asan_watchossim_dynamic.dylib b/test/Driver/Inputs/openembedded_aarch64_linux_tree/usr/lib64/aarch64-oe-linux/6.3.0/crtend.o
index e69de29bb2d1..e69de29bb2d1 100644
--- a/test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.asan_watchossim_dynamic.dylib
+++ b/test/Driver/Inputs/openembedded_aarch64_linux_tree/usr/lib64/aarch64-oe-linux/6.3.0/crtend.o
diff --git a/test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.fuzzer_osx.a b/test/Driver/Inputs/openembedded_aarch64_linux_tree/usr/lib64/crt1.o
index e69de29bb2d1..e69de29bb2d1 100644
--- a/test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.fuzzer_osx.a
+++ b/test/Driver/Inputs/openembedded_aarch64_linux_tree/usr/lib64/crt1.o
diff --git a/test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.lsan_ios_dynamic.dylib b/test/Driver/Inputs/openembedded_aarch64_linux_tree/usr/lib64/crti.o
index e69de29bb2d1..e69de29bb2d1 100644
--- a/test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.lsan_ios_dynamic.dylib
+++ b/test/Driver/Inputs/openembedded_aarch64_linux_tree/usr/lib64/crti.o
diff --git a/test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.lsan_iossim_dynamic.dylib b/test/Driver/Inputs/openembedded_aarch64_linux_tree/usr/lib64/crtn.o
index e69de29bb2d1..e69de29bb2d1 100644
--- a/test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.lsan_iossim_dynamic.dylib
+++ b/test/Driver/Inputs/openembedded_aarch64_linux_tree/usr/lib64/crtn.o
diff --git a/test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.lsan_osx_dynamic.dylib b/test/Driver/Inputs/openembedded_arm_linux_tree/usr/include/c++/6.3.0/backward/.keep
index e69de29bb2d1..e69de29bb2d1 100644
--- a/test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.lsan_osx_dynamic.dylib
+++ b/test/Driver/Inputs/openembedded_arm_linux_tree/usr/include/c++/6.3.0/backward/.keep
diff --git a/test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.lsan_tvossim_dynamic.dylib b/test/Driver/Inputs/openembedded_arm_linux_tree/usr/lib/arm-oe-linux-gnueabi/6.3.0/crtbegin.o
index e69de29bb2d1..e69de29bb2d1 100644
--- a/test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.lsan_tvossim_dynamic.dylib
+++ b/test/Driver/Inputs/openembedded_arm_linux_tree/usr/lib/arm-oe-linux-gnueabi/6.3.0/crtbegin.o
diff --git a/test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.tsan_iossim_dynamic.dylib b/test/Driver/Inputs/openembedded_arm_linux_tree/usr/lib/arm-oe-linux-gnueabi/6.3.0/crtend.o
index e69de29bb2d1..e69de29bb2d1 100644
--- a/test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.tsan_iossim_dynamic.dylib
+++ b/test/Driver/Inputs/openembedded_arm_linux_tree/usr/lib/arm-oe-linux-gnueabi/6.3.0/crtend.o
diff --git a/test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.tsan_osx_dynamic.dylib b/test/Driver/Inputs/openembedded_arm_linux_tree/usr/lib/crt1.o
index e69de29bb2d1..e69de29bb2d1 100644
--- a/test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.tsan_osx_dynamic.dylib
+++ b/test/Driver/Inputs/openembedded_arm_linux_tree/usr/lib/crt1.o
diff --git a/test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.tsan_tvossim_dynamic.dylib b/test/Driver/Inputs/openembedded_arm_linux_tree/usr/lib/crti.o
index e69de29bb2d1..e69de29bb2d1 100644
--- a/test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.tsan_tvossim_dynamic.dylib
+++ b/test/Driver/Inputs/openembedded_arm_linux_tree/usr/lib/crti.o
diff --git a/test/Driver/Inputs/openembedded_arm_linux_tree/usr/lib/crtn.o b/test/Driver/Inputs/openembedded_arm_linux_tree/usr/lib/crtn.o
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/test/Driver/Inputs/openembedded_arm_linux_tree/usr/lib/crtn.o
diff --git a/test/Driver/aarch64-cpus.c b/test/Driver/aarch64-cpus.c
index 330af351182d..d3cb35fa1030 100644
--- a/test/Driver/aarch64-cpus.c
+++ b/test/Driver/aarch64-cpus.c
@@ -388,6 +388,14 @@
// RUN: %clang -target aarch64_be -mlittle-endian -march=armv8.2-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV82A %s
// GENERICV82A: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v8.2a"
+// RUN: %clang -target aarch64_be -march=armv8.2a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV82A-BE %s
+// RUN: %clang -target aarch64_be -march=armv8.2-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV82A-BE %s
+// RUN: %clang -target aarch64 -mbig-endian -march=armv8.2a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV82A-BE %s
+// RUN: %clang -target aarch64 -mbig-endian -march=armv8.2-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV82A-BE %s
+// RUN: %clang -target aarch64_be -mbig-endian -march=armv8.2a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV82A-BE %s
+// RUN: %clang -target aarch64_be -mbig-endian -march=armv8.2-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV82A-BE %s
+// GENERICV82A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v8.2a"
+
// RUN: %clang -target aarch64 -march=armv8.2-a+fp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV82A-FP16 %s
// GENERICV82A-FP16: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v8.2a" "-target-feature" "+fullfp16"
@@ -397,6 +405,71 @@
// RUN: %clang -target aarch64 -march=armv8.2-a+fp16+profile -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV82A-FP16-SPE %s
// GENERICV82A-FP16-SPE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v8.2a" "-target-feature" "+fullfp16" "-target-feature" "+spe"
+// RUN: %clang -target aarch64 -march=armv8.3a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV83A %s
+// RUN: %clang -target aarch64 -march=armv8.3-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV83A %s
+// RUN: %clang -target aarch64 -mlittle-endian -march=armv8.3a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV83A %s
+// RUN: %clang -target aarch64 -mlittle-endian -march=armv8.3-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV83A %s
+// RUN: %clang -target aarch64_be -mlittle-endian -march=armv8.3a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV83A %s
+// RUN: %clang -target aarch64_be -mlittle-endian -march=armv8.3-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV83A %s
+// GENERICV83A: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v8.3a"
+
+// RUN: %clang -target aarch64_be -march=armv8.3a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV83A-BE %s
+// RUN: %clang -target aarch64_be -march=armv8.3-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV83A-BE %s
+// RUN: %clang -target aarch64 -mbig-endian -march=armv8.3a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV83A-BE %s
+// RUN: %clang -target aarch64 -mbig-endian -march=armv8.3-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV83A-BE %s
+// RUN: %clang -target aarch64_be -mbig-endian -march=armv8.3a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV83A-BE %s
+// RUN: %clang -target aarch64_be -mbig-endian -march=armv8.3-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV83A-BE %s
+// GENERICV83A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v8.3a"
+
+// RUN: %clang -target aarch64 -march=armv8.3-a+fp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV83A-FP16 %s
+// GENERICV83A-FP16: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v8.3a" "-target-feature" "+fullfp16"
+
+// RUN: %clang -target aarch64 -march=armv8.4a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV84A %s
+// RUN: %clang -target aarch64 -march=armv8.4-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV84A %s
+// RUN: %clang -target aarch64 -mlittle-endian -march=armv8.4a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV84A %s
+// RUN: %clang -target aarch64 -mlittle-endian -march=armv8.4-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV84A %s
+// RUN: %clang -target aarch64_be -mlittle-endian -march=armv8.4a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV84A %s
+// RUN: %clang -target aarch64_be -mlittle-endian -march=armv8.4-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV84A %s
+// GENERICV84A: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v8.4a"
+
+// RUN: %clang -target aarch64_be -march=armv8.4a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV84A-BE %s
+// RUN: %clang -target aarch64_be -march=armv8.4-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV84A-BE %s
+// RUN: %clang -target aarch64 -mbig-endian -march=armv8.4a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV84A-BE %s
+// RUN: %clang -target aarch64 -mbig-endian -march=armv8.4-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV84A-BE %s
+// RUN: %clang -target aarch64_be -mbig-endian -march=armv8.4a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV84A-BE %s
+// RUN: %clang -target aarch64_be -mbig-endian -march=armv8.4-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV84A-BE %s
+// GENERICV84A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v8.4a"
+
+// RUN: %clang -target aarch64 -march=armv8.4-a+fp16 -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV84A-FP16 %s
+// GENERICV84A-FP16: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v8.4a" "-target-feature" "+fullfp16"
+
+// fullfp16 is not specified by default for v8.2a, and can be enabled by +fp16
+// RUN: %clang -target aarch64 -march=armv8.2a -### -c %s 2>&1 | FileCheck -check-prefix=V82ANOFP16 -check-prefix=GENERICV82A %s
+// RUN: %clang -target aarch64 -march=armv8.2-a -### -c %s 2>&1 | FileCheck -check-prefix=V82ANOFP16 -check-prefix=GENERICV82A %s
+// V82ANOFP16-NOT: "-target-feature" "-fullfp16"
+// V82ANOFP16-NOT: "-target-feature" "+fullfp16"
+// RUN: %clang -target aarch64 -march=armv8.2a+fp16 -### -c %s 2>&1 | FileCheck -check-prefix=V82AFP16 -check-prefix=GENERICV82A %s
+// RUN: %clang -target aarch64 -march=armv8.2-a+fp16 -### -c %s 2>&1 | FileCheck -check-prefix=V82AFP16 -check-prefix=GENERICV82A %s
+// V82AFP16: "-target-feature" "+fullfp16"
+
+// fullfp16 is off by default for v8a, feature must not be mentioned
+// RUN: %clang -target aarch64 -march=armv8a -### -c %s 2>&1 | FileCheck -check-prefix=V82ANOFP16 -check-prefix=GENERIC %s
+// RUN: %clang -target aarch64 -march=armv8-a -### -c %s 2>&1 | FileCheck -check-prefix=V82ANOFP16 -check-prefix=GENERIC %s
+
+// RAS is on by default for v8.2a, but can be disabled by +noras
+// RUN: %clang -target aarch64 -march=armv8.2a -### -c %s 2>&1 | FileCheck -check-prefix=V82ARAS -check-prefix=GENERICV82A %s
+// RUN: %clang -target aarch64 -march=armv8.2-a -### -c %s 2>&1 | FileCheck -check-prefix=V82ARAS -check-prefix=GENERICV82A %s
+// V82ARAS-NOT: "-target-feature" "+ras"
+// V82ARAS-NOT: "-target-feature" "-ras"
+// RUN: %clang -target aarch64 -march=armv8.2a+noras -### -c %s 2>&1 | FileCheck -check-prefix=V82ANORAS -check-prefix=GENERICV82A %s
+// RUN: %clang -target aarch64 -march=armv8.2-a+noras -### -c %s 2>&1 | FileCheck -check-prefix=V82ANORAS -check-prefix=GENERICV82A %s
+// V82ANORAS: "-target-feature" "-ras"
+
+// RAS is off by default for v8a, but can be enabled by +ras (this is not architecturally valid)
+// RUN: %clang -target aarch64 -march=armv8a+ras -### -c %s 2>&1 | FileCheck -check-prefix=V8ARAS -check-prefix=GENERIC %s
+// RUN: %clang -target aarch64 -march=armv8-a+ras -### -c %s 2>&1 | FileCheck -check-prefix=V8ARAS -check-prefix=GENERIC %s
+// V8ARAS: "-target-feature" "+ras"
+
// ================== Check whether -march accepts mixed-case values.
// RUN: %clang -target aarch64_be -march=ARMV8.1A -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV81A-BE %s
// RUN: %clang -target aarch64_be -march=ARMV8.1-A -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV81A-BE %s
diff --git a/test/Driver/arm-cortex-cpus.c b/test/Driver/arm-cortex-cpus.c
index 90542326f36c..541a1e4e4e58 100644
--- a/test/Driver/arm-cortex-cpus.c
+++ b/test/Driver/arm-cortex-cpus.c
@@ -287,6 +287,46 @@
// RUN: %clang -target armv8a-linux-eabi -march=armv8.2-a+fp16 -### -c %s 2>&1 | FileCheck --check-prefix CHECK-V82A-FP16 %s
// CHECK-V82A-FP16: "-cc1"{{.*}} "-triple" "armv8.2{{.*}}" "-target-cpu" "generic" {{.*}}"-target-feature" "+fullfp16"
+// RUN: %clang -target armv8.3a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V83A %s
+// RUN: %clang -target arm -march=armv8.3a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V83A %s
+// RUN: %clang -target arm -march=armv8.3-a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V83A %s
+// RUN: %clang -target arm -march=armv8.3a -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V83A %s
+// RUN: %clang -target armv8.3a -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V83A %s
+// RUN: %clang -target arm -march=armv8.3a -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V83A %s
+// RUN: %clang -target arm -mlittle-endian -march=armv8.3-a -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V83A %s
+// CHECK-V83A: "-cc1"{{.*}} "-triple" "armv8.3{{.*}}" "-target-cpu" "generic"
+
+// RUN: %clang -target armebv8.3a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V83A %s
+// RUN: %clang -target armv8.3a -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V83A %s
+// RUN: %clang -target armeb -march=armebv8.3a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V83A %s
+// RUN: %clang -target armeb -march=armebv8.3-a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V83A %s
+// RUN: %clang -target arm -march=armebv8.3a -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V83A %s
+// RUN: %clang -target arm -march=armebv8.3-a -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V83A %s
+// CHECK-BE-V83A: "-cc1"{{.*}} "-triple" "armebv8.3{{.*}}" "-target-cpu" "generic"
+
+// RUN: %clang -target armv8a-linux-eabi -march=armv8.3-a+fp16 -### -c %s 2>&1 | FileCheck --check-prefix CHECK-V83A-FP16 %s
+// CHECK-V83A-FP16: "-cc1"{{.*}} "-triple" "armv8.3{{.*}}" "-target-cpu" "generic" {{.*}}"-target-feature" "+fullfp16"
+
+// RUN: %clang -target armv8.4a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V84A %s
+// RUN: %clang -target arm -march=armv8.4a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V84A %s
+// RUN: %clang -target arm -march=armv8.4-a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V84A %s
+// RUN: %clang -target arm -march=armv8.4a -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V84A %s
+// RUN: %clang -target armv8.4a -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V84A %s
+// RUN: %clang -target arm -march=armv8.4a -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V84A %s
+// RUN: %clang -target arm -mlittle-endian -march=armv8.4-a -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V84A %s
+// CHECK-V84A: "-cc1"{{.*}} "-triple" "armv8.4{{.*}}" "-target-cpu" "generic"
+
+// RUN: %clang -target armebv8.4a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V84A %s
+// RUN: %clang -target armv8.4a -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V84A %s
+// RUN: %clang -target armeb -march=armebv8.4a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V84A %s
+// RUN: %clang -target armeb -march=armebv8.4-a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V84A %s
+// RUN: %clang -target arm -march=armebv8.4a -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V84A %s
+// RUN: %clang -target arm -march=armebv8.4-a -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V84A %s
+// CHECK-BE-V84A: "-cc1"{{.*}} "-triple" "armebv8.4{{.*}}" "-target-cpu" "generic"
+
+// RUN: %clang -target armv8a-linux-eabi -march=armv8.4-a+fp16 -### -c %s 2>&1 | FileCheck --check-prefix CHECK-V84A-FP16 %s
+// CHECK-V84A-FP16: "-cc1"{{.*}} "-triple" "armv8.4{{.*}}" "-target-cpu" "generic" {{.*}}"-target-feature" "+fullfp16"
+
// Once we have CPUs with optional v8.2-A FP16, we will need a way to turn it
// on and off. Cortex-A53 is a placeholder for now.
// RUN: %clang -target armv8a-linux-eabi -mcpu=cortex-a53+fp16 -### -c %s 2>&1 | FileCheck --check-prefix CHECK-CORTEX-A53-FP16 %s
@@ -294,6 +334,15 @@
// CHECK-CORTEX-A53-FP16: "-cc1" {{.*}}"-target-cpu" "cortex-a53" {{.*}}"-target-feature" "+fullfp16"
// CHECK-CORTEX-A53-NOFP16: "-cc1" {{.*}}"-target-cpu" "cortex-a53" {{.*}}"-target-feature" "-fullfp16"
+// RAS is on by default for v8.2-a (this is handled in the backend), but can be
+// optionally enabled for v8.0-a and v8.1-a. Cortex-A53 does not have RAS, but
+// is used here to check that this option will work on any future CPUs that may
+// have optional RAS.
+// RUN: %clang -target armv8a -march=armv8-a+ras -### -c %s 2>&1 | FileCheck -check-prefix=RAS %s
+// RUN: %clang -target armv8a -march=armv8.1-a+ras -### -c %s 2>&1 | FileCheck -check-prefix=RAS %s
+// RUN: %clang -target armv8a -mcpu=cortex-a53+ras -### -c %s 2>&1 | FileCheck -check-prefix=RAS %s
+// RAS: "-target-feature" "+ras"
+
// RUN: %clang -target armv8m.base %s -### -c 2>&1 | FileCheck %s --check-prefix=V8M_BASELINE
// RUN: %clang -target arm -march=armv8-m.base %s -### -c 2>&1 | FileCheck %s --check-prefix=V8M_BASELINE
// RUN: %clang -target arm -march=armv8m.base %s -### -c 2>&1 | FileCheck %s --check-prefix=V8M_BASELINE
diff --git a/test/Driver/baremetal.cpp b/test/Driver/baremetal.cpp
index a433e2df07cb..2e93734651e8 100644
--- a/test/Driver/baremetal.cpp
+++ b/test/Driver/baremetal.cpp
@@ -10,7 +10,7 @@
// CHECK-V6M-C-SAME: "-internal-isystem" "[[SYSROOT]]{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}v1"
// CHECk-V6M-C-SAME: "-internal-isystem" "[[SYSROOT]]{{[/\\]+}}include"
// CHECK-V6M-C-SAME: "-x" "c++" "{{.*}}baremetal.cpp"
-// CHECK-V6M-C-NEXT: "{{[^"]*}}ld.lld{{(\.exe)?}}" "{{.*}}.o" "-Bstatic"
+// CHECK-V6M-C-NEXT: "{{[^"]*}}ld{{(\.(lld|bfd|gold))?}}{{(\.exe)?}}" "{{.*}}.o" "-Bstatic"
// CHECK-V6M-C-SAME: "-L[[RESOURCE_DIR:[^"]+]]{{[/\\]+}}lib{{[/\\]+}}baremetal"
// CHECK-V6M-C-SAME: "-T" "semihosted.lds" "-Lsome{{[/\\]+}}directory{{[/\\]+}}user{{[/\\]+}}asked{{[/\\]+}}for"
// CHECK-V6M-C-SAME: "-lc" "-lm" "-lclang_rt.builtins-armv6m.a"
@@ -32,7 +32,7 @@
// RUN: -target armv6m-none-eabi \
// RUN: --sysroot=%S/Inputs/baremetal_arm \
// RUN: | FileCheck --check-prefix=CHECK-V6M-DEFAULTCXX %s
-// CHECK-V6M-DEFAULTCXX: "{{[^"]*}}ld.lld{{(\.exe)?}}" "{{.*}}.o" "-Bstatic"
+// CHECK-V6M-DEFAULTCXX: "{{[^"]*}}ld{{(\.(lld|bfd|gold))?}}{{(\.exe)?}}" "{{.*}}.o" "-Bstatic"
// CHECK-V6M-DEFAULTCXX-SAME: "-L{{[^"]*}}{{[/\\]+}}lib{{(64)?}}{{[/\\]+}}clang{{[/\\]+}}{{.*}}{{[/\\]+}}lib{{[/\\]+}}baremetal"
// CHECK-V6M-DEFAULTCXX-SAME: "-lc++" "-lc++abi" "-lunwind"
// CHECK-V6M-DEFAULTCXX-SAME: "-lc" "-lm" "-lclang_rt.builtins-armv6m.a"
@@ -45,7 +45,7 @@
// RUN: | FileCheck --check-prefix=CHECK-V6M-LIBCXX %s
// CHECK-V6M-LIBCXX-NOT: "-internal-isystem" "{{[^"]+}}{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}{{[^v].*}}"
// CHECK-V6M-LIBCXX: "-internal-isystem" "{{[^"]+}}{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}v1"
-// CHECK-V6M-LIBCXX: "{{[^"]*}}ld.lld{{(\.exe)?}}" "{{.*}}.o" "-Bstatic"
+// CHECK-V6M-LIBCXX: "{{[^"]*}}ld{{(\.(lld|bfd|gold))?}}{{(\.exe)?}}" "{{.*}}.o" "-Bstatic"
// CHECK-V6M-LIBCXX-SAME: "-L{{[^"]*}}{{[/\\]+}}lib{{(64)?}}{{[/\\]+}}clang{{[/\\]+}}{{.*}}{{[/\\]+}}lib{{[/\\]+}}baremetal"
// CHECK-V6M-LIBCXX-SAME: "-lc++" "-lc++abi" "-lunwind"
// CHECK-V6M-LIBCXX-SAME: "-lc" "-lm" "-lclang_rt.builtins-armv6m.a"
@@ -58,7 +58,7 @@
// RUN: | FileCheck --check-prefix=CHECK-V6M-LIBSTDCXX %s
// CHECK-V6M-LIBSTDCXX-NOT: "-internal-isystem" "{{[^"]+}}{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}v1"
// CHECK-V6M-LIBSTDCXX: "-internal-isystem" "{{[^"]+}}{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}6.0.0"
-// CHECK-V6M-LIBSTDCXX: "{{[^"]*}}ld.lld{{(\.exe)?}}" "{{.*}}.o" "-Bstatic"
+// CHECK-V6M-LIBSTDCXX: "{{[^"]*}}ld{{(\.(lld|bfd|gold))?}}{{(\.exe)?}}" "{{.*}}.o" "-Bstatic"
// CHECK-V6M-LIBSTDCXX-SAME: "-L{{[^"]*}}{{[/\\]+}}lib{{(64)?}}{{[/\\]+}}clang{{[/\\]+}}{{.*}}{{[/\\]+}}lib{{[/\\]+}}baremetal"
// CHECK-V6M-LIBSTDCXX-SAME: "-lstdc++" "-lsupc++" "-lunwind"
// CHECK-V6M-LIBSTDCXX-SAME: "-lc" "-lm" "-lclang_rt.builtins-armv6m.a"
@@ -69,7 +69,7 @@
// RUN: --sysroot=%S/Inputs/baremetal_arm \
// RUN: -nodefaultlibs \
// RUN: | FileCheck --check-prefix=CHECK-V6M-NDL %s
-// CHECK-V6M-NDL: "{{[^"]*}}ld.lld{{(\.exe)?}}" "{{.*}}.o" "-Bstatic"
+// CHECK-V6M-NDL: "{{[^"]*}}ld{{(\.(lld|bfd|gold))?}}{{(\.exe)?}}" "{{.*}}.o" "-Bstatic"
// CHECK-V6M-NDL-SAME: "-L{{[^"]*}}{{[/\\]+}}lib{{(64)?}}{{[/\\]+}}clang{{[/\\]+}}{{.*}}{{[/\\]+}}lib{{[/\\]+}}baremetal" "-o" "{{.*}}.o"
// RUN: %clangxx -target arm-none-eabi -v 2>&1 \
diff --git a/test/Driver/cuda-dwarf-2.cu b/test/Driver/cuda-dwarf-2.cu
index b6c7f500f5ca..7956e6ddbe23 100644
--- a/test/Driver/cuda-dwarf-2.cu
+++ b/test/Driver/cuda-dwarf-2.cu
@@ -15,6 +15,8 @@
// RUN: %clang -### -target x86_64-linux-gnu -c --cuda-gpu-arch=sm_20 %s -gline-tables-only -O2 --cuda-noopt-device-debug 2>&1 | \
// RUN: FileCheck %s -check-prefix NO_DEBUG -check-prefix LINE_TABLE
+// NO_DEBUG-NOT: warning: debug
+// LINE_TABLE-NOT: warning: debug
// NO_DEBUG: ptxas
// NO_DEBUG-NOT: "-g"
// LINE_TABLE: "-lineinfo"
@@ -36,6 +38,7 @@
// RUN: %clang -### -target x86_64-linux-gnu -c --cuda-gpu-arch=sm_20 %s -ggdb3 -O3 --cuda-noopt-device-debug 2>&1 | \
// RUN: FileCheck %s -check-prefix HAS_DEBUG
+// HAS_DEBUG-NOT: warning: debug
// HAS_DEBUG: "-fcuda-is-device"
// HAS_DEBUG-SAME: "-dwarf-version=2"
// HAS_DEBUG: ptxas
diff --git a/test/Driver/cuda-unsupported-debug-options.cu b/test/Driver/cuda-unsupported-debug-options.cu
new file mode 100644
index 000000000000..3aa1bc0b4711
--- /dev/null
+++ b/test/Driver/cuda-unsupported-debug-options.cu
@@ -0,0 +1,22 @@
+// REQUIRES: clang-driver
+// REQUIRES: x86-registered-target
+// REQUIRES: nvptx-registered-target
+// REQUIRES: zlib
+
+// RUN: %clang -### -target x86_64-linux-gnu -c %s -g -gz 2>&1 | FileCheck %s
+// RUN: %clang -### -target x86_64-linux-gnu -c %s -gdwarf -fdebug-info-for-profiling 2>&1 | FileCheck %s
+// RUN: %clang -### -target x86_64-linux-gnu -c %s -gdwarf-2 -gsplit-dwarf 2>&1 | FileCheck %s
+// RUN: %clang -### -target x86_64-linux-gnu -c %s -gdwarf-3 -glldb 2>&1 | FileCheck %s
+// RUN: %clang -### -target x86_64-linux-gnu -c %s -gdwarf-4 -gcodeview 2>&1 | FileCheck %s
+// RUN: %clang -### -target x86_64-linux-gnu -c %s -gdwarf-5 -gmodules 2>&1 | FileCheck %s
+// RUN: %clang -### -target x86_64-linux-gnu -c %s -ggdb -gembed-source -gdwarf-5 2>&1 | FileCheck %s
+// RUN: %clang -### -target x86_64-linux-gnu -c %s -ggdb1 -fdebug-macro 2>&1 | FileCheck %s
+// RUN: %clang -### -target x86_64-linux-gnu -c %s -ggdb2 -ggnu-pubnames 2>&1 | FileCheck %s
+// RUN: %clang -### -target x86_64-linux-gnu -c %s -ggdb3 -gdwarf-aranges 2>&1 | FileCheck %s
+// RUN: %clang -### -target x86_64-linux-gnu -c %s -g -gcolumn-info -fdebug-types-section 2>&1 | FileCheck %s
+// CHECK: debug information option '{{-gz|-fdebug-info-for-profiling|-gsplit-dwarf|-glldb|-gcodeview|-gmodules|-gembed-source|-fdebug-macro|-ggnu-pubnames|-gdwarf-aranges|-fdebug-types-section}}' is not supported for target 'nvptx64-nvidia-cuda' [-Wunsupported-target-opt]
+// CHECK-NOT: debug information option '{{.*}}' is not supported for target 'x86
+// CHECK: "-triple" "nvptx64-nvidia-cuda"
+// CHECK-NOT: {{-compress-debug|-fdebug-info-for-profiling|split-dwarf|lldb|codeview|module-format|embed-source|debug-info-macro|gnu-pubnames|generate-arange-section|generate-type-units}}
+// CHECK: "-triple" "x86_64
+// CHECK-SAME: {{-compress-debug|-fdebug-info-for-profiling|split-dwarf|lldb|codeview|module-format|embed-source|debug-info-macro|gnu-pubnames|generate-arange-section|generate-type-units}}
diff --git a/test/Driver/darwin-asan-nofortify.c b/test/Driver/darwin-asan-nofortify.c
index 7d6da6d05798..58b5be9fcbb7 100644
--- a/test/Driver/darwin-asan-nofortify.c
+++ b/test/Driver/darwin-asan-nofortify.c
@@ -1,5 +1,5 @@
// Make sure AddressSanitizer disables _FORTIFY_SOURCE on Darwin.
-// RUN: %clang -fsanitize=address %s -E -dM -target x86_64-darwin -resource-dir %S/Inputs/resource_dir | FileCheck %s
+// RUN: %clang -fsanitize=address %s -E -dM -target x86_64-darwin | FileCheck %s
// CHECK: #define _FORTIFY_SOURCE 0
diff --git a/test/Driver/darwin-sanitizer-ld.c b/test/Driver/darwin-sanitizer-ld.c
index f7dfb157b44e..53c7fce115e7 100644
--- a/test/Driver/darwin-sanitizer-ld.c
+++ b/test/Driver/darwin-sanitizer-ld.c
@@ -1,7 +1,6 @@
// Test sanitizer link flags on Darwin.
// RUN: %clang -no-canonical-prefixes -### -target x86_64-darwin \
-// RUN: -resource-dir %S/Inputs/resource_dir \
// RUN: -stdlib=platform -fsanitize=address %s -o %t.o 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-ASAN %s
@@ -13,14 +12,6 @@
// CHECK-ASAN: "-rpath" "{{.*}}lib{{.*}}darwin"
// RUN: %clang -no-canonical-prefixes -### -target x86_64-darwin \
-// RUN: -resource-dir %S/Inputs/fake_resource_dir \
-// RUN: -stdlib=platform -fsanitize=address %s -o %t.o 2>&1 \
-// RUN: | FileCheck --check-prefix=CHECK-LOAD-FAIL %s
-
-// CHECK-LOAD-FAIL: error: unsupported option '-fsanitize=address' for target 'x86_64--darwin'
-
-// RUN: %clang -no-canonical-prefixes -### -target x86_64-darwin \
-// RUN: -resource-dir %S/Inputs/resource_dir \
// RUN: -fPIC -shared -fsanitize=address %s -o %t.so 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-DYN-ASAN %s
@@ -31,7 +22,6 @@
// CHECK-DYN-ASAN: "-rpath" "{{.*}}lib{{.*}}darwin"
// RUN: %clang -no-canonical-prefixes -### -target x86_64-darwin \
-// RUN: -resource-dir %S/Inputs/resource_dir \
// RUN: -stdlib=platform -fsanitize=undefined %s -o %t.o 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-UBSAN %s
@@ -44,7 +34,6 @@
// RUN: %clang -no-canonical-prefixes -### -target x86_64-darwin \
// RUN: -fsanitize=bounds -fsanitize-undefined-trap-on-error \
-// RUN: -resource-dir %S/Inputs/resource_dir \
// RUN: %s -o %t.o 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-BOUNDS %s
@@ -53,7 +42,6 @@
// RUN: %clang -no-canonical-prefixes -### -target x86_64-darwin \
// RUN: -fPIC -shared -fsanitize=undefined %s -o %t.so 2>&1 \
-// RUN: -resource-dir %S/Inputs/resource_dir \
// RUN: | FileCheck --check-prefix=CHECK-DYN-UBSAN %s
// CHECK-DYN-UBSAN: "{{.*}}ld{{(.exe)?}}"
@@ -64,7 +52,6 @@
// RUN: %clang -no-canonical-prefixes -### -target x86_64-darwin \
// RUN: -fsanitize=bounds -fsanitize-undefined-trap-on-error \
-// RUN: -resource-dir %S/Inputs/resource_dir \
// RUN: %s -o %t.so -fPIC -shared 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-DYN-BOUNDS %s
@@ -73,7 +60,6 @@
// RUN: %clang -no-canonical-prefixes -### -target x86_64-darwin \
// RUN: -stdlib=platform -fsanitize=address -mios-simulator-version-min=7.0 \
-// RUN: -resource-dir %S/Inputs/resource_dir \
// RUN: %s -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-ASAN-IOSSIM %s
// CHECK-ASAN-IOSSIM: "{{.*}}ld{{(.exe)?}}"
@@ -84,7 +70,6 @@
// CHECK-ASAN-IOSSIM: "-rpath" "{{.*}}lib{{.*}}darwin"
// RUN: %clang -no-canonical-prefixes -### -target x86_64-darwin \
-// RUN: -resource-dir %S/Inputs/resource_dir \
// RUN: -stdlib=platform -fsanitize=address \
// RUN: -mtvos-simulator-version-min=8.3.0 %s -o %t.o 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-ASAN-TVOSSIM %s
@@ -98,7 +83,6 @@
// RUN: %clang -no-canonical-prefixes -### -target x86_64-darwin \
// RUN: -stdlib=platform -fsanitize=address \
-// RUN: -resource-dir %S/Inputs/resource_dir \
// RUN: -mwatchos-simulator-version-min=2.0.0 %s -o %t.o 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-ASAN-WATCHOSSIM %s
@@ -110,7 +94,6 @@
// CHECK-ASAN-WATCHOSSIM: "-rpath" "{{.*}}lib{{.*}}darwin"
// RUN: %clang -no-canonical-prefixes -### -target armv7-apple-ios \
-// RUN: -resource-dir %S/Inputs/resource_dir \
// RUN: -stdlib=platform -fsanitize=address -miphoneos-version-min=7 \
// RUN: %s -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-ASAN-IOS %s
@@ -123,7 +106,6 @@
// RUN: %clang -no-canonical-prefixes -### -target arm64-apple-tvos \
// RUN: -stdlib=platform -fsanitize=address -mtvos-version-min=8.3 \
-// RUN: -resource-dir %S/Inputs/resource_dir \
// RUN: %s -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-ASAN-TVOS %s
// CHECK-ASAN-TVOS: "{{.*}}ld{{(.exe)?}}"
@@ -135,7 +117,6 @@
// RUN: %clang -no-canonical-prefixes -### -target armv7k-apple-watchos \
// RUN: -stdlib=platform -fsanitize=address -mwatchos-version-min=2.0 \
-// RUN: -resource-dir %S/Inputs/resource_dir \
// RUN: %s -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-ASAN-WATCHOS %s
// CHECK-ASAN-WATCHOS: "{{.*}}ld{{(.exe)?}}"
diff --git a/test/Driver/fsanitize.c b/test/Driver/fsanitize.c
index e6d94649f065..304e75930245 100644
--- a/test/Driver/fsanitize.c
+++ b/test/Driver/fsanitize.c
@@ -29,7 +29,22 @@
// CHECK-COVERAGE-WIN64: "--dependent-lib={{[^"]*}}ubsan_standalone-x86_64.lib"
// RUN: %clang -target x86_64-linux-gnu -fsanitize=integer %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-INTEGER -implicit-check-not="-fsanitize-address-use-after-scope"
-// CHECK-INTEGER: "-fsanitize={{((signed-integer-overflow|unsigned-integer-overflow|integer-divide-by-zero|shift-base|shift-exponent),?){5}"}}
+// CHECK-INTEGER: "-fsanitize={{((signed-integer-overflow|unsigned-integer-overflow|integer-divide-by-zero|shift-base|shift-exponent|implicit-integer-truncation),?){6}"}}
+
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=implicit-conversion %s -### 2>&1 | FileCheck %s --check-prefixes=CHECK-implicit-conversion,CHECK-implicit-conversion-RECOVER
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=implicit-conversion -fsanitize-recover=implicit-conversion %s -### 2>&1 | FileCheck %s --check-prefixes=CHECK-implicit-conversion,CHECK-implicit-conversion-RECOVER
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=implicit-conversion -fno-sanitize-recover=implicit-conversion %s -### 2>&1 | FileCheck %s --check-prefixes=CHECK-implicit-conversion,CHECK-implicit-conversion-NORECOVER
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=implicit-conversion -fsanitize-trap=implicit-conversion %s -### 2>&1 | FileCheck %s --check-prefixes=CHECK-implicit-conversion,CHECK-implicit-conversion-TRAP
+// CHECK-implicit-conversion: "-fsanitize={{((implicit-integer-truncation),?){1}"}}
+// CHECK-implicit-conversion-RECOVER: "-fsanitize-recover={{((implicit-integer-truncation),?){1}"}}
+// CHECK-implicit-conversion-RECOVER-NOT: "-fno-sanitize-recover={{((implicit-integer-truncation),?){1}"}}
+// CHECK-implicit-conversion-RECOVER-NOT: "-fsanitize-trap={{((implicit-integer-truncation),?){1}"}}
+// CHECK-implicit-conversion-NORECOVER-NOT: "-fno-sanitize-recover={{((implicit-integer-truncation),?){1}"}} // ???
+// CHECK-implicit-conversion-NORECOVER-NOT: "-fsanitize-recover={{((implicit-integer-truncation),?){1}"}}
+// CHECK-implicit-conversion-NORECOVER-NOT: "-fsanitize-trap={{((implicit-integer-truncation),?){1}"}}
+// CHECK-implicit-conversion-TRAP: "-fsanitize-trap={{((implicit-integer-truncation),?){1}"}}
+// CHECK-implicit-conversion-TRAP-NOT: "-fsanitize-recover={{((implicit-integer-truncation),?){1}"}}
+// CHECK-implicit-conversion-TRAP-NOT: "-fno-sanitize-recover={{((implicit-integer-truncation),?){1}"}}
// RUN: %clang -fsanitize=bounds -### -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix=CHECK-BOUNDS
// CHECK-BOUNDS: "-fsanitize={{((array-bounds|local-bounds),?){2}"}}
@@ -343,24 +358,24 @@
// RUN: %clang -target x86_64-apple-darwin10 -fsanitize=memory -fno-sanitize=memory %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-MSAN-NOMSAN-DARWIN
// CHECK-MSAN-NOMSAN-DARWIN-NOT: unsupported option
-// RUN: %clang -target x86_64-apple-darwin10 -fsanitize=memory -fsanitize=thread,memory -resource-dir %S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-MSAN-TSAN-MSAN-DARWIN
+// RUN: %clang -target x86_64-apple-darwin10 -fsanitize=memory -fsanitize=thread,memory %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-MSAN-TSAN-MSAN-DARWIN
// CHECK-MSAN-TSAN-MSAN-DARWIN: unsupported option '-fsanitize=memory' for target 'x86_64-apple-darwin10'
// CHECK-MSAN-TSAN-MSAN-DARWIN-NOT: unsupported option
-// RUN: %clang -target x86_64-apple-darwin10 -fsanitize=thread,memory -fsanitize=memory -resource-dir %S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-MSAN-MSAN-DARWIN
+// RUN: %clang -target x86_64-apple-darwin10 -fsanitize=thread,memory -fsanitize=memory %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-MSAN-MSAN-DARWIN
// CHECK-TSAN-MSAN-MSAN-DARWIN: unsupported option '-fsanitize=memory' for target 'x86_64-apple-darwin10'
// CHECK-TSAN-MSAN-MSAN-DARWIN-NOT: unsupported option
-// RUN: %clang -target x86_64-apple-darwin -fsanitize=thread -resource-dir %S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-X86-64-DARWIN
+// RUN: %clang -target x86_64-apple-darwin -fsanitize=thread %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-X86-64-DARWIN
// CHECK-TSAN-X86-64-DARWIN-NOT: unsupported option
-// RUN: %clang -target x86_64-apple-iossimulator -fsanitize=thread -resource-dir %S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-X86-64-IOSSIMULATOR
+// RUN: %clang -target x86_64-apple-iossimulator -fsanitize=thread %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-X86-64-IOSSIMULATOR
// CHECK-TSAN-X86-64-IOSSIMULATOR-NOT: unsupported option
-// RUN: %clang -target x86_64-apple-tvossimulator -fsanitize=thread -resource-dir %S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-X86-64-TVOSSIMULATOR
+// RUN: %clang -target x86_64-apple-tvossimulator -fsanitize=thread %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-X86-64-TVOSSIMULATOR
// CHECK-TSAN-X86-64-TVOSSIMULATOR-NOT: unsupported option
-// RUN: %clang -target i386-apple-darwin -fsanitize=thread -resource-dir %S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-I386-DARWIN
+// RUN: %clang -target i386-apple-darwin -fsanitize=thread %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-I386-DARWIN
// CHECK-TSAN-I386-DARWIN: unsupported option '-fsanitize=thread' for target 'i386-apple-darwin'
// RUN: %clang -target arm-apple-ios -fsanitize=thread %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-ARM-IOS
@@ -433,25 +448,25 @@
// RUN: %clang -target i386-pc-openbsd -fsanitize=efficiency-working-set %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ESAN-OPENBSD
// CHECK-ESAN-OPENBSD: error: unsupported option '-fsanitize=efficiency-{{.*}}' for target 'i386-pc-openbsd'
-// RUN: %clang -target x86_64-apple-darwin -fsanitize=leak -resource-dir %S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LSAN-X86-64-DARWIN
+// RUN: %clang -target x86_64-apple-darwin -fsanitize=leak %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LSAN-X86-64-DARWIN
// CHECK-LSAN-X86-64-DARWIN-NOT: unsupported option
-// RUN: %clang -target x86_64-apple-iossimulator -fsanitize=leak -resource-dir %S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LSAN-X86-64-IOSSIMULATOR
+// RUN: %clang -target x86_64-apple-iossimulator -fsanitize=leak %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LSAN-X86-64-IOSSIMULATOR
// CHECK-LSAN-X86-64-IOSSIMULATOR-NOT: unsupported option
-// RUN: %clang -target x86_64-apple-tvossimulator -fsanitize=leak -resource-dir %S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LSAN-X86-64-TVOSSIMULATOR
+// RUN: %clang -target x86_64-apple-tvossimulator -fsanitize=leak %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LSAN-X86-64-TVOSSIMULATOR
// CHECK-LSAN-X86-64-TVOSSIMULATOR-NOT: unsupported option
-// RUN: %clang -target i386-apple-darwin -fsanitize=leak -resource-dir %S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LSAN-I386-DARWIN
+// RUN: %clang -target i386-apple-darwin -fsanitize=leak %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LSAN-I386-DARWIN
// CHECK-LSAN-I386-DARWIN-NOT: unsupported option
-// RUN: %clang -target arm-apple-ios -fsanitize=leak -resource-dir %S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LSAN-ARM-IOS
+// RUN: %clang -target arm-apple-ios -fsanitize=leak %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LSAN-ARM-IOS
// CHECK-LSAN-ARM-IOS-NOT: unsupported option
-// RUN: %clang -target i386-apple-iossimulator -fsanitize=leak -resource-dir %S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LSAN-I386-IOSSIMULATOR
+// RUN: %clang -target i386-apple-iossimulator -fsanitize=leak %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LSAN-I386-IOSSIMULATOR
// CHECK-LSAN-I386-IOSSIMULATOR-NOT: unsupported option
-// RUN: %clang -target i386-apple-tvossimulator -fsanitize=leak -resource-dir %S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LSAN-I386-TVOSSIMULATOR
+// RUN: %clang -target i386-apple-tvossimulator -fsanitize=leak %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LSAN-I386-TVOSSIMULATOR
// CHECK-LSAN-I386-TVOSSIMULATOR-NOT: unsupported option
// RUN: %clang -target i686-linux-gnu -fsanitize=efficiency-cache-frag %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ESAN-X86
diff --git a/test/Driver/fuzzer.c b/test/Driver/fuzzer.c
index 5a371e260c60..3fdf5ab9c9b9 100644
--- a/test/Driver/fuzzer.c
+++ b/test/Driver/fuzzer.c
@@ -1,6 +1,6 @@
// Test flags inserted by -fsanitize=fuzzer.
-// RUN: %clang -fsanitize=fuzzer %s -target x86_64-apple-darwin14 -resource-dir %S/Inputs/resource_dir -### 2>&1 | FileCheck --check-prefixes=CHECK-FUZZER-LIB,CHECK-COVERAGE-FLAGS %s
+// RUN: %clang -fsanitize=fuzzer %s -target x86_64-apple-darwin14 -### 2>&1 | FileCheck --check-prefixes=CHECK-FUZZER-LIB,CHECK-COVERAGE-FLAGS %s
//
// CHECK-FUZZER-LIB: libclang_rt.fuzzer
// CHECK-COVERAGE: -fsanitize-coverage-inline-8bit-counters
@@ -8,21 +8,21 @@
// CHECK-COVERAGE-SAME: -fsanitize-coverage-trace-cmp
// CHECK-COVERAGE-SAME: -fsanitize-coverage-pc-table
-// RUN: %clang -fsanitize=fuzzer -target i386-unknown-linux -stdlib=platform -resource-dir %S/Inputs/resource_dir %s -### 2>&1 | FileCheck --check-prefixes=CHECK-LIBCXX-LINUX %s
+// RUN: %clang -fsanitize=fuzzer -target i386-unknown-linux -stdlib=platform %s -### 2>&1 | FileCheck --check-prefixes=CHECK-LIBCXX-LINUX %s
//
// CHECK-LIBCXX-LINUX: -lstdc++
-// RUN: %clang -target x86_64-apple-darwin14 -fsanitize=fuzzer -resource-dir %S/Inputs/resource_dir %s -### 2>&1 | FileCheck --check-prefixes=CHECK-LIBCXX-DARWIN %s
+// RUN: %clang -target x86_64-apple-darwin14 -fsanitize=fuzzer %s -### 2>&1 | FileCheck --check-prefixes=CHECK-LIBCXX-DARWIN %s
//
// CHECK-LIBCXX-DARWIN: -lc++
// Check that we don't link in libFuzzer.a when producing a shared object.
-// RUN: %clang -fsanitize=fuzzer %s -shared -o %t.so -resource-dir %S/Inputs/resource_dir -### 2>&1 | FileCheck --check-prefixes=CHECK-NOLIB-SO %s
+// RUN: %clang -fsanitize=fuzzer %s -shared -o %t.so -### 2>&1 | FileCheck --check-prefixes=CHECK-NOLIB-SO %s
// CHECK-NOLIB-SO-NOT: libclang_rt.libfuzzer
// Check that we don't link in libFuzzer when compiling with -fsanitize=fuzzer-no-link.
-// RUN: %clang -fsanitize=fuzzer-no-link %s -target x86_64-apple-darwin14 -resource-dir %S/Inputs/resource_dir -### 2>&1 | FileCheck --check-prefixes=CHECK-NOLIB,CHECK-COV %s
+// RUN: %clang -fsanitize=fuzzer-no-link %s -target x86_64-apple-darwin14 -### 2>&1 | FileCheck --check-prefixes=CHECK-NOLIB,CHECK-COV %s
// CHECK-NOLIB-NOT: libclang_rt.libfuzzer
// CHECK-COV: -fsanitize-coverage-inline-8bit-counters
diff --git a/test/Driver/linux-header-search.cpp b/test/Driver/linux-header-search.cpp
index 3f024aa49593..f545b439b4ab 100644
--- a/test/Driver/linux-header-search.cpp
+++ b/test/Driver/linux-header-search.cpp
@@ -493,3 +493,25 @@
// CHECK-DEBIAN-SPARC64: "-internal-externc-isystem" "[[SYSROOT]]/usr/include/sparc64-linux-gnu"
// CHECK-DEBIAN-SPARC64: "-internal-externc-isystem" "[[SYSROOT]]/include"
// CHECK-DEBIAN-SPARC64: "-internal-externc-isystem" "[[SYSROOT]]/usr/include"
+
+// Check header search on OpenEmbedded ARM.
+// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \
+// RUN: -target arm-oe-linux-gnueabi -stdlib=libstdc++ \
+// RUN: --sysroot=%S/Inputs/openembedded_arm_linux_tree \
+// RUN: | FileCheck --check-prefix=CHECK-OE-ARM %s
+
+// CHECK-OE-ARM: "{{[^"]*}}clang{{[^"]*}}" "-cc1"
+// CHECK-OE-ARM: "-isysroot" "[[SYSROOT:[^"]+]]"
+// CHECK-OE-ARM: "-internal-isystem" "[[SYSROOT]]/usr/lib/arm-oe-linux-gnueabi/6.3.0/../../../include/c++/6.3.0"
+// CHECK-OE-ARM: "-internal-isystem" "[[SYSROOT]]/usr/lib/arm-oe-linux-gnueabi/6.3.0/../../../include/c++/6.3.0/backward"
+
+// Check header search on OpenEmbedded AArch64.
+// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \
+// RUN: -target aarch64-oe-linux -stdlib=libstdc++ \
+// RUN: --sysroot=%S/Inputs/openembedded_aarch64_linux_tree \
+// RUN: | FileCheck --check-prefix=CHECK-OE-AARCH64 %s
+
+// CHECK-OE-AARCH64: "{{[^"]*}}clang{{[^"]*}}" "-cc1"
+// CHECK-OE-AARCH64: "-isysroot" "[[SYSROOT:[^"]+]]"
+// CHECK-OE-AARCH64: "-internal-isystem" "[[SYSROOT]]/usr/lib64/aarch64-oe-linux/6.3.0/../../../include/c++/6.3.0"
+// CHECK-OE-AARCH64: "-internal-isystem" "[[SYSROOT]]/usr/lib64/aarch64-oe-linux/6.3.0/../../../include/c++/6.3.0/backward"
diff --git a/test/Driver/linux-ld.c b/test/Driver/linux-ld.c
index 02e6618a0460..787013931a48 100644
--- a/test/Driver/linux-ld.c
+++ b/test/Driver/linux-ld.c
@@ -1813,4 +1813,40 @@
// CHECK-LD-AMI: "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed"
// CHECK-LD-AMI: "-lc"
// CHECK-LD-AMI: "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed"
-//
+
+// Check whether the OpenEmbedded ARM libs are added correctly.
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: --target=arm-oe-linux-gnueabi -rtlib=libgcc \
+// RUN: --sysroot=%S/Inputs/openembedded_arm_linux_tree \
+// RUN: | FileCheck --check-prefix=CHECK-OE-ARM %s
+
+// CHECK-OE-ARM: "-cc1" "-triple" "armv4t-oe-linux-gnueabi"
+// CHECK-OE-ARM: ld{{.*}}" "--sysroot=[[SYSROOT:[^"]+]]"
+// CHECK-OE-ARM: "-m" "armelf_linux_eabi" "-dynamic-linker"
+// CHECK-OE-ARM: "[[SYSROOT]]/usr/lib/arm-oe-linux-gnueabi/6.3.0/../../../lib{{/|\\\\}}crt1.o"
+// CHECK-OE-ARM: "[[SYSROOT]]/usr/lib/arm-oe-linux-gnueabi/6.3.0/../../../lib{{/|\\\\}}crti.o"
+// CHECK-OE-ARM: "[[SYSROOT]]/usr/lib/arm-oe-linux-gnueabi/6.3.0{{/|\\\\}}crtbegin.o"
+// CHECK-OE-ARM: "-L[[SYSROOT]]/usr/lib/arm-oe-linux-gnueabi/6.3.0"
+// CHECK-OE-ARM: "-L[[SYSROOT]]/usr/lib/arm-oe-linux-gnueabi"
+// CHECK-OE-ARM: "-L[[SYSROOT]]/usr/lib"
+// CHECK-OE-ARM: "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" "-lc" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed"
+// CHECK-OE-ARM: "[[SYSROOT]]/usr/lib/arm-oe-linux-gnueabi/6.3.0{{/|\\\\}}crtend.o"
+// CHECK-OE-ARM: "[[SYSROOT]]/usr/lib/arm-oe-linux-gnueabi/6.3.0/../../../lib{{/|\\\\}}crtn.o"
+
+// Check whether the OpenEmbedded AArch64 libs are added correctly.
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: --target=aarch64-oe-linux -rtlib=libgcc \
+// RUN: --sysroot=%S/Inputs/openembedded_aarch64_linux_tree \
+// RUN: | FileCheck --check-prefix=CHECK-OE-AARCH64 %s
+
+// CHECK-OE-AARCH64: "-cc1" "-triple" "aarch64-oe-linux"
+// CHECK-OE-AARCH64: ld{{.*}}" "--sysroot=[[SYSROOT:[^"]+]]"
+// CHECK-OE-AARCH64: "-m" "aarch64linux" "-dynamic-linker"
+// CHECK-OE-AARCH64: "[[SYSROOT]]/usr/lib64/aarch64-oe-linux/6.3.0/../../../lib64{{/|\\\\}}crt1.o"
+// CHECK-OE-AARCH64: "[[SYSROOT]]/usr/lib64/aarch64-oe-linux/6.3.0/../../../lib64{{/|\\\\}}crti.o"
+// CHECK-OE-AARCH64: "[[SYSROOT]]/usr/lib64/aarch64-oe-linux/6.3.0{{/|\\\\}}crtbegin.o"
+// CHECK-OE-AARCH64: "-L[[SYSROOT]]/usr/lib64/aarch64-oe-linux/6.3.0"
+// CHECK-OE-AARCH64: "-L[[SYSROOT]]/usr/lib64"
+// CHECK-OE-AARCH64: "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" "-lc" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed"
+// CHECK-OE-AARCH64: "[[SYSROOT]]/usr/lib64/aarch64-oe-linux/6.3.0{{/|\\\\}}crtend.o"
+// CHECK-OE-AARCH64: "[[SYSROOT]]/usr/lib64/aarch64-oe-linux/6.3.0/../../../lib64{{/|\\\\}}crtn.o"
diff --git a/test/Driver/openmp-offload-gpu.c b/test/Driver/openmp-offload-gpu.c
index 3d14041a13f8..ca3d9445443d 100644
--- a/test/Driver/openmp-offload-gpu.c
+++ b/test/Driver/openmp-offload-gpu.c
@@ -182,6 +182,8 @@
// RUN: %clang -### -no-canonical-prefixes -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -Xopenmp-target -march=sm_60 %s -ggdb1 -O2 --cuda-noopt-device-debug 2>&1 \
// RUN: | FileCheck -check-prefix=NO_DEBUG -check-prefix=LINE_TABLE %s
+// LINE_TABLE-NOT: warning: debug
+// NO_DEBUG-NOT: warning: debug
// NO_DEBUG: ptxas
// LINE_TABLE: "-lineinfo"
// NO_DEBUG-NOT: "-g"
@@ -203,6 +205,7 @@
// RUN: %clang -### -no-canonical-prefixes -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -Xopenmp-target -march=sm_60 %s -ggdb3 -O2 --cuda-noopt-device-debug 2>&1 \
// RUN: | FileCheck -check-prefix=HAS_DEBUG %s
+// HAS_DEBUG-NOT: warning: debug
// HAS_DEBUG: "-triple" "nvptx64-nvidia-cuda"
// HAS_DEBUG-SAME: "-dwarf-version=2"
// HAS_DEBUG-SAME: "-fopenmp-is-device"
diff --git a/test/Driver/openmp-unsupported-debug-options.c b/test/Driver/openmp-unsupported-debug-options.c
new file mode 100644
index 000000000000..20e0c47f7fff
--- /dev/null
+++ b/test/Driver/openmp-unsupported-debug-options.c
@@ -0,0 +1,22 @@
+// REQUIRES: clang-driver
+// REQUIRES: x86-registered-target
+// REQUIRES: nvptx-registered-target
+// REQUIRES: zlib
+
+// RUN: %clang -### -target x86_64-linux-gnu -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -c %s -g -gz 2>&1 | FileCheck %s
+// RUN: %clang -### -target x86_64-linux-gnu -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -c %s -gdwarf -fdebug-info-for-profiling 2>&1 | FileCheck %s
+// RUN: %clang -### -target x86_64-linux-gnu -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -c %s -gdwarf-2 -gsplit-dwarf 2>&1 | FileCheck %s
+// RUN: %clang -### -target x86_64-linux-gnu -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -c %s -gdwarf-3 -glldb 2>&1 | FileCheck %s
+// RUN: %clang -### -target x86_64-linux-gnu -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -c %s -gdwarf-4 -gcodeview 2>&1 | FileCheck %s
+// RUN: %clang -### -target x86_64-linux-gnu -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -c %s -gdwarf-5 -gmodules 2>&1 | FileCheck %s
+// RUN: %clang -### -target x86_64-linux-gnu -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -c %s -ggdb -gembed-source -gdwarf-5 2>&1 | FileCheck %s
+// RUN: %clang -### -target x86_64-linux-gnu -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -c %s -ggdb1 -fdebug-macro 2>&1 | FileCheck %s
+// RUN: %clang -### -target x86_64-linux-gnu -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -c %s -ggdb2 -ggnu-pubnames 2>&1 | FileCheck %s
+// RUN: %clang -### -target x86_64-linux-gnu -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -c %s -ggdb3 -gdwarf-aranges 2>&1 | FileCheck %s
+// RUN: %clang -### -target x86_64-linux-gnu -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -c %s -g -gcolumn-info -fdebug-types-section 2>&1 | FileCheck %s
+// CHECK: debug information option '{{-gz|-fdebug-info-for-profiling|-gsplit-dwarf|-glldb|-gcodeview|-gmodules|-gembed-source|-fdebug-macro|-ggnu-pubnames|-gdwarf-aranges|-fdebug-types-section}}' is not supported for target 'nvptx64-nvidia-cuda' [-Wunsupported-target-opt]
+// CHECK-NOT: debug information option '{{.*}}' is not supported for target 'x86
+// CHECK: "-triple" "nvptx64-nvidia-cuda"
+// CHECK-NOT: {{-compress-debug|-fdebug-info-for-profiling|split-dwarf|lldb|codeview|module-format|embed-source|debug-info-macro|gnu-pubnames|generate-arange-section|generate-type-units}}
+// CHECK: "-triple" "x86_64
+// CHECK-SAME: {{-compress-debug|-fdebug-info-for-profiling|split-dwarf|lldb|codeview|module-format|embed-source|debug-info-macro|gnu-pubnames|generate-arange-section|generate-type-units}}
diff --git a/test/Driver/riscv32-toolchain.c b/test/Driver/riscv32-toolchain.c
index 1e93e97c5313..1e0c750a3fa4 100644
--- a/test/Driver/riscv32-toolchain.c
+++ b/test/Driver/riscv32-toolchain.c
@@ -3,6 +3,36 @@
// RUN: %clang %s -### -no-canonical-prefixes -target riscv32 2>&1 | FileCheck -check-prefix=CC1 %s
// CC1: clang{{.*}} "-cc1" "-triple" "riscv32"
+// RUN: %clang %s -### -no-canonical-prefixes \
+// RUN: -target riscv32-unknown-elf \
+// RUN: --gcc-toolchain=%S/Inputs/basic_riscv32_tree \
+// RUN: --sysroot=%S/Inputs/basic_riscv32_tree/riscv32-unknown-elf 2>&1 \
+// RUN: | FileCheck -check-prefix=C-RV32-BAREMETAL-ILP32 %s
+
+// C-RV32-BAREMETAL-ILP32: "{{.*}}Inputs/basic_riscv32_tree/lib/gcc/riscv32-unknown-elf/8.0.1/../../../../bin{{/|\\\\}}riscv32-unknown-elf-ld"
+// C-RV32-BAREMETAL-ILP32: "--sysroot={{.*}}/Inputs/basic_riscv32_tree/riscv32-unknown-elf"
+// C-RV32-BAREMETAL-ILP32: "{{.*}}/Inputs/basic_riscv32_tree/riscv32-unknown-elf/lib{{/|\\\\}}crt0.o"
+// C-RV32-BAREMETAL-ILP32: "{{.*}}/Inputs/basic_riscv32_tree/lib/gcc/riscv32-unknown-elf/8.0.1{{/|\\\\}}crtbegin.o"
+// C-RV32-BAREMETAL-ILP32: "-L{{.*}}/Inputs/basic_riscv32_tree/riscv32-unknown-elf/lib"
+// C-RV32-BAREMETAL-ILP32: "-L{{.*}}/Inputs/basic_riscv32_tree/lib/gcc/riscv32-unknown-elf/8.0.1"
+// C-RV32-BAREMETAL-ILP32: "--start-group" "-lc" "-lgloss" "--end-group" "-lgcc"
+// C-RV32-BAREMETAL-ILP32: "{{.*}}/Inputs/basic_riscv32_tree/lib/gcc/riscv32-unknown-elf/8.0.1{{/|\\\\}}crtend.o"
+
+// RUN: %clangxx %s -### -no-canonical-prefixes \
+// RUN: -target riscv32-unknown-elf -stdlib=libstdc++ \
+// RUN: --gcc-toolchain=%S/Inputs/basic_riscv32_tree \
+// RUN: --sysroot=%S/Inputs/basic_riscv32_tree/riscv32-unknown-elf 2>&1 \
+// RUN: | FileCheck -check-prefix=CXX-RV32-BAREMETAL-ILP32 %s
+
+// CXX-RV32-BAREMETAL-ILP32: "-internal-isystem" "{{.*}}Inputs/basic_riscv32_tree/lib/gcc/riscv32-unknown-elf/8.0.1/../../../../riscv32-unknown-elf/include/c++{{/|\\\\}}8.0.1"
+// CXX-RV32-BAREMETAL-ILP32: "{{.*}}Inputs/basic_riscv32_tree/lib/gcc/riscv32-unknown-elf/8.0.1/../../../../bin{{/|\\\\}}riscv32-unknown-elf-ld"
+// CXX-RV32-BAREMETAL-ILP32: "--sysroot={{.*}}/Inputs/basic_riscv32_tree/riscv32-unknown-elf"
+// CXX-RV32-BAREMETAL-ILP32: "{{.*}}/Inputs/basic_riscv32_tree/riscv32-unknown-elf/lib{{/|\\\\}}crt0.o"
+// CXX-RV32-BAREMETAL-ILP32: "{{.*}}/Inputs/basic_riscv32_tree/lib/gcc/riscv32-unknown-elf/8.0.1{{/|\\\\}}crtbegin.o"
+// CXX-RV32-BAREMETAL-ILP32: "-L{{.*}}/Inputs/basic_riscv32_tree/riscv32-unknown-elf/lib"
+// CXX-RV32-BAREMETAL-ILP32: "-L{{.*}}/Inputs/basic_riscv32_tree/lib/gcc/riscv32-unknown-elf/8.0.1"
+// CXX-RV32-BAREMETAL-ILP32: "-lstdc++" "--start-group" "-lc" "-lgloss" "--end-group" "-lgcc"
+// CXX-RV32-BAREMETAL-ILP32: "{{.*}}/Inputs/basic_riscv32_tree/lib/gcc/riscv32-unknown-elf/8.0.1{{/|\\\\}}crtend.o"
// RUN: %clang %s -### -no-canonical-prefixes -fuse-ld=ld \
// RUN: -target riscv32-linux-unknown-elf \
diff --git a/test/Driver/sanitizer-ld.c b/test/Driver/sanitizer-ld.c
index f07fe922ecca..483c87a6242f 100644
--- a/test/Driver/sanitizer-ld.c
+++ b/test/Driver/sanitizer-ld.c
@@ -530,7 +530,6 @@
// RUN: %clangxx -fsanitize=address %s -### -o %t.o 2>&1 \
// RUN: -mmacosx-version-min=10.6 \
-// RUN: -resource-dir=%S/Inputs/resource_dir \
// RUN: -target x86_64-apple-darwin13.4.0 -fuse-ld=ld -stdlib=platform \
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
// RUN: | FileCheck --check-prefix=CHECK-ASAN-DARWIN106-CXX %s
@@ -540,7 +539,6 @@
// RUN: %clangxx -fsanitize=leak %s -### -o %t.o 2>&1 \
// RUN: -mmacosx-version-min=10.6 \
-// RUN: -resource-dir=%S/Inputs/resource_dir \
// RUN: -target x86_64-apple-darwin13.4.0 -fuse-ld=ld -stdlib=platform \
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
// RUN: | FileCheck --check-prefix=CHECK-LSAN-DARWIN106-CXX %s
@@ -600,7 +598,6 @@
// RUN: %clang -fsanitize=cfi -fsanitize-stats %s -### -o %t.o 2>&1 \
// RUN: -target x86_64-apple-darwin -fuse-ld=ld \
-// RUN: -resource-dir=%S/Inputs/resource_dir \
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
// RUN: | FileCheck --check-prefix=CHECK-CFI-STATS-DARWIN %s
// CHECK-CFI-STATS-DARWIN: "{{.*}}ld{{(.exe)?}}"
diff --git a/test/Frontend/clang-abi-compat.cpp b/test/Frontend/clang-abi-compat.cpp
index 7ee94646b6d7..b7f2758a9db6 100644
--- a/test/Frontend/clang-abi-compat.cpp
+++ b/test/Frontend/clang-abi-compat.cpp
@@ -1,6 +1,6 @@
// RUN: not %clang_cc1 -fclang-abi-compat=banana %s -fsyntax-only 2>&1 | FileCheck --check-prefix=INVALID %s
// RUN: not %clang_cc1 -fclang-abi-compat=2.9 %s -fsyntax-only 2>&1 | FileCheck --check-prefix=INVALID %s
-// RUN: not %clang_cc1 -fclang-abi-compat=8 %s -fsyntax-only 2>&1 | FileCheck --check-prefix=INVALID %s
+// RUN: not %clang_cc1 -fclang-abi-compat=42 %s -fsyntax-only 2>&1 | FileCheck --check-prefix=INVALID %s
// RUN: not %clang_cc1 -fclang-abi-compat=3.10 %s -fsyntax-only 2>&1 | FileCheck --check-prefix=INVALID %s
// RUN: not %clang_cc1 -fclang-abi-compat=4.1 %s -fsyntax-only 2>&1 | FileCheck --check-prefix=INVALID %s
// RUN: not %clang_cc1 -fclang-abi-compat=04 %s -fsyntax-only 2>&1 | FileCheck --check-prefix=INVALID %s
diff --git a/test/Index/complete-access-checks-crash.cpp b/test/Index/complete-access-checks-crash.cpp
new file mode 100644
index 000000000000..c7ac4d656378
--- /dev/null
+++ b/test/Index/complete-access-checks-crash.cpp
@@ -0,0 +1,13 @@
+struct Base {
+protected:
+ bool bar();
+};
+struct Derived : Base {
+};
+
+struct X {
+ int foo() {
+ Derived(). // RUN: c-index-test -code-completion-at=%s:10:15 %s | FileCheck %s
+ // CHECK: bar{{.*}}(inaccessible)
+ }
+};
diff --git a/test/Modules/resolution-change.m b/test/Modules/resolution-change.m
index bf95104968a3..4c8eb70db8ad 100644
--- a/test/Modules/resolution-change.m
+++ b/test/Modules/resolution-change.m
@@ -21,6 +21,8 @@
// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs/modules-with-same-name/DependsOnA -I %S/Inputs/modules-with-same-name/path2/A -include-pch %t-A.pch %s -fsyntax-only 2>&1 | FileCheck -check-prefix=CHECK-WRONGA %s
// CHECK-WRONGA: module 'A' was built in directory '{{.*Inputs.modules-with-same-name.path1.A}}' but now resides in directory '{{.*Inputs.modules-with-same-name.path2.A}}'
+// RUN: %clang_cc1 -fno-validate-pch -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs/modules-with-same-name/DependsOnA -I %S/Inputs/modules-with-same-name/path2/A -include-pch %t-A.pch %s -fsyntax-only
+
#ifndef HEADER
#define HEADER
@import DependsOnA;
diff --git a/test/OpenMP/declare_target_codegen.cpp b/test/OpenMP/declare_target_codegen.cpp
index a221387c7312..96bdc874ece2 100644
--- a/test/OpenMP/declare_target_codegen.cpp
+++ b/test/OpenMP/declare_target_codegen.cpp
@@ -18,14 +18,15 @@
// CHECK-DAG: @d = global i32 0,
// CHECK-DAG: @c = external global i32,
// CHECK-DAG: @globals = global %struct.S zeroinitializer,
-// CHECK-DAG: @{{.+}}stat = weak_odr global %struct.S zeroinitializer,
-// CHECK-DAG: @llvm.used = appending global [2 x i8*] [i8* bitcast (void ()* @__omp_offloading__{{.+}}_globals_l[[@LINE+42]]_ctor to i8*), i8* bitcast (void ()* @__omp_offloading__{{.+}}_stat_l[[@LINE+43]]_ctor to i8*)], section "llvm.metadata"
+// CHECK-DAG: [[STAT:@.+stat]] = internal global %struct.S zeroinitializer,
+// CHECK-DAG: [[STAT_REF:@.+]] = internal constant %struct.S* [[STAT]]
+// CHECK-DAG: @llvm.used = appending global [2 x i8*] [i8* bitcast (void ()* @__omp_offloading__{{.+}}_globals_l[[@LINE+42]]_ctor to i8*), i8* bitcast (void ()* @__omp_offloading__{{.+}}_stat_l[[@LINE+43]]_ctor to i8*)],
+// CHECK-DAG: @llvm.compiler.used = appending global [1 x i8*] [i8* bitcast (%struct.S** [[STAT_REF]] to i8*)],
// CHECK-DAG: define {{.*}}i32 @{{.*}}{{foo|bar|baz2|baz3|FA|f_method}}{{.*}}()
// CHECK-DAG: define {{.*}}void @{{.*}}TemplateClass{{.*}}(%class.TemplateClass* %{{.*}})
// CHECK-DAG: define {{.*}}i32 @{{.*}}TemplateClass{{.*}}f_method{{.*}}(%class.TemplateClass* %{{.*}})
-// CHECK-DAG: define {{.*}}void @__omp_offloading__{{.*}}_globals_l[[@LINE+37]]_ctor()
-// CHECK-DAG: define {{.*}}void @__omp_offloading__{{.*}}_stat_l[[@LINE+37]]_ctor()
+// CHECK-DAG: define {{.*}}void @__omp_offloading__{{.*}}_globals_l[[@LINE+36]]_ctor()
#ifndef HEADER
#define HEADER
diff --git a/test/OpenMP/nvptx_declare_target_var_ctor_dtor_codegen.cpp b/test/OpenMP/nvptx_declare_target_var_ctor_dtor_codegen.cpp
index 3cd85eefbc2c..b9049a40281d 100644
--- a/test/OpenMP/nvptx_declare_target_var_ctor_dtor_codegen.cpp
+++ b/test/OpenMP/nvptx_declare_target_var_ctor_dtor_codegen.cpp
@@ -15,7 +15,7 @@
// SIMD-ONLY-NOT: {{__kmpc|__tgt}}
-// DEVICE-DAG: [[C_ADDR:.+]] = weak_odr global i32 0,
+// DEVICE-DAG: [[C_ADDR:.+]] = internal global i32 0,
// DEVICE-DAG: [[CD_ADDR:@.+]] = global %struct.S zeroinitializer,
// HOST-DAG: @[[C_ADDR:.+]] = internal global i32 0,
// HOST-DAG: @[[CD_ADDR:.+]] = global %struct.S zeroinitializer,
diff --git a/test/OpenMP/target_codegen.cpp b/test/OpenMP/target_codegen.cpp
index 15eb469fa280..6395dd354fa2 100644
--- a/test/OpenMP/target_codegen.cpp
+++ b/test/OpenMP/target_codegen.cpp
@@ -85,8 +85,8 @@
// Check if offloading descriptor is created.
// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
-// CHECK: [[DEVBEGIN:@.+]] = external constant i8
-// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[DEVBEGIN:@.+]] = extern_weak constant i8
+// CHECK: [[DEVEND:@.+]] = extern_weak constant i8
// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }], comdat($[[REGFN]])
// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, comdat($[[REGFN]])
diff --git a/test/OpenMP/target_codegen_registration.cpp b/test/OpenMP/target_codegen_registration.cpp
index b98b33c9a4dd..2774de64fc7f 100644
--- a/test/OpenMP/target_codegen_registration.cpp
+++ b/test/OpenMP/target_codegen_registration.cpp
@@ -174,8 +174,8 @@
// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
-// CHECK: [[DEVBEGIN:@.+]] = external constant i8
-// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[DEVBEGIN:@.+]] = extern_weak constant i8
+// CHECK: [[DEVEND:@.+]] = extern_weak constant i8
// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }], comdat($[[REGFN]])
// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, comdat($[[REGFN]])
diff --git a/test/OpenMP/target_depend_codegen.cpp b/test/OpenMP/target_depend_codegen.cpp
index bd709e1def7d..588ab9757e4a 100644
--- a/test/OpenMP/target_depend_codegen.cpp
+++ b/test/OpenMP/target_depend_codegen.cpp
@@ -58,8 +58,8 @@
// Check if offloading descriptor is created.
// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
-// CHECK: [[DEVBEGIN:@.+]] = external constant i8
-// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[DEVBEGIN:@.+]] = extern_weak constant i8
+// CHECK: [[DEVEND:@.+]] = extern_weak constant i8
// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }], comdat($[[REGFN]])
// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, comdat($[[REGFN]])
diff --git a/test/OpenMP/target_parallel_codegen.cpp b/test/OpenMP/target_parallel_codegen.cpp
index f1a511a6bb45..bebde4edf722 100644
--- a/test/OpenMP/target_parallel_codegen.cpp
+++ b/test/OpenMP/target_parallel_codegen.cpp
@@ -85,8 +85,8 @@
// Check if offloading descriptor is created.
// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
-// CHECK: [[DEVBEGIN:@.+]] = external constant i8
-// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[DEVBEGIN:@.+]] = extern_weak constant i8
+// CHECK: [[DEVEND:@.+]] = extern_weak constant i8
// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }], comdat($[[REGFN]])
// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, comdat($[[REGFN]])
diff --git a/test/OpenMP/target_parallel_codegen_registration.cpp b/test/OpenMP/target_parallel_codegen_registration.cpp
index c9892eae36d6..234c5500c1f3 100644
--- a/test/OpenMP/target_parallel_codegen_registration.cpp
+++ b/test/OpenMP/target_parallel_codegen_registration.cpp
@@ -174,8 +174,8 @@
// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
-// CHECK: [[DEVBEGIN:@.+]] = external constant i8
-// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[DEVBEGIN:@.+]] = extern_weak constant i8
+// CHECK: [[DEVEND:@.+]] = extern_weak constant i8
// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }], comdat($[[REGFN]])
// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, comdat($[[REGFN]])
diff --git a/test/OpenMP/target_parallel_depend_codegen.cpp b/test/OpenMP/target_parallel_depend_codegen.cpp
index 52d13a34d85a..dc55ec15e51f 100644
--- a/test/OpenMP/target_parallel_depend_codegen.cpp
+++ b/test/OpenMP/target_parallel_depend_codegen.cpp
@@ -58,8 +58,8 @@
// Check if offloading descriptor is created.
// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
-// CHECK: [[DEVBEGIN:@.+]] = external constant i8
-// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[DEVBEGIN:@.+]] = extern_weak constant i8
+// CHECK: [[DEVEND:@.+]] = extern_weak constant i8
// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }], comdat($[[REGFN]])
// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, comdat($[[REGFN]])
diff --git a/test/OpenMP/target_parallel_for_codegen.cpp b/test/OpenMP/target_parallel_for_codegen.cpp
index d541d14670a5..dc6243c9df3c 100644
--- a/test/OpenMP/target_parallel_for_codegen.cpp
+++ b/test/OpenMP/target_parallel_for_codegen.cpp
@@ -86,8 +86,8 @@
// Check if offloading descriptor is created.
// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
-// CHECK: [[DEVBEGIN:@.+]] = external constant i8
-// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[DEVBEGIN:@.+]] = extern_weak constant i8
+// CHECK: [[DEVEND:@.+]] = extern_weak constant i8
// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }], comdat($[[REGFN]])
// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, comdat($[[REGFN]])
diff --git a/test/OpenMP/target_parallel_for_codegen_registration.cpp b/test/OpenMP/target_parallel_for_codegen_registration.cpp
index 9a69ea994efc..a23b1ace97fa 100644
--- a/test/OpenMP/target_parallel_for_codegen_registration.cpp
+++ b/test/OpenMP/target_parallel_for_codegen_registration.cpp
@@ -174,8 +174,8 @@
// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
-// CHECK: [[DEVBEGIN:@.+]] = external constant i8
-// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[DEVBEGIN:@.+]] = extern_weak constant i8
+// CHECK: [[DEVEND:@.+]] = extern_weak constant i8
// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }], comdat($[[REGFN]])
// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, comdat($[[REGFN]])
diff --git a/test/OpenMP/target_parallel_for_depend_codegen.cpp b/test/OpenMP/target_parallel_for_depend_codegen.cpp
index c6e71375f18c..85ec945c4f65 100644
--- a/test/OpenMP/target_parallel_for_depend_codegen.cpp
+++ b/test/OpenMP/target_parallel_for_depend_codegen.cpp
@@ -58,8 +58,8 @@
// Check if offloading descriptor is created.
// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
-// CHECK: [[DEVBEGIN:@.+]] = external constant i8
-// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[DEVBEGIN:@.+]] = extern_weak constant i8
+// CHECK: [[DEVEND:@.+]] = extern_weak constant i8
// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }], comdat($[[REGFN]])
// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, comdat($[[REGFN]])
diff --git a/test/OpenMP/target_parallel_for_simd_codegen.cpp b/test/OpenMP/target_parallel_for_simd_codegen.cpp
index 012b2f86be48..75bf2d17afd6 100644
--- a/test/OpenMP/target_parallel_for_simd_codegen.cpp
+++ b/test/OpenMP/target_parallel_for_simd_codegen.cpp
@@ -85,8 +85,8 @@
// Check if offloading descriptor is created.
// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
-// CHECK: [[DEVBEGIN:@.+]] = external constant i8
-// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[DEVBEGIN:@.+]] = extern_weak constant i8
+// CHECK: [[DEVEND:@.+]] = extern_weak constant i8
// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }], comdat($[[REGFN]])
// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, comdat($[[REGFN]])
diff --git a/test/OpenMP/target_parallel_for_simd_codegen_registration.cpp b/test/OpenMP/target_parallel_for_simd_codegen_registration.cpp
index 5973c8d182f1..82f8cefa2c44 100644
--- a/test/OpenMP/target_parallel_for_simd_codegen_registration.cpp
+++ b/test/OpenMP/target_parallel_for_simd_codegen_registration.cpp
@@ -174,8 +174,8 @@
// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
-// CHECK: [[DEVBEGIN:@.+]] = external constant i8
-// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[DEVBEGIN:@.+]] = extern_weak constant i8
+// CHECK: [[DEVEND:@.+]] = extern_weak constant i8
// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }], comdat($[[REGFN]])
// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, comdat($[[REGFN]])
diff --git a/test/OpenMP/target_parallel_for_simd_depend_codegen.cpp b/test/OpenMP/target_parallel_for_simd_depend_codegen.cpp
index 6fc71a787559..83d752d9abe7 100644
--- a/test/OpenMP/target_parallel_for_simd_depend_codegen.cpp
+++ b/test/OpenMP/target_parallel_for_simd_depend_codegen.cpp
@@ -58,8 +58,8 @@
// Check if offloading descriptor is created.
// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
-// CHECK: [[DEVBEGIN:@.+]] = external constant i8
-// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[DEVBEGIN:@.+]] = extern_weak constant i8
+// CHECK: [[DEVEND:@.+]] = extern_weak constant i8
// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }], comdat($[[REGFN]])
// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, comdat($[[REGFN]])
diff --git a/test/OpenMP/target_parallel_if_codegen.cpp b/test/OpenMP/target_parallel_if_codegen.cpp
index aab1a14a5eb5..264017f7c523 100644
--- a/test/OpenMP/target_parallel_if_codegen.cpp
+++ b/test/OpenMP/target_parallel_if_codegen.cpp
@@ -70,8 +70,8 @@
// Check if offloading descriptor is created.
// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
-// CHECK: [[DEVBEGIN:@.+]] = external constant i8
-// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[DEVBEGIN:@.+]] = extern_weak constant i8
+// CHECK: [[DEVEND:@.+]] = extern_weak constant i8
// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }], comdat($[[REGFN]])
// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, comdat($[[REGFN]])
diff --git a/test/OpenMP/target_parallel_num_threads_codegen.cpp b/test/OpenMP/target_parallel_num_threads_codegen.cpp
index e6b93113c557..e271811a4911 100644
--- a/test/OpenMP/target_parallel_num_threads_codegen.cpp
+++ b/test/OpenMP/target_parallel_num_threads_codegen.cpp
@@ -70,8 +70,8 @@
// Check if offloading descriptor is created.
// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
-// CHECK: [[DEVBEGIN:@.+]] = external constant i8
-// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[DEVBEGIN:@.+]] = extern_weak constant i8
+// CHECK: [[DEVEND:@.+]] = extern_weak constant i8
// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }], comdat($[[REGFN]])
// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, comdat($[[REGFN]])
diff --git a/test/OpenMP/target_simd_codegen.cpp b/test/OpenMP/target_simd_codegen.cpp
index a2ec51c4e22f..81ad4038044c 100644
--- a/test/OpenMP/target_simd_codegen.cpp
+++ b/test/OpenMP/target_simd_codegen.cpp
@@ -82,8 +82,8 @@
// Check if offloading descriptor is created.
// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
-// CHECK: [[DEVBEGIN:@.+]] = external constant i8
-// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[DEVBEGIN:@.+]] = extern_weak constant i8
+// CHECK: [[DEVEND:@.+]] = extern_weak constant i8
// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }], comdat($[[REGFN]])
// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, comdat($[[REGFN]])
diff --git a/test/OpenMP/target_simd_codegen_registration.cpp b/test/OpenMP/target_simd_codegen_registration.cpp
index 39e930a5d554..a888b2587405 100644
--- a/test/OpenMP/target_simd_codegen_registration.cpp
+++ b/test/OpenMP/target_simd_codegen_registration.cpp
@@ -174,8 +174,8 @@
// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
-// CHECK: [[DEVBEGIN:@.+]] = external constant i8
-// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[DEVBEGIN:@.+]] = extern_weak constant i8
+// CHECK: [[DEVEND:@.+]] = extern_weak constant i8
// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }], comdat($[[REGFN]])
// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, comdat($[[REGFN]])
diff --git a/test/OpenMP/target_simd_depend_codegen.cpp b/test/OpenMP/target_simd_depend_codegen.cpp
index ed34dd12dfb6..e87b4fc8c30f 100644
--- a/test/OpenMP/target_simd_depend_codegen.cpp
+++ b/test/OpenMP/target_simd_depend_codegen.cpp
@@ -58,8 +58,8 @@
// Check if offloading descriptor is created.
// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
-// CHECK: [[DEVBEGIN:@.+]] = external constant i8
-// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[DEVBEGIN:@.+]] = extern_weak constant i8
+// CHECK: [[DEVEND:@.+]] = extern_weak constant i8
// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }], comdat($[[REGFN]])
// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, comdat($[[REGFN]])
diff --git a/test/OpenMP/target_teams_codegen.cpp b/test/OpenMP/target_teams_codegen.cpp
index 5c18a0cba3bb..43391fc641a6 100644
--- a/test/OpenMP/target_teams_codegen.cpp
+++ b/test/OpenMP/target_teams_codegen.cpp
@@ -87,8 +87,8 @@
// Check if offloading descriptor is created.
// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
-// CHECK: [[DEVBEGIN:@.+]] = external constant i8
-// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[DEVBEGIN:@.+]] = extern_weak constant i8
+// CHECK: [[DEVEND:@.+]] = extern_weak constant i8
// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }], comdat($[[REGFN]])
// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, comdat($[[REGFN]])
diff --git a/test/OpenMP/target_teams_codegen_registration.cpp b/test/OpenMP/target_teams_codegen_registration.cpp
index e62be6813460..a18e180c5c81 100644
--- a/test/OpenMP/target_teams_codegen_registration.cpp
+++ b/test/OpenMP/target_teams_codegen_registration.cpp
@@ -174,8 +174,8 @@
// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
-// CHECK: [[DEVBEGIN:@.+]] = external constant i8
-// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[DEVBEGIN:@.+]] = extern_weak constant i8
+// CHECK: [[DEVEND:@.+]] = extern_weak constant i8
// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }], comdat($[[REGFN]])
// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, comdat($[[REGFN]])
diff --git a/test/OpenMP/target_teams_depend_codegen.cpp b/test/OpenMP/target_teams_depend_codegen.cpp
index a5fbc5afc163..9f9c7656eafc 100644
--- a/test/OpenMP/target_teams_depend_codegen.cpp
+++ b/test/OpenMP/target_teams_depend_codegen.cpp
@@ -58,8 +58,8 @@
// Check if offloading descriptor is created.
// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
-// CHECK: [[DEVBEGIN:@.+]] = external constant i8
-// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[DEVBEGIN:@.+]] = extern_weak constant i8
+// CHECK: [[DEVEND:@.+]] = extern_weak constant i8
// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }], comdat($[[REGFN]])
// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, comdat($[[REGFN]])
diff --git a/test/OpenMP/target_teams_distribute_codegen.cpp b/test/OpenMP/target_teams_distribute_codegen.cpp
index f9500a73ef79..aa1bc016da0d 100644
--- a/test/OpenMP/target_teams_distribute_codegen.cpp
+++ b/test/OpenMP/target_teams_distribute_codegen.cpp
@@ -88,8 +88,8 @@
// Check if offloading descriptor is created.
// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
-// CHECK: [[DEVBEGIN:@.+]] = external constant i8
-// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[DEVBEGIN:@.+]] = extern_weak constant i8
+// CHECK: [[DEVEND:@.+]] = extern_weak constant i8
// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }], comdat($[[REGFN]])
// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, comdat($[[REGFN]])
diff --git a/test/OpenMP/target_teams_distribute_codegen_registration.cpp b/test/OpenMP/target_teams_distribute_codegen_registration.cpp
index e45e040b1fcd..3213a9706f72 100644
--- a/test/OpenMP/target_teams_distribute_codegen_registration.cpp
+++ b/test/OpenMP/target_teams_distribute_codegen_registration.cpp
@@ -174,8 +174,8 @@
// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
-// CHECK: [[DEVBEGIN:@.+]] = external constant i8
-// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[DEVBEGIN:@.+]] = extern_weak constant i8
+// CHECK: [[DEVEND:@.+]] = extern_weak constant i8
// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }], comdat($[[REGFN]])
// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, comdat($[[REGFN]])
diff --git a/test/OpenMP/target_teams_distribute_depend_codegen.cpp b/test/OpenMP/target_teams_distribute_depend_codegen.cpp
index f066574e8768..99b7f2c2e9c3 100644
--- a/test/OpenMP/target_teams_distribute_depend_codegen.cpp
+++ b/test/OpenMP/target_teams_distribute_depend_codegen.cpp
@@ -58,8 +58,8 @@
// Check if offloading descriptor is created.
// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
-// CHECK: [[DEVBEGIN:@.+]] = external constant i8
-// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[DEVBEGIN:@.+]] = extern_weak constant i8
+// CHECK: [[DEVEND:@.+]] = extern_weak constant i8
// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }], comdat($[[REGFN]])
// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, comdat($[[REGFN]])
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_depend_codegen.cpp b/test/OpenMP/target_teams_distribute_parallel_for_depend_codegen.cpp
index 5cfa2cca51b5..f573c0454774 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_depend_codegen.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_depend_codegen.cpp
@@ -58,8 +58,8 @@
// Check if offloading descriptor is created.
// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
-// CHECK: [[DEVBEGIN:@.+]] = external constant i8
-// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[DEVBEGIN:@.+]] = extern_weak constant i8
+// CHECK: [[DEVEND:@.+]] = extern_weak constant i8
// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }], comdat($[[REGFN]])
// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, comdat($[[REGFN]])
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_codegen_registration.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_codegen_registration.cpp
index 76a7b4d0bd86..0222bc8d908a 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_simd_codegen_registration.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_codegen_registration.cpp
@@ -174,8 +174,8 @@
// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
-// CHECK: [[DEVBEGIN:@.+]] = external constant i8
-// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[DEVBEGIN:@.+]] = extern_weak constant i8
+// CHECK: [[DEVEND:@.+]] = extern_weak constant i8
// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }], comdat($[[REGFN]])
// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, comdat($[[REGFN]])
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_depend_codegen.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_depend_codegen.cpp
index 2a10ae872375..1258e685ea73 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_simd_depend_codegen.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_depend_codegen.cpp
@@ -58,8 +58,8 @@
// Check if offloading descriptor is created.
// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
-// CHECK: [[DEVBEGIN:@.+]] = external constant i8
-// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[DEVBEGIN:@.+]] = extern_weak constant i8
+// CHECK: [[DEVEND:@.+]] = extern_weak constant i8
// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }], comdat($[[REGFN]])
// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, comdat($[[REGFN]])
diff --git a/test/OpenMP/target_teams_distribute_simd_codegen.cpp b/test/OpenMP/target_teams_distribute_simd_codegen.cpp
index c400e0867154..425afd262256 100644
--- a/test/OpenMP/target_teams_distribute_simd_codegen.cpp
+++ b/test/OpenMP/target_teams_distribute_simd_codegen.cpp
@@ -88,8 +88,8 @@
// Check if offloading descriptor is created.
// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
-// CHECK: [[DEVBEGIN:@.+]] = external constant i8
-// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[DEVBEGIN:@.+]] = extern_weak constant i8
+// CHECK: [[DEVEND:@.+]] = extern_weak constant i8
// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }], comdat($[[REGFN]])
// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, comdat($[[REGFN]])
diff --git a/test/OpenMP/target_teams_distribute_simd_codegen_registration.cpp b/test/OpenMP/target_teams_distribute_simd_codegen_registration.cpp
index 5020bcc87aaf..606919740da2 100644
--- a/test/OpenMP/target_teams_distribute_simd_codegen_registration.cpp
+++ b/test/OpenMP/target_teams_distribute_simd_codegen_registration.cpp
@@ -174,8 +174,8 @@
// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
-// CHECK: [[DEVBEGIN:@.+]] = external constant i8
-// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[DEVBEGIN:@.+]] = extern_weak constant i8
+// CHECK: [[DEVEND:@.+]] = extern_weak constant i8
// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }], comdat($[[REGFN]])
// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, comdat($[[REGFN]])
diff --git a/test/OpenMP/target_teams_distribute_simd_depend_codegen.cpp b/test/OpenMP/target_teams_distribute_simd_depend_codegen.cpp
index 0c1c13e1e908..1eb732322ce6 100644
--- a/test/OpenMP/target_teams_distribute_simd_depend_codegen.cpp
+++ b/test/OpenMP/target_teams_distribute_simd_depend_codegen.cpp
@@ -58,8 +58,8 @@
// Check if offloading descriptor is created.
// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
-// CHECK: [[DEVBEGIN:@.+]] = external constant i8
-// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[DEVBEGIN:@.+]] = extern_weak constant i8
+// CHECK: [[DEVEND:@.+]] = extern_weak constant i8
// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }], comdat($[[REGFN]])
// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, comdat($[[REGFN]])
diff --git a/test/OpenMP/target_teams_num_teams_codegen.cpp b/test/OpenMP/target_teams_num_teams_codegen.cpp
index 0961c03e30f0..6edde0042edd 100644
--- a/test/OpenMP/target_teams_num_teams_codegen.cpp
+++ b/test/OpenMP/target_teams_num_teams_codegen.cpp
@@ -70,8 +70,8 @@
// Check if offloading descriptor is created.
// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
-// CHECK: [[DEVBEGIN:@.+]] = external constant i8
-// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[DEVBEGIN:@.+]] = extern_weak constant i8
+// CHECK: [[DEVEND:@.+]] = extern_weak constant i8
// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }], comdat($[[REGFN]])
// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, comdat($[[REGFN]])
diff --git a/test/OpenMP/target_teams_thread_limit_codegen.cpp b/test/OpenMP/target_teams_thread_limit_codegen.cpp
index 21c9c5a68e70..3baa81cc9ecb 100644
--- a/test/OpenMP/target_teams_thread_limit_codegen.cpp
+++ b/test/OpenMP/target_teams_thread_limit_codegen.cpp
@@ -70,8 +70,8 @@
// Check if offloading descriptor is created.
// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
-// CHECK: [[DEVBEGIN:@.+]] = external constant i8
-// CHECK: [[DEVEND:@.+]] = external constant i8
+// CHECK: [[DEVBEGIN:@.+]] = extern_weak constant i8
+// CHECK: [[DEVEND:@.+]] = extern_weak constant i8
// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }], comdat($[[REGFN]])
// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, comdat($[[REGFN]])
diff --git a/test/PCH/coroutines.cpp b/test/PCH/coroutines.cpp
index 46a2872420bf..f907d1213731 100644
--- a/test/PCH/coroutines.cpp
+++ b/test/PCH/coroutines.cpp
@@ -66,6 +66,14 @@ int f2(T x) { // checks coawait_expr and coroutine_body_stmt
co_return x; // checks coreturn_stmt with expr
}
+struct S {};
+S operator co_await(S) { return S(); }
+
+template <typename T>
+int f3(T x) {
+ co_await x; // checks dependent_coawait with overloaded co_await operator
+}
+
#else
// expected-no-diagnostics
diff --git a/test/PCH/cxx-templates.cpp b/test/PCH/cxx-templates.cpp
index e241701f50df..a7f7b1981f56 100644
--- a/test/PCH/cxx-templates.cpp
+++ b/test/PCH/cxx-templates.cpp
@@ -116,3 +116,19 @@ namespace MemberSpecializationLocation {
#endif
int k = A<int>::n;
}
+
+// https://bugs.llvm.org/show_bug.cgi?id=34728
+namespace PR34728 {
+int test() {
+ // Verify with several TemplateParmDecl kinds, using PCH (incl. modules).
+ int z1 = func1(/*ignored*/2.718);
+ int z2 = func2(/*ignored*/3.142);
+ int tmp3 = 30;
+ Container<int> c = func3(tmp3);
+ int z3 = c.item;
+
+ // Return value is meaningless. Just "use" all these values to avoid
+ // warning about unused vars / values.
+ return z1 + z2 + z3;
+}
+} // end namespace PR34728
diff --git a/test/PCH/cxx-templates.h b/test/PCH/cxx-templates.h
index 68b252e7974e..e812aa68fb81 100644
--- a/test/PCH/cxx-templates.h
+++ b/test/PCH/cxx-templates.h
@@ -361,3 +361,38 @@ namespace rdar15468709c {
namespace MemberSpecializationLocation {
template<typename T> struct A { static int n; };
}
+
+// https://bugs.llvm.org/show_bug.cgi?id=34728
+namespace PR34728 {
+
+// case 1: defaulted `NonTypeTemplateParmDecl`, non-defaulted 2nd tpl param
+template <int foo = 10, class T>
+int func1(T const &);
+
+template <int foo, class T>
+int func1(T const &) {
+ return foo;
+}
+
+// case 2: defaulted `TemplateTypeParmDecl`, non-defaulted 2nd tpl param
+template <class A = int, class B>
+A func2(B const &);
+
+template <class A, class B>
+A func2(B const &) {
+ return A(20.0f);
+}
+
+// case 3: defaulted `TemplateTemplateParmDecl`, non-defaulted 2nd tpl param
+template <class T>
+struct Container { T const &item; };
+
+template <template <class> class C = Container, class D>
+C<D> func3(D const &);
+
+template <template <class> class C, class D>
+C<D> func3(D const &d) {
+ return Container<D>{d};
+}
+
+} // end namespace PR34728
diff --git a/test/Parser/cxx1z-fold-expressions.cpp b/test/Parser/cxx1z-fold-expressions.cpp
index 342f11555fa7..93ee6f20ffc6 100644
--- a/test/Parser/cxx1z-fold-expressions.cpp
+++ b/test/Parser/cxx1z-fold-expressions.cpp
@@ -60,3 +60,29 @@ template <int... N> constexpr int nestedFoldOperator() {
}
static_assert(nestedFoldOperator<3, 1>() == 1);
+
+// A fold-expression is a primary-expression.
+template <typename T, typename... Ts>
+constexpr auto castSum(Ts... Args) {
+ return (T)(Args + ...).Value; // expected-error{{member reference base type 'int' is not a structure or union}}
+}
+
+template <typename... Ts>
+constexpr auto simpleSum(Ts... Args) {
+ return (... + Args).Value; // expected-error{{member reference base type 'int' is not a structure or union}}
+}
+
+void prim() {
+ castSum<int>(1, 2);
+ // expected-note@-1{{in instantiation of function template specialization}}
+ simpleSum(1, 2);
+ // expected-note@-1{{in instantiation of function template specialization}}
+
+ struct Number {
+ int Value;
+ constexpr Number operator+(Number Rhs) const { return {Rhs.Value + Value}; }
+ };
+
+ static_assert(castSum<long>(Number{1}, Number{2}) == 3);
+ static_assert(simpleSum(Number{1}, Number{2}) == 3);
+}
diff --git a/test/SemaCUDA/device-var-init.cu b/test/SemaCUDA/device-var-init.cu
index 46cb90da2ecf..dd5d19a6a2e8 100644
--- a/test/SemaCUDA/device-var-init.cu
+++ b/test/SemaCUDA/device-var-init.cu
@@ -207,17 +207,22 @@ __device__ void df_sema() {
// expected-error@-1 {{initialization is not supported for __shared__ variables.}}
static __device__ int ds;
- // expected-error@-1 {{within a __device__ function, only __shared__ variables may be marked 'static'}}
+ // expected-error@-1 {{within a __device__ function, only __shared__ variables or const variables without device memory qualifier may be marked 'static'}}
static __constant__ int dc;
- // expected-error@-1 {{within a __device__ function, only __shared__ variables may be marked 'static'}}
+ // expected-error@-1 {{within a __device__ function, only __shared__ variables or const variables without device memory qualifier may be marked 'static'}}
static int v;
- // expected-error@-1 {{within a __device__ function, only __shared__ variables may be marked 'static'}}
+ // expected-error@-1 {{within a __device__ function, only __shared__ variables or const variables without device memory qualifier may be marked 'static'}}
+ static const int cv = 1;
+ static const __device__ int cds = 1;
+ // expected-error@-1 {{within a __device__ function, only __shared__ variables or const variables without device memory qualifier may be marked 'static'}}
+ static const __constant__ int cdc = 1;
+ // expected-error@-1 {{within a __device__ function, only __shared__ variables or const variables without device memory qualifier may be marked 'static'}}
}
__host__ __device__ void hd_sema() {
static int x = 42;
#ifdef __CUDA_ARCH__
- // expected-error@-2 {{within a __host__ __device__ function, only __shared__ variables may be marked 'static'}}
+ // expected-error@-2 {{within a __host__ __device__ function, only __shared__ variables or const variables without device memory qualifier may be marked 'static'}}
#endif
}
diff --git a/test/SemaCXX/attr-lifetimebound.cpp b/test/SemaCXX/attr-lifetimebound.cpp
new file mode 100644
index 000000000000..90124c323d02
--- /dev/null
+++ b/test/SemaCXX/attr-lifetimebound.cpp
@@ -0,0 +1,115 @@
+// RUN: %clang_cc1 -std=c++2a -verify %s
+
+namespace usage_invalid {
+ // FIXME: Should we diagnose a void return type?
+ void voidreturn(int &param [[clang::lifetimebound]]);
+
+ int *not_class_member() [[clang::lifetimebound]]; // expected-error {{non-member function has no implicit object parameter}}
+ struct A {
+ A() [[clang::lifetimebound]]; // expected-error {{cannot be applied to a constructor}}
+ ~A() [[clang::lifetimebound]]; // expected-error {{cannot be applied to a destructor}}
+ static int *static_class_member() [[clang::lifetimebound]]; // expected-error {{static member function has no implicit object parameter}}
+ int not_function [[clang::lifetimebound]]; // expected-error {{only applies to parameters and implicit object parameters}}
+ int [[clang::lifetimebound]] also_not_function; // expected-error {{cannot be applied to types}}
+ };
+ int *attr_with_param(int &param [[clang::lifetimebound(42)]]); // expected-error {{takes no arguments}}
+}
+
+namespace usage_ok {
+ struct IntRef { int *target; };
+
+ int &refparam(int &param [[clang::lifetimebound]]);
+ int &classparam(IntRef param [[clang::lifetimebound]]);
+
+ // Do not diagnose non-void return types; they can still be lifetime-bound.
+ long long ptrintcast(int &param [[clang::lifetimebound]]) {
+ return (long long)&param;
+ }
+ // Likewise.
+ int &intptrcast(long long param [[clang::lifetimebound]]) {
+ return *(int*)param;
+ }
+
+ struct A {
+ A();
+ A(int);
+ int *class_member() [[clang::lifetimebound]];
+ operator int*() [[clang::lifetimebound]];
+ };
+
+ int *p = A().class_member(); // expected-warning {{temporary whose address is used as value of local variable 'p' will be destroyed at the end of the full-expression}}
+ int *q = A(); // expected-warning {{temporary whose address is used as value of local variable 'q' will be destroyed at the end of the full-expression}}
+ int *r = A(1); // expected-warning {{temporary whose address is used as value of local variable 'r' will be destroyed at the end of the full-expression}}
+}
+
+# 1 "<std>" 1 3
+namespace std {
+ using size_t = __SIZE_TYPE__;
+ struct string {
+ string();
+ string(const char*);
+
+ char &operator[](size_t) const [[clang::lifetimebound]];
+ };
+ string operator""s(const char *, size_t);
+
+ struct string_view {
+ string_view();
+ string_view(const char *p [[clang::lifetimebound]]);
+ string_view(const string &s [[clang::lifetimebound]]);
+ };
+ string_view operator""sv(const char *, size_t);
+
+ struct vector {
+ int *data();
+ size_t size();
+ };
+
+ template<typename K, typename V> struct map {};
+}
+# 68 "attr-lifetimebound.cpp" 2
+
+using std::operator""s;
+using std::operator""sv;
+
+namespace p0936r0_examples {
+ std::string_view s = "foo"s; // expected-warning {{temporary}}
+
+ std::string operator+(std::string_view s1, std::string_view s2);
+ void f() {
+ std::string_view sv = "hi";
+ std::string_view sv2 = sv + sv; // expected-warning {{temporary}}
+ sv2 = sv + sv; // FIXME: can we infer that we should warn here too?
+ }
+
+ struct X { int a, b; };
+ const int &f(const X &x [[clang::lifetimebound]]) { return x.a; }
+ const int &r = f(X()); // expected-warning {{temporary}}
+
+ char &c = std::string("hello my pretty long strong")[0]; // expected-warning {{temporary}}
+
+ struct reversed_range {
+ int *begin();
+ int *end();
+ int *p;
+ std::size_t n;
+ };
+ template <typename R> reversed_range reversed(R &&r [[clang::lifetimebound]]) {
+ return reversed_range{r.data(), r.size()};
+ }
+
+ std::vector make_vector();
+ void use_reversed_range() {
+ // FIXME: Don't expose the name of the internal range variable.
+ for (auto x : reversed(make_vector())) {} // expected-warning {{temporary implicitly bound to local reference will be destroyed at the end of the full-expression}}
+ }
+
+ template <typename K, typename V>
+ const V &findOrDefault(const std::map<K, V> &m [[clang::lifetimebound]],
+ const K &key,
+ const V &defvalue [[clang::lifetimebound]]);
+
+ // FIXME: Maybe weaken the wording here: "local reference 'v' could bind to temporary that will be destroyed at end of full-expression"?
+ std::map<std::string, std::string> m;
+ const std::string &v = findOrDefault(m, "foo"s, "bar"s); // expected-warning {{temporary bound to local reference 'v'}}
+}
diff --git a/test/SemaCXX/constexpr-string.cpp b/test/SemaCXX/constexpr-string.cpp
index 2ed35fcc2bdd..1145a2081cba 100644
--- a/test/SemaCXX/constexpr-string.cpp
+++ b/test/SemaCXX/constexpr-string.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 %s -std=c++1z -fsyntax-only -verify -pedantic
-// RUN: %clang_cc1 %s -std=c++1z -fsyntax-only -verify -pedantic -fno-signed-char
-// RUN: %clang_cc1 %s -std=c++1z -fsyntax-only -verify -pedantic -fno-wchar -Dwchar_t=__WCHAR_TYPE__
+// RUN: %clang_cc1 %s -triple x86_64-linux-gnu -std=c++1z -fsyntax-only -verify -pedantic
+// RUN: %clang_cc1 %s -triple x86_64-linux-gnu -std=c++1z -fsyntax-only -verify -pedantic -fno-signed-char
+// RUN: %clang_cc1 %s -triple x86_64-linux-gnu -std=c++1z -fsyntax-only -verify -pedantic -fno-wchar -Dwchar_t=__WCHAR_TYPE__
# 6 "/usr/include/string.h" 1 3 4
extern "C" {
@@ -14,10 +14,13 @@ extern "C" {
extern char *strchr(const char *s, int c);
extern void *memchr(const void *s, int c, size_t n);
+
+ extern void *memcpy(void *d, const void *s, size_t n);
+ extern void *memmove(void *d, const void *s, size_t n);
}
-# 19 "SemaCXX/constexpr-string.cpp" 2
+# 22 "SemaCXX/constexpr-string.cpp" 2
-# 21 "/usr/include/wchar.h" 1 3 4
+# 24 "/usr/include/wchar.h" 1 3 4
extern "C" {
extern size_t wcslen(const wchar_t *p);
@@ -27,9 +30,12 @@ extern "C" {
extern wchar_t *wcschr(const wchar_t *s, wchar_t c);
extern wchar_t *wmemchr(const wchar_t *s, wchar_t c, size_t n);
+
+ extern wchar_t *wmemcpy(wchar_t *d, const wchar_t *s, size_t n);
+ extern wchar_t *wmemmove(wchar_t *d, const wchar_t *s, size_t n);
}
-# 33 "SemaCXX/constexpr-string.cpp" 2
+# 39 "SemaCXX/constexpr-string.cpp" 2
namespace Strlen {
constexpr int n = __builtin_strlen("hello"); // ok
static_assert(n == 5);
@@ -235,3 +241,133 @@ namespace WcschrEtc {
constexpr bool a = !wcschr(L"hello", L'h'); // expected-error {{constant expression}} expected-note {{non-constexpr function 'wcschr' cannot be used in a constant expression}}
constexpr bool b = !wmemchr(L"hello", L'h', 3); // expected-error {{constant expression}} expected-note {{non-constexpr function 'wmemchr' cannot be used in a constant expression}}
}
+
+namespace MemcpyEtc {
+ template<typename T>
+ constexpr T result(T (&arr)[4]) {
+ return arr[0] * 1000 + arr[1] * 100 + arr[2] * 10 + arr[3];
+ }
+
+ constexpr int test_memcpy(int a, int b, int n) {
+ int arr[4] = {1, 2, 3, 4};
+ __builtin_memcpy(arr + a, arr + b, n);
+ // expected-note@-1 2{{overlapping memory regions}}
+ // expected-note@-2 {{size to copy (1) is not a multiple of size of element type 'int'}}
+ // expected-note@-3 {{source is not a contiguous array of at least 2 elements of type 'int'}}
+ // expected-note@-4 {{destination is not a contiguous array of at least 3 elements of type 'int'}}
+ return result(arr);
+ }
+ constexpr int test_memmove(int a, int b, int n) {
+ int arr[4] = {1, 2, 3, 4};
+ __builtin_memmove(arr + a, arr + b, n);
+ // expected-note@-1 {{size to copy (1) is not a multiple of size of element type 'int'}}
+ // expected-note@-2 {{source is not a contiguous array of at least 2 elements of type 'int'}}
+ // expected-note@-3 {{destination is not a contiguous array of at least 3 elements of type 'int'}}
+ return result(arr);
+ }
+ constexpr int test_wmemcpy(int a, int b, int n) {
+ wchar_t arr[4] = {1, 2, 3, 4};
+ __builtin_wmemcpy(arr + a, arr + b, n);
+ // expected-note@-1 2{{overlapping memory regions}}
+ // expected-note-re@-2 {{source is not a contiguous array of at least 2 elements of type '{{wchar_t|int}}'}}
+ // expected-note-re@-3 {{destination is not a contiguous array of at least 3 elements of type '{{wchar_t|int}}'}}
+ return result(arr);
+ }
+ constexpr int test_wmemmove(int a, int b, int n) {
+ wchar_t arr[4] = {1, 2, 3, 4};
+ __builtin_wmemmove(arr + a, arr + b, n);
+ // expected-note-re@-1 {{source is not a contiguous array of at least 2 elements of type '{{wchar_t|int}}'}}
+ // expected-note-re@-2 {{destination is not a contiguous array of at least 3 elements of type '{{wchar_t|int}}'}}
+ return result(arr);
+ }
+
+ static_assert(test_memcpy(1, 2, 4) == 1334);
+ static_assert(test_memcpy(2, 1, 4) == 1224);
+ static_assert(test_memcpy(0, 1, 8) == 2334); // expected-error {{constant}} expected-note {{in call}}
+ static_assert(test_memcpy(1, 0, 8) == 1124); // expected-error {{constant}} expected-note {{in call}}
+ static_assert(test_memcpy(1, 2, 1) == 1334); // expected-error {{constant}} expected-note {{in call}}
+ static_assert(test_memcpy(0, 3, 4) == 4234);
+ static_assert(test_memcpy(0, 3, 8) == 4234); // expected-error {{constant}} expected-note {{in call}}
+ static_assert(test_memcpy(2, 0, 12) == 4234); // expected-error {{constant}} expected-note {{in call}}
+
+ static_assert(test_memmove(1, 2, 4) == 1334);
+ static_assert(test_memmove(2, 1, 4) == 1224);
+ static_assert(test_memmove(0, 1, 8) == 2334);
+ static_assert(test_memmove(1, 0, 8) == 1124);
+ static_assert(test_memmove(1, 2, 1) == 1334); // expected-error {{constant}} expected-note {{in call}}
+ static_assert(test_memmove(0, 3, 4) == 4234);
+ static_assert(test_memmove(0, 3, 8) == 4234); // expected-error {{constant}} expected-note {{in call}}
+ static_assert(test_memmove(2, 0, 12) == 4234); // expected-error {{constant}} expected-note {{in call}}
+
+ static_assert(test_wmemcpy(1, 2, 1) == 1334);
+ static_assert(test_wmemcpy(2, 1, 1) == 1224);
+ static_assert(test_wmemcpy(0, 1, 2) == 2334); // expected-error {{constant}} expected-note {{in call}}
+ static_assert(test_wmemcpy(1, 0, 2) == 1124); // expected-error {{constant}} expected-note {{in call}}
+ static_assert(test_wmemcpy(1, 2, 1) == 1334);
+ static_assert(test_wmemcpy(0, 3, 1) == 4234);
+ static_assert(test_wmemcpy(0, 3, 2) == 4234); // expected-error {{constant}} expected-note {{in call}}
+ static_assert(test_wmemcpy(2, 0, 3) == 4234); // expected-error {{constant}} expected-note {{in call}}
+
+ static_assert(test_wmemmove(1, 2, 1) == 1334);
+ static_assert(test_wmemmove(2, 1, 1) == 1224);
+ static_assert(test_wmemmove(0, 1, 2) == 2334);
+ static_assert(test_wmemmove(1, 0, 2) == 1124);
+ static_assert(test_wmemmove(1, 2, 1) == 1334);
+ static_assert(test_wmemmove(0, 3, 1) == 4234);
+ static_assert(test_wmemmove(0, 3, 2) == 4234); // expected-error {{constant}} expected-note {{in call}}
+ static_assert(test_wmemmove(2, 0, 3) == 4234); // expected-error {{constant}} expected-note {{in call}}
+
+ // Copying is permitted for any trivially-copyable type.
+ struct Trivial { char k; short s; constexpr bool ok() { return k == 3 && s == 4; } };
+ constexpr bool test_trivial() {
+ Trivial arr[3] = {{1, 2}, {3, 4}, {5, 6}};
+ __builtin_memcpy(arr, arr+1, sizeof(Trivial));
+ __builtin_memmove(arr+1, arr, 2 * sizeof(Trivial));
+ return arr[0].ok() && arr[1].ok() && arr[2].ok();
+ }
+ static_assert(test_trivial());
+
+ // But not for a non-trivially-copyable type.
+ struct NonTrivial {
+ constexpr NonTrivial() : n(0) {}
+ constexpr NonTrivial(const NonTrivial &) : n(1) {}
+ int n;
+ };
+ constexpr bool test_nontrivial_memcpy() { // expected-error {{never produces a constant}}
+ NonTrivial arr[3] = {};
+ __builtin_memcpy(arr, arr + 1, sizeof(NonTrivial)); // expected-note 2{{non-trivially-copyable}}
+ return true;
+ }
+ static_assert(test_nontrivial_memcpy()); // expected-error {{constant}} expected-note {{in call}}
+ constexpr bool test_nontrivial_memmove() { // expected-error {{never produces a constant}}
+ NonTrivial arr[3] = {};
+ __builtin_memcpy(arr, arr + 1, sizeof(NonTrivial)); // expected-note 2{{non-trivially-copyable}}
+ return true;
+ }
+ static_assert(test_nontrivial_memmove()); // expected-error {{constant}} expected-note {{in call}}
+
+ // Type puns via constant evaluated memcpy are not supported yet.
+ constexpr float type_pun(const unsigned &n) {
+ float f = 0.0f;
+ __builtin_memcpy(&f, &n, 4); // expected-note {{cannot constant evaluate 'memcpy' from object of type 'const unsigned int' to object of type 'float'}}
+ return f;
+ }
+ static_assert(type_pun(0x3f800000) == 1.0f); // expected-error {{constant}} expected-note {{in call}}
+
+ // Make sure we're not confused by derived-to-base conversions.
+ struct Base { int a; };
+ struct Derived : Base { int b; };
+ constexpr int test_derived_to_base(int n) {
+ Derived arr[2] = {1, 2, 3, 4};
+ Base *p = &arr[0];
+ Base *q = &arr[1];
+ __builtin_memcpy(p, q, sizeof(Base) * n); // expected-note {{source is not a contiguous array of at least 2 elements of type 'MemcpyEtc::Base'}}
+ return arr[0].a * 1000 + arr[0].b * 100 + arr[1].a * 10 + arr[1].b;
+ }
+ static_assert(test_derived_to_base(0) == 1234);
+ static_assert(test_derived_to_base(1) == 3234);
+ // FIXME: We could consider making this work by stripping elements off both
+ // designators until we have a long enough matching size, if both designators
+ // point to the start of their respective final elements.
+ static_assert(test_derived_to_base(2) == 3434); // expected-error {{constant}} expected-note {{in call}}
+}
diff --git a/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp b/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
index f72cb886d81a..cbf7c2eee51c 100644
--- a/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
+++ b/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
@@ -373,6 +373,35 @@ void bar(D<int>& d) {
}
}
+namespace rdar41330135 {
+template <int> struct A {};
+template <class T>
+struct S {
+ template <class U>
+ S(T a, U t, A<sizeof(t)>);
+};
+template <class T> struct D {
+ D(T t, A<sizeof(t)>);
+};
+int f() {
+ S s(0, 0, A<sizeof(int)>());
+ D d(0, A<sizeof(int)>());
+}
+
+namespace test_dupls {
+template<unsigned long> struct X {};
+template<typename T> struct A {
+ A(T t, X<sizeof(t)>);
+};
+A a(0, {});
+template<typename U> struct B {
+ B(U u, X<sizeof(u)>);
+};
+B b(0, {});
+}
+
+}
+
#else
// expected-no-diagnostics
diff --git a/test/SemaCXX/warn-dangling-local.cpp b/test/SemaCXX/warn-dangling-local.cpp
index 19a722f84d16..5c1d56972945 100644
--- a/test/SemaCXX/warn-dangling-local.cpp
+++ b/test/SemaCXX/warn-dangling-local.cpp
@@ -18,3 +18,9 @@ void f() {
// points to, which doesn't live long enough.
int *const &s = (int *const &)T{1, 2, 3}; // expected-warning {{temporary bound to local reference 's' will be destroyed at the end of the full-expression}}
}
+
+// PR38355
+void g() {
+ const int a[] = {a[0]};
+ const int b[] = {a[0]};
+}
diff --git a/test/SemaObjCXX/class-templ-error-null-init.mm b/test/SemaObjCXX/class-templ-error-null-init.mm
new file mode 100644
index 000000000000..b621a3ab24de
--- /dev/null
+++ b/test/SemaObjCXX/class-templ-error-null-init.mm
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++17 -verify %s
+// expected-no-diagnostics
+template <typename a, int* = nullptr>
+struct e {
+ e(a) {}
+};
+e c(0);
diff --git a/test/SemaObjCXX/noescape.mm b/test/SemaObjCXX/noescape.mm
index 6c5d9897aaf0..9432a3a48a0b 100644
--- a/test/SemaObjCXX/noescape.mm
+++ b/test/SemaObjCXX/noescape.mm
@@ -88,3 +88,42 @@ void test0() {
S5<&noescapeFunc2> ne1;
}
+
+@protocol NoescapeProt
+-(void) m0:(int*)__attribute__((noescape)) p; // expected-note 2 {{parameter of overridden method is annotated with __attribute__((noescape))}}
++(void) m1:(int*)__attribute__((noescape)) p;
+-(void) m1:(int*) p;
+@end
+
+__attribute__((objc_root_class))
+@interface C3
+-(void) m0:(int*) p;
++(void) m1:(int*)__attribute__((noescape)) p;
+-(void) m1:(int*) p;
+@end
+
+@interface C3 () <NoescapeProt> // expected-note {{class extension conforms to protocol 'NoescapeProt' which defines method 'm0:'}}
+@end
+
+@implementation C3
+-(void) m0:(int*) p { // expected-warning {{parameter of overriding method should be annotated with __attribute__((noescape))}}
+}
++(void) m1:(int*)__attribute__((noescape)) p {
+}
+-(void) m1:(int*) p {
+}
+@end
+
+__attribute__((objc_root_class))
+@interface C4 <NoescapeProt>
+-(void) m0:(int*) p; // expected-warning {{parameter of overriding method should be annotated with __attribute__((noescape))}}
+@end
+
+@implementation C4
+-(void) m0:(int*) p {
+}
++(void) m1:(int*)__attribute__((noescape)) p {
+}
+-(void) m1:(int*) p {
+}
+@end
diff --git a/test/SemaOpenCL/invalid-kernel-parameters.cl b/test/SemaOpenCL/invalid-kernel-parameters.cl
index 2433c17fe022..e3372b188877 100644
--- a/test/SemaOpenCL/invalid-kernel-parameters.cl
+++ b/test/SemaOpenCL/invalid-kernel-parameters.cl
@@ -9,7 +9,35 @@ kernel void half_arg(half x) { } // expected-error{{declaring function parameter
// bool, half, size_t, ptrdiff_t, intptr_t, and uintptr_t
// or a struct / union with any of these types in them
-// TODO: Ban int types, size_t, ptrdiff_t ...
+typedef __SIZE_TYPE__ size_t; // expected-note{{'size_t' (aka 'unsigned int') declared here}}
+ // expected-note@-1{{'size_t' (aka 'unsigned int') declared here}}
+typedef __PTRDIFF_TYPE__ ptrdiff_t; // expected-note{{'ptrdiff_t' (aka 'int') declared here}}
+typedef __INTPTR_TYPE__ intptr_t; // expected-note{{'intptr_t' (aka 'int') declared here}}
+typedef __UINTPTR_TYPE__ uintptr_t; // expected-note{{'uintptr_t' (aka 'unsigned int') declared here}}
+
+kernel void size_t_arg(size_t x) {} // expected-error{{'size_t' (aka 'unsigned int') cannot be used as the type of a kernel parameter}}
+
+kernel void ptrdiff_t_arg(ptrdiff_t x) {} // expected-error{{'ptrdiff_t' (aka 'int') cannot be used as the type of a kernel parameter}}
+
+kernel void intptr_t_arg(intptr_t x) {} // expected-error{{'intptr_t' (aka 'int') cannot be used as the type of a kernel parameter}}
+
+kernel void uintptr_t_arg(uintptr_t x) {} // expected-error{{'uintptr_t' (aka 'unsigned int') cannot be used as the type of a kernel parameter}}
+
+typedef size_t size_ty;
+struct SizeTStruct { // expected-note{{within field of type 'SizeTStruct' declared here}}
+ size_ty s; // expected-note{{field of illegal type 'size_ty' (aka 'unsigned int') declared here}}
+};
+kernel void size_t_struct_arg(struct SizeTStruct x) {} // expected-error{{'struct SizeTStruct' cannot be used as the type of a kernel parameter}}
+
+union SizeTUnion { // expected-note{{within field of type 'SizeTUnion' declared here}}
+ size_t s; // expected-note{{field of illegal type 'size_t' (aka 'unsigned int') declared here}}
+ float f;
+};
+kernel void size_t_union_arg(union SizeTUnion x) {} // expected-error{{'union SizeTUnion' cannot be used as the type of a kernel parameter}}
+
+typedef size_t s_ty; // expected-note{{'s_ty' (aka 'unsigned int') declared here}}
+typedef s_ty ss_ty; // expected-note{{'ss_ty' (aka 'unsigned int') declared here}}
+kernel void typedef_to_size_t(ss_ty s) {} // expected-error{{'ss_ty' (aka 'unsigned int') cannot be used as the type of a kernel parameter}}
kernel void bool_arg(bool x) { } // expected-error{{'bool' cannot be used as the type of a kernel parameter}}
@@ -136,3 +164,16 @@ struct AlsoUser // expected-note{{within field of type 'AlsoUser' declared here}
};
kernel void pointer_in_nested_struct_arg_2(struct Valid valid, struct NestedPointer arg, struct AlsoUser also) { } // expected-error 2 {{struct kernel parameters may not contain pointers}}
+
+struct ArrayOfPtr // expected-note{{within field of type 'ArrayOfPtr' declared here}}
+{
+ float *arr[3]; // expected-note{{field of illegal type 'float *[3]' declared here}}
+ // expected-note@-1{{field of illegal type 'float *[3]' declared here}}
+};
+kernel void array_of_ptr(struct ArrayOfPtr arr) {} // expected-error{{struct kernel parameters may not contain pointers}}
+
+struct ArrayOfStruct // expected-note{{within field of type 'ArrayOfStruct' declared here}}
+{
+ struct ArrayOfPtr arr[3]; // expected-note{{within field of type 'struct ArrayOfPtr [3]' declared here}}
+};
+kernel void array_of_struct(struct ArrayOfStruct arr) {} // expected-error{{struct kernel parameters may not contain pointers}}