diff options
Diffstat (limited to 'test')
35 files changed, 952 insertions, 78 deletions
diff --git a/test/Analysis/DynamicTypePropagation.m b/test/Analysis/DynamicTypePropagation.m index 25a0ae35fd32..63904b842567 100644 --- a/test/Analysis/DynamicTypePropagation.m +++ b/test/Analysis/DynamicTypePropagation.m @@ -4,6 +4,9 @@ # error Compiler does not support Objective-C generics? #endif +typedef __typeof(sizeof(int)) size_t; +void *memset(void *, int, size_t); + #define nil 0 typedef unsigned long NSUInteger; typedef int BOOL; @@ -21,6 +24,7 @@ __attribute__((objc_root_class)) @end @interface NSArray<ObjectType> : NSObject +- (void) init; - (BOOL)contains:(ObjectType)obj; - (ObjectType)getObjAtIndex:(NSUInteger)idx; - (ObjectType)objectAtIndexedSubscript:(NSUInteger)idx; @@ -55,3 +59,11 @@ void testArgument(NSArray<MyType *> *arr, id element) { // MyType! [element myFunction:0 myParam:0 ]; } + +// Do not try this at home! The analyzer shouldn't crash though when it +// tries to figure out the dynamic type behind the alloca's return value. +void testAlloca(size_t NSArrayClassSizeWeKnowSomehow) { + NSArray *arr = __builtin_alloca(NSArrayClassSizeWeKnowSomehow); + memset(arr, 0, NSArrayClassSizeWeKnowSomehow); + [arr init]; // no-crash +} diff --git a/test/Analysis/analyzer_test.py b/test/Analysis/analyzer_test.py index 58df11a4ba47..0aa2dbc1bb09 100644 --- a/test/Analysis/analyzer_test.py +++ b/test/Analysis/analyzer_test.py @@ -5,24 +5,39 @@ import lit.TestRunner class AnalyzerTest(lit.formats.ShTest): def execute(self, test, litConfig): - result = self.executeWithAnalyzeSubstitution( - test, litConfig, '-analyzer-constraints=range') + results = [] - if result.code == lit.Test.FAIL: - return result + # Parse any test requirements ('REQUIRES: ') + saved_test = test + lit.TestRunner.parseIntegratedTestScript(test) + + if 'z3' not in test.requires: + results.append(self.executeWithAnalyzeSubstitution( + saved_test, litConfig, '-analyzer-constraints=range')) + + if results[-1].code == lit.Test.FAIL: + return results[-1] # If z3 backend available, add an additional run line for it if test.config.clang_staticanalyzer_z3 == '1': - result = self.executeWithAnalyzeSubstitution( - test, litConfig, '-analyzer-constraints=z3 -DANALYZER_CM_Z3') + results.append(self.executeWithAnalyzeSubstitution( + saved_test, litConfig, '-analyzer-constraints=z3 -DANALYZER_CM_Z3')) - return result + # Combine all result outputs into the last element + for x in results: + if x != results[-1]: + results[-1].output = x.output + results[-1].output + + if results: + return results[-1] + return lit.Test.Result(lit.Test.UNSUPPORTED, + "Test requires the following unavailable features: z3") def executeWithAnalyzeSubstitution(self, test, litConfig, substitution): saved_substitutions = list(test.config.substitutions) test.config.substitutions.append(('%analyze', substitution)) result = lit.TestRunner.executeShTest(test, litConfig, - self.execute_external) + self.execute_external) test.config.substitutions = saved_substitutions return result diff --git a/test/CodeCompletion/member-access.cpp b/test/CodeCompletion/member-access.cpp index 53af121951bb..a0dc7b485679 100644 --- a/test/CodeCompletion/member-access.cpp +++ b/test/CodeCompletion/member-access.cpp @@ -145,4 +145,22 @@ public: // CHECK-CC6: o2 : [#BaseTemplate<T>#]o2 // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:142:11 %s -o - | FileCheck -check-prefix=CHECK-CC6 %s } + + static void staticFn(T &obj); + + struct Nested { }; }; + +template<typename T> +void dependentColonColonCompletion() { + Template<T>::staticFn(); +// CHECK-CC7: function : [#void#]function() +// CHECK-CC7: Nested : Nested +// CHECK-CC7: o1 : [#BaseTemplate<int>#]o1 +// CHECK-CC7: o2 : [#BaseTemplate<T>#]o2 +// CHECK-CC7: staticFn : [#void#]staticFn(<#T &obj#>) +// CHECK-CC7: Template : Template +// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:156:16 %s -o - | FileCheck -check-prefix=CHECK-CC7 %s + typename Template<T>::Nested m; +// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:164:25 %s -o - | FileCheck -check-prefix=CHECK-CC7 %s +} diff --git a/test/CodeGen/Inputs/thinlto-multi-module.ll b/test/CodeGen/Inputs/thinlto-multi-module.ll new file mode 100644 index 000000000000..e8dc16a8f572 --- /dev/null +++ b/test/CodeGen/Inputs/thinlto-multi-module.ll @@ -0,0 +1,9 @@ +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define void @f2() { + ret void +} + +!0 = !{i32 1, !"ThinLTO", i32 0} +!llvm.module.flags = !{ !0 } diff --git a/test/CodeGen/attributes.c b/test/CodeGen/attributes.c index 9e5fa9f90651..34833a246920 100644 --- a/test/CodeGen/attributes.c +++ b/test/CodeGen/attributes.c @@ -56,6 +56,13 @@ void t4() {} void t7() __attribute__((noreturn, nothrow)); void t7() { while (1) {} } +// CHECK: define void @t72() [[COLDDEF:#[0-9]+]] { +void t71(void) __attribute__((cold)); +void t72() __attribute__((cold)); +void t72() { t71(); } +// CHECK: call void @t71() [[COLDSITE:#[0-9]+]] +// CHECK: declare void @t71() [[COLDDECL:#[0-9]+]] + // CHECK: define void @t10() [[NUW]] section "SECT" { void t10(void) __attribute__((section("SECT"))); void t10(void) {} @@ -92,3 +99,6 @@ void __attribute__((section(".bar"))) t22(void) {} // CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} } // CHECK: attributes [[NR]] = { noinline noreturn nounwind{{.*}} } +// CHECK: attributes [[COLDDEF]] = { cold {{.*}}} +// CHECK: attributes [[COLDDECL]] = { cold {{.*}}} +// CHECK: attributes [[COLDSITE]] = { cold {{.*}}} diff --git a/test/CodeGen/avx-builtins.c b/test/CodeGen/avx-builtins.c index 90f428efb339..31a08440d061 100644 --- a/test/CodeGen/avx-builtins.c +++ b/test/CodeGen/avx-builtins.c @@ -1427,3 +1427,51 @@ float test_mm256_cvtss_f32(__m256 __a) // CHECK: extractelement <8 x float> %{{.*}}, i32 0 return _mm256_cvtss_f32(__a); } + +__m256 test_mm256_cmp_ps_true(__m256 a, __m256 b) { + // CHECK-LABEL: @test_mm256_cmp_ps_true + // CHECK: store <8 x float> <float 0xFFFFFFFFE0000000, + return _mm256_cmp_ps(a, b, _CMP_TRUE_UQ); +} + +__m256 test_mm256_cmp_pd_true(__m256 a, __m256 b) { + // CHECK-LABEL: @test_mm256_cmp_pd_true + // CHECK: store <4 x double> <double 0xFFFFFFFFFFFFFFFF, + return _mm256_cmp_pd(a, b, _CMP_TRUE_UQ); +} + +__m256 test_mm256_cmp_ps_false(__m256 a, __m256 b) { + // CHECK-LABEL: @test_mm256_cmp_ps_false + // CHECK: store <8 x float> zeroinitializer, <8 x float>* %tmp, align 32 + return _mm256_cmp_ps(a, b, _CMP_FALSE_OQ); +} + +__m256 test_mm256_cmp_pd_false(__m256 a, __m256 b) { + // CHECK-LABEL: @test_mm256_cmp_pd_false + // CHECK: store <4 x double> zeroinitializer, <4 x double>* %tmp, align 32 + return _mm256_cmp_pd(a, b, _CMP_FALSE_OQ); +} + +__m256 test_mm256_cmp_ps_strue(__m256 a, __m256 b) { + // CHECK-LABEL: @test_mm256_cmp_ps_strue + // CHECK: store <8 x float> <float 0xFFFFFFFFE0000000, + return _mm256_cmp_ps(a, b, _CMP_TRUE_US); +} + +__m256 test_mm256_cmp_pd_strue(__m256 a, __m256 b) { + // CHECK-LABEL: @test_mm256_cmp_pd_strue + // CHECK: store <4 x double> <double 0xFFFFFFFFFFFFFFFF, + return _mm256_cmp_pd(a, b, _CMP_TRUE_US); +} + +__m256 test_mm256_cmp_ps_sfalse(__m256 a, __m256 b) { + // CHECK-LABEL: @test_mm256_cmp_ps_sfalse + // CHECK: store <8 x float> zeroinitializer, <8 x float>* %tmp, align 32 + return _mm256_cmp_ps(a, b, _CMP_FALSE_OS); +} + +__m256 test_mm256_cmp_pd_sfalse(__m256 a, __m256 b) { + // CHECK-LABEL: @test_mm256_cmp_pd_sfalse + // CHECK: store <4 x double> zeroinitializer, <4 x double>* %tmp, align 32 + return _mm256_cmp_pd(a, b, _CMP_FALSE_OS); +} diff --git a/test/CodeGen/builtins-ppc-error.c b/test/CodeGen/builtins-ppc-error.c index c3d6e639d828..29eebf286100 100644 --- a/test/CodeGen/builtins-ppc-error.c +++ b/test/CodeGen/builtins-ppc-error.c @@ -11,6 +11,8 @@ #include <altivec.h> extern vector signed int vsi; +extern vector signed int vui; +extern vector float vf; extern vector unsigned char vuc; void testInsertWord(void) { @@ -34,3 +36,34 @@ void testXXSLDWI(int index) { vec_xxsldwi(1, 2, 3); //expected-error {{first two arguments to '__builtin_vsx_xxsldwi' must be vectors}} vec_xxsldwi(vsi, vuc, 2); //expected-error {{first two arguments to '__builtin_vsx_xxsldwi' must have the same type}} } + +void testCTF(int index) { + vec_ctf(vsi, index); //expected-error {{argument to '__builtin_altivec_vcfsx' must be a constant integer}} + vec_ctf(vui, index); //expected-error {{argument to '__builtin_altivec_vcfsx' must be a constant integer}} +} + +void testVCFSX(int index) { + vec_vcfsx(vsi, index); //expected-error {{argument to '__builtin_altivec_vcfsx' must be a constant integer}} +} + +void testVCFUX(int index) { + vec_vcfux(vui, index); //expected-error {{argument to '__builtin_altivec_vcfux' must be a constant integer}} +} + +void testCTS(int index) { + vec_cts(vf, index); //expected-error {{argument to '__builtin_altivec_vctsxs' must be a constant integer}} + +} + +void testVCTSXS(int index) { + vec_vctsxs(vf, index); //expected-error {{argument to '__builtin_altivec_vctsxs' must be a constant integer}} +} + +void testCTU(int index) { + vec_ctu(vf, index); //expected-error {{argument to '__builtin_altivec_vctuxs' must be a constant integer}} + +} + +void testVCTUXS(int index) { + vec_vctuxs(vf, index); //expected-error {{argument to '__builtin_altivec_vctuxs' must be a constant integer}} +} diff --git a/test/CodeGen/dependent-lib.c b/test/CodeGen/dependent-lib.c index 9cf49c88d77b..7178a29692a1 100644 --- a/test/CodeGen/dependent-lib.c +++ b/test/CodeGen/dependent-lib.c @@ -3,14 +3,10 @@ // RUN: %clang_cc1 %s --dependent-lib=msvcrt -triple x86_64-pc-win32 -emit-llvm -o - | FileCheck %s // RUN: %clang_cc1 %s --dependent-lib=msvcrt -triple i686-pc-linux -emit-llvm -o - | FileCheck -check-prefix LINUX %s -// CHECK: !llvm.module.flags = !{{{.*}}} -// CHECK: !{{[0-9]+}} = !{i32 6, !"Linker Options", ![[link_opts:[0-9]+]]} -// CHECK: ![[link_opts]] = !{![[msvcrt:[0-9]+]]} +// CHECK: !llvm.linker.options = !{![[msvcrt:[0-9]+]]} // CHECK: ![[msvcrt]] = !{!"/DEFAULTLIB:msvcrt.lib"} -// LINUX: !llvm.module.flags = !{{{.*}}} -// LINUX: !{{[0-9]+}} = !{i32 6, !"Linker Options", ![[link_opts:[0-9]+]]} -// LINUX: ![[link_opts]] = !{![[msvcrt:[0-9]+]]} +// LINUX: !llvm.linker.options = !{![[msvcrt:[0-9]+]]} // LINUX: ![[msvcrt]] = !{!"-lmsvcrt"} int f(); diff --git a/test/CodeGen/linker-option.c b/test/CodeGen/linker-option.c index b1b2ec461c89..13bd981179b5 100644 --- a/test/CodeGen/linker-option.c +++ b/test/CodeGen/linker-option.c @@ -1,8 +1,6 @@ // RUN: %clang_cc1 %s --linker-option=/include:foo -triple i686-pc-win32 -emit-llvm -o - | FileCheck %s -// CHECK: !llvm.module.flags = !{{{.*}}} -// CHECK: !{{[0-9]+}} = !{i32 6, !"Linker Options", ![[link_opts:[0-9]+]]} -// CHECK: ![[link_opts]] = !{![[msvcrt:[0-9]+]]} +// CHECK: !llvm.linker.options = !{![[msvcrt:[0-9]+]]} // CHECK: ![[msvcrt]] = !{!"/include:foo"} int f(); diff --git a/test/CodeGen/mips-debug-info-bitfield.c b/test/CodeGen/mips-debug-info-bitfield.c new file mode 100644 index 000000000000..a0e2ed9cde86 --- /dev/null +++ b/test/CodeGen/mips-debug-info-bitfield.c @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -x c -debug-info-kind=limited -triple mips-none-linux-gnu -emit-llvm -o - %s | FileCheck %s + +struct fields +{ + unsigned a : 4; + unsigned b : 4; +} flags; + +// CHECK: !DIDerivedType(tag: DW_TAG_member, +// CHECK-SAME: {{.*}}name: "a" +// CHECK-NOT: {{.*}}offset: +// CHECK-SAME: {{.*}}flags: DIFlagBitField + +// CHECK: !DIDerivedType(tag: DW_TAG_member, +// CHECK-SAME: {{.*}}name: "b" +// CHECK-SAME: {{.*}}offset: 4 +// CHECK-SAME: {{.*}}flags: DIFlagBitField diff --git a/test/CodeGen/pragma-comment.c b/test/CodeGen/pragma-comment.c index 71a7dfc0b018..e20efacdcb22 100644 --- a/test/CodeGen/pragma-comment.c +++ b/test/CodeGen/pragma-comment.c @@ -14,9 +14,7 @@ #pragma comment(linker," /bar=" BAR) #pragma comment(linker," /foo=\"foo bar\"") -// CHECK: !llvm.module.flags = !{{{.*}}} -// CHECK: !{{[0-9]+}} = !{i32 6, !"Linker Options", ![[link_opts:[0-9]+]]} -// CHECK: ![[link_opts]] = !{![[msvcrt:[0-9]+]], ![[kernel32:[0-9]+]], ![[USER32:[0-9]+]], ![[space:[0-9]+]], ![[bar:[0-9]+]], ![[foo:[0-9]+]]} +// CHECK: !llvm.linker.options = !{![[msvcrt:[0-9]+]], ![[kernel32:[0-9]+]], ![[USER32:[0-9]+]], ![[space:[0-9]+]], ![[bar:[0-9]+]], ![[foo:[0-9]+]]} // CHECK: ![[msvcrt]] = !{!"/DEFAULTLIB:msvcrt.lib"} // CHECK: ![[kernel32]] = !{!"/DEFAULTLIB:kernel32.lib"} // CHECK: ![[USER32]] = !{!"/DEFAULTLIB:USER32.LIB"} diff --git a/test/CodeGen/pragma-detect_mismatch.c b/test/CodeGen/pragma-detect_mismatch.c index 08259fc6be71..066183d31264 100644 --- a/test/CodeGen/pragma-detect_mismatch.c +++ b/test/CodeGen/pragma-detect_mismatch.c @@ -6,8 +6,6 @@ #define BAR "2" #pragma detect_mismatch("test2", BAR) -// CHECK: !llvm.module.flags = !{{{.*}}} -// CHECK: !{{[0-9]+}} = !{i32 6, !"Linker Options", ![[link_opts:[0-9]+]]} -// CHECK: ![[link_opts]] = !{![[test:[0-9]+]], ![[test2:[0-9]+]]} +// CHECK: !llvm.linker.options = !{![[test:[0-9]+]], ![[test2:[0-9]+]]} // CHECK: ![[test]] = !{!"/FAILIFMISMATCH:\22test=1\22"} // CHECK: ![[test2]] = !{!"/FAILIFMISMATCH:\22test2=2\22"} diff --git a/test/CodeGen/thinlto-backend-option.ll b/test/CodeGen/thinlto-backend-option.ll index 4c7c0ea3efcd..4fcdd079df84 100644 --- a/test/CodeGen/thinlto-backend-option.ll +++ b/test/CodeGen/thinlto-backend-option.ll @@ -8,6 +8,8 @@ ; RUN: %clang -flto=thin -c -o %t.o %s ; RUN: llvm-lto -thinlto -o %t %t.o -; RUN: not %clang_cc1 -x ir %t.o -fthinlto-index=%t.thinlto.bc -backend-option -nonexistent -emit-obj -o /dev/null 2>&1 | FileCheck %s +; RUN: not %clang_cc1 -x ir %t.o -fthinlto-index=%t.thinlto.bc -backend-option -nonexistent -emit-obj -o /dev/null 2>&1 | FileCheck %s -check-prefix=UNKNOWN +; UNKNOWN: clang: Unknown command line argument '-nonexistent' -; CHECK: clang: Unknown command line argument '-nonexistent' +; RUN: not %clang_cc1 -flto=thinfoo 2>&1 | FileCheck %s -check-prefix=INVALID +; INVALID: error: invalid value 'thinfoo' in '-flto=thinfoo' diff --git a/test/CodeGen/thinlto-multi-module.ll b/test/CodeGen/thinlto-multi-module.ll index 21d28cf44da2..385d98c74d94 100644 --- a/test/CodeGen/thinlto-multi-module.ll +++ b/test/CodeGen/thinlto-multi-module.ll @@ -3,8 +3,8 @@ ; RUN: opt -module-summary -o %t1.o %s ; RUN: llvm-lto -thinlto -o %t %t1.o -; RUN: opt -o %t2.o %S/Inputs/thinlto_backend.ll -; RUN: llvm-cat -b -o %t1cat.o %t1.o %t2.o +; RUN: opt -module-summary -o %t2.o %S/Inputs/thinlto-multi-module.ll +; RUN: llvm-cat -b -o %t1cat.o %t2.o %t1.o ; RUN: cp %t1cat.o %t1.o ; RUN: %clang -target x86_64-unknown-linux-gnu -O2 -o %t3.o -x ir %t1.o -c -fthinlto-index=%t.thinlto.bc ; RUN: llvm-nm %t3.o | FileCheck --check-prefix=CHECK-OBJ %s diff --git a/test/CodeGen/ubsan-pointer-overflow.m b/test/CodeGen/ubsan-pointer-overflow.m index 56df95baff55..da622355fdb4 100644 --- a/test/CodeGen/ubsan-pointer-overflow.m +++ b/test/CodeGen/ubsan-pointer-overflow.m @@ -5,23 +5,21 @@ void unary_arith(char *p) { // CHECK: [[BASE:%.*]] = ptrtoint i8* {{.*}} to i64, !nosanitize // CHECK-NEXT: [[COMPGEP:%.*]] = add i64 [[BASE]], 1, !nosanitize // CHECK-NEXT: [[POSVALID:%.*]] = icmp uge i64 [[COMPGEP]], [[BASE]], !nosanitize - // CHECK-NEXT: [[NEGVALID:%.*]] = icmp ult i64 [[COMPGEP]], [[BASE]], !nosanitize - // CHECK-NEXT: [[DIFFVALID:%.*]] = select i1 true, i1 [[POSVALID]], i1 [[NEGVALID]], !nosanitize - // CHECK-NEXT: [[VALID:%.*]] = and i1 true, [[DIFFVALID]], !nosanitize - // CHECK-NEXT: br i1 [[VALID]]{{.*}}, !nosanitize + // CHECK-NEXT: br i1 [[POSVALID]]{{.*}}, !nosanitize // CHECK: call void @__ubsan_handle_pointer_overflow{{.*}}, i64 [[BASE]], i64 [[COMPGEP]]){{.*}}, !nosanitize ++p; // CHECK: ptrtoint i8* {{.*}} to i64, !nosanitize // CHECK-NEXT: add i64 {{.*}}, -1, !nosanitize // CHECK: select i1 false{{.*}}, !nosanitize - // CHECK-NEXT: and i1 true{{.*}}, !nosanitize // CHECK: call void @__ubsan_handle_pointer_overflow{{.*}} --p; + // CHECK-NOT: select // CHECK: call void @__ubsan_handle_pointer_overflow{{.*}} p++; + // CHECK: select // CHECK: call void @__ubsan_handle_pointer_overflow{{.*}} p--; } @@ -30,22 +28,43 @@ void unary_arith(char *p) { void binary_arith(char *p, int i) { // CHECK: [[SMUL:%.*]] = call { i64, i1 } @llvm.smul.with.overflow.i64(i64 1, i64 %{{.*}}), !nosanitize // CHECK-NEXT: [[SMULOFLOW:%.*]] = extractvalue { i64, i1 } [[SMUL]], 1, !nosanitize - // CHECK-NEXT: [[OFFSETOFLOW:%.*]] = or i1 false, [[SMULOFLOW]], !nosanitize // CHECK-NEXT: [[SMULVAL:%.*]] = extractvalue { i64, i1 } [[SMUL]], 0, !nosanitize // CHECK-NEXT: [[BASE:%.*]] = ptrtoint i8* {{.*}} to i64, !nosanitize // CHECK-NEXT: [[COMPGEP:%.*]] = add i64 [[BASE]], [[SMULVAL]], !nosanitize + // CHECK-NEXT: [[OFFSETVALID:%.*]] = xor i1 [[SMULOFLOW]], true, !nosanitize // CHECK-NEXT: [[POSVALID:%.*]] = icmp uge i64 [[COMPGEP]], [[BASE]], !nosanitize - // CHECK-NEXT: [[NEGVALID:%.*]] = icmp ult i64 [[COMPGEP]], [[BASE]], !nosanitize // CHECK-NEXT: [[POSOFFSET:%.*]] = icmp sge i64 [[SMULVAL]], 0, !nosanitize - // CHECK-DAG: [[OFFSETVALID:%.*]] = xor i1 [[OFFSETOFLOW]], true, !nosanitize - // CHECK-DAG: [[DIFFVALID:%.*]] = select i1 [[POSOFFSET]], i1 [[POSVALID]], i1 [[NEGVALID]], !nosanitize - // CHECK: [[VALID:%.*]] = and i1 [[OFFSETVALID]], [[DIFFVALID]], !nosanitize + // CHECK-NEXT: [[NEGVALID:%.*]] = icmp ult i64 [[COMPGEP]], [[BASE]], !nosanitize + // CHECK-NEXT: [[DIFFVALID:%.*]] = select i1 [[POSOFFSET]], i1 [[POSVALID]], i1 [[NEGVALID]], !nosanitize + // CHECK: [[VALID:%.*]] = and i1 [[DIFFVALID]], [[OFFSETVALID]], !nosanitize // CHECK-NEXT: br i1 [[VALID]]{{.*}}, !nosanitize // CHECK: call void @__ubsan_handle_pointer_overflow{{.*}}, i64 [[BASE]], i64 [[COMPGEP]]){{.*}}, !nosanitize p + i; // CHECK: [[OFFSET:%.*]] = sub i64 0, {{.*}} // CHECK-NEXT: getelementptr inbounds {{.*}} [[OFFSET]] + // CHECK: select + // CHECK: call void @__ubsan_handle_pointer_overflow{{.*}} + p - i; +} + +// CHECK-LABEL: define void @binary_arith_unsigned +void binary_arith_unsigned(char *p, unsigned i) { + // CHECK: [[SMUL:%.*]] = call { i64, i1 } @llvm.smul.with.overflow.i64(i64 1, i64 %{{.*}}), !nosanitize + // CHECK-NEXT: [[SMULOFLOW:%.*]] = extractvalue { i64, i1 } [[SMUL]], 1, !nosanitize + // CHECK-NEXT: [[SMULVAL:%.*]] = extractvalue { i64, i1 } [[SMUL]], 0, !nosanitize + // CHECK-NEXT: [[BASE:%.*]] = ptrtoint i8* {{.*}} to i64, !nosanitize + // CHECK-NEXT: [[COMPGEP:%.*]] = add i64 [[BASE]], [[SMULVAL]], !nosanitize + // CHECK-NEXT: [[OFFSETVALID:%.*]] = xor i1 [[SMULOFLOW]], true, !nosanitize + // CHECK-NEXT: [[POSVALID:%.*]] = icmp uge i64 [[COMPGEP]], [[BASE]], !nosanitize + // CHECK: [[VALID:%.*]] = and i1 [[POSVALID]], [[OFFSETVALID]], !nosanitize + // CHECK-NEXT: br i1 [[VALID]]{{.*}}, !nosanitize + // CHECK: call void @__ubsan_handle_pointer_overflow{{.*}}, i64 [[BASE]], i64 [[COMPGEP]]){{.*}}, !nosanitize + p + i; + + // CHECK: [[OFFSET:%.*]] = sub i64 0, {{.*}} + // CHECK-NEXT: getelementptr inbounds {{.*}} [[OFFSET]] + // CHECK: select // CHECK: call void @__ubsan_handle_pointer_overflow{{.*}} p - i; } @@ -55,16 +74,15 @@ void fixed_len_array(int k) { // CHECK: getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[ARR:%.*]], i64 0, i64 [[IDXPROM:%.*]] // CHECK-NEXT: [[SMUL:%.*]] = call { i64, i1 } @llvm.smul.with.overflow.i64(i64 40, i64 [[IDXPROM]]), !nosanitize // CHECK-NEXT: [[SMULOFLOW:%.*]] = extractvalue { i64, i1 } [[SMUL]], 1, !nosanitize - // CHECK-NEXT: [[OFFSETOFLOW:%.*]] = or i1 false, [[SMULOFLOW]], !nosanitize // CHECK-NEXT: [[SMULVAL:%.*]] = extractvalue { i64, i1 } [[SMUL]], 0, !nosanitize // CHECK-NEXT: [[BASE:%.*]] = ptrtoint [10 x [10 x i32]]* [[ARR]] to i64, !nosanitize // CHECK-NEXT: [[COMPGEP:%.*]] = add i64 [[BASE]], [[SMULVAL]], !nosanitize + // CHECK-NEXT: [[OFFSETVALID:%.*]] = xor i1 [[SMULOFLOW]], true, !nosanitize // CHECK-NEXT: [[POSVALID:%.*]] = icmp uge i64 [[COMPGEP]], [[BASE]], !nosanitize - // CHECK-NEXT: [[NEGVALID:%.*]] = icmp ult i64 [[COMPGEP]], [[BASE]], !nosanitize // CHECK-NEXT: [[POSOFFSET:%.*]] = icmp sge i64 [[SMULVAL]], 0, !nosanitize - // CHECK-DAG: [[OFFSETVALID:%.*]] = xor i1 [[OFFSETOFLOW]], true, !nosanitize - // CHECK-DAG: [[DIFFVALID:%.*]] = select i1 [[POSOFFSET]], i1 [[POSVALID]], i1 [[NEGVALID]], !nosanitize - // CHECK: [[VALID:%.*]] = and i1 [[OFFSETVALID]], [[DIFFVALID]], !nosanitize + // CHECK-NEXT: [[NEGVALID:%.*]] = icmp ult i64 [[COMPGEP]], [[BASE]], !nosanitize + // CHECK-NEXT: [[DIFFVALID:%.*]] = select i1 [[POSOFFSET]], i1 [[POSVALID]], i1 [[NEGVALID]], !nosanitize + // CHECK: [[VALID:%.*]] = and i1 [[DIFFVALID]], [[OFFSETVALID]], !nosanitize // CHECK-NEXT: br i1 [[VALID]]{{.*}}, !nosanitize // CHECK: call void @__ubsan_handle_pointer_overflow{{.*}}, i64 [[BASE]], i64 [[COMPGEP]]){{.*}}, !nosanitize @@ -101,6 +119,24 @@ void pointer_array(int **arr, int k) { arr[k][k]; } +// CHECK-LABEL: define void @pointer_array_unsigned_indices +void pointer_array_unsigned_indices(int **arr, unsigned k) { + // CHECK-NOT: select + // CHECK: call void @__ubsan_handle_pointer_overflow{{.*}} + // CHECK-NOT: select + // CHECK: call void @__ubsan_handle_pointer_overflow{{.*}} + arr[k][k]; +} + +// CHECK-LABEL: define void @pointer_array_mixed_indices +void pointer_array_mixed_indices(int **arr, int i, unsigned j) { + // CHECK: select + // CHECK: call void @__ubsan_handle_pointer_overflow{{.*}} + // CHECK-NOT: select + // CHECK: call void @__ubsan_handle_pointer_overflow{{.*}} + arr[i][j]; +} + struct S1 { int pad1; union { @@ -118,6 +154,7 @@ void struct_index(struct S1 *p) { // CHECK: getelementptr inbounds %struct.S1, %struct.S1* [[P:%.*]], i64 10 // CHECK-NEXT: [[BASE:%.*]] = ptrtoint %struct.S1* [[P]] to i64, !nosanitize // CHECK-NEXT: [[COMPGEP:%.*]] = add i64 [[BASE]], 240, !nosanitize + // CHECK: select // CHECK: @__ubsan_handle_pointer_overflow{{.*}} i64 [[BASE]], i64 [[COMPGEP]]) {{.*}}, !nosanitize // CHECK-NOT: @__ubsan_handle_pointer_overflow @@ -130,10 +167,12 @@ typedef void (*funcptr_t)(void); // CHECK-LABEL: define void @function_pointer_arith void function_pointer_arith(funcptr_t *p, int k) { // CHECK: add i64 {{.*}}, 8, !nosanitize + // CHECK-NOT: select // CHECK: @__ubsan_handle_pointer_overflow{{.*}} ++p; // CHECK: @llvm.smul.with.overflow.i64(i64 8, i64 {{.*}}), !nosanitize + // CHECK: select // CHECK: call void @__ubsan_handle_pointer_overflow{{.*}} p + k; } @@ -145,11 +184,13 @@ void variable_len_array_arith(int n, int k) { // CHECK: getelementptr inbounds i32, i32* {{.*}}, i64 [[INC:%.*]] // CHECK: @llvm.smul.with.overflow.i64(i64 4, i64 [[INC]]), !nosanitize + // CHECK-NOT: select // CHECK: call void @__ubsan_handle_pointer_overflow{{.*}} ++p; // CHECK: getelementptr inbounds i32, i32* {{.*}}, i64 [[IDXPROM:%.*]] // CHECK: @llvm.smul.with.overflow.i64(i64 4, i64 [[IDXPROM]]), !nosanitize + // CHECK: select // CHECK: call void @__ubsan_handle_pointer_overflow{{.*}} p + k; } @@ -157,6 +198,7 @@ void variable_len_array_arith(int n, int k) { // CHECK-LABEL: define void @objc_id void objc_id(id *p) { // CHECK: add i64 {{.*}}, 8, !nosanitize + // CHECK-NOT: select // CHECK: @__ubsan_handle_pointer_overflow{{.*}} p++; } diff --git a/test/CodeGen/ubsan-volatile.c b/test/CodeGen/ubsan-volatile.c new file mode 100644 index 000000000000..ce54aada81fd --- /dev/null +++ b/test/CodeGen/ubsan-volatile.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsanitize=null,alignment,object-size,vptr -S -emit-llvm %s -o - | FileCheck %s + +// CHECK: @volatile_null_deref +void volatile_null_deref(volatile int *p) { + // CHECK-NOT: call{{.*}}ubsan + *p; +} diff --git a/test/CodeGenCXX/ms-thread_local.cpp b/test/CodeGenCXX/ms-thread_local.cpp index 5183ab5c32e1..dc7958d6eacf 100644 --- a/test/CodeGenCXX/ms-thread_local.cpp +++ b/test/CodeGenCXX/ms-thread_local.cpp @@ -27,7 +27,5 @@ A f() { return c; } -// CHECK: !llvm.module.flags = !{{{.*}}} -// CHECK: !{{[0-9]+}} = !{i32 6, !"Linker Options", ![[link_opts:[0-9]+]]} -// CHECK: ![[link_opts]] = !{![[dyn_tls_init:[0-9]+]]} +// CHECK: !llvm.linker.options = !{![[dyn_tls_init:[0-9]+]]} // CHECK: ![[dyn_tls_init]] = !{!"/include:___dyn_tls_init@12"} diff --git a/test/CodeGenCoroutines/coro-await.cpp b/test/CodeGenCoroutines/coro-await.cpp index 1e2deaa8f59a..fc6559f1e0ad 100644 --- a/test/CodeGenCoroutines/coro-await.cpp +++ b/test/CodeGenCoroutines/coro-await.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fcoroutines-ts -std=c++14 -emit-llvm %s -o - -disable-llvm-passes | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fcoroutines-ts -std=c++14 \ +// RUN: -emit-llvm %s -o - -disable-llvm-passes -Wno-coroutine -Wno-unused | FileCheck %s namespace std { namespace experimental { @@ -278,3 +279,50 @@ void AwaitLValue() { suspend_always lval; co_await lval; } + +struct RefTag { }; + +struct AwaitResumeReturnsLValue { + bool await_ready(); + void await_suspend(std::experimental::coroutine_handle<>); + RefTag& await_resume(); +}; + + +template<> +struct std::experimental::coroutine_traits<void,double> { + struct promise_type { + void get_return_object(); + init_susp initial_suspend(); + final_susp final_suspend(); + void return_void(); + AwaitResumeReturnsLValue yield_value(int); + }; +}; + +// Verifies that we don't crash when returning an lvalue from an await_resume() +// expression. +// CHECK-LABEL: define void @_Z18AwaitReturnsLValued(double) +void AwaitReturnsLValue(double) { + AwaitResumeReturnsLValue a; + // CHECK: %[[AVAR:.+]] = alloca %struct.AwaitResumeReturnsLValue, + // CHECK: %[[XVAR:.+]] = alloca %struct.RefTag*, + + // CHECK: %[[YVAR:.+]] = alloca %struct.RefTag*, + // CHECK-NEXT: %[[TMP1:.+]] = alloca %struct.AwaitResumeReturnsLValue, + + // CHECK: %[[ZVAR:.+]] = alloca %struct.RefTag*, + // CHECK-NEXT: %[[TMP2:.+]] = alloca %struct.AwaitResumeReturnsLValue, + + // CHECK: %[[RES1:.+]] = call dereferenceable({{.*}}) %struct.RefTag* @_ZN24AwaitResumeReturnsLValue12await_resumeEv(%struct.AwaitResumeReturnsLValue* %[[AVAR]]) + // CHECK-NEXT: store %struct.RefTag* %[[RES1]], %struct.RefTag** %[[XVAR]], + RefTag& x = co_await a; + + // CHECK: %[[RES2:.+]] = call dereferenceable({{.*}}) %struct.RefTag* @_ZN24AwaitResumeReturnsLValue12await_resumeEv(%struct.AwaitResumeReturnsLValue* %[[TMP1]]) + // CHECK-NEXT: store %struct.RefTag* %[[RES2]], %struct.RefTag** %[[YVAR]], + + RefTag& y = co_await AwaitResumeReturnsLValue{}; + // CHECK: %[[RES3:.+]] = call dereferenceable({{.*}}) %struct.RefTag* @_ZN24AwaitResumeReturnsLValue12await_resumeEv(%struct.AwaitResumeReturnsLValue* %[[TMP2]]) + // CHECK-NEXT: store %struct.RefTag* %[[RES3]], %struct.RefTag** %[[ZVAR]], + RefTag& z = co_yield 42; +} diff --git a/test/CodeGenObjC/availability-cf-link-guard.m b/test/CodeGenObjC/availability-cf-link-guard.m index 918d13ffd9f4..6bd426476bba 100644 --- a/test/CodeGenObjC/availability-cf-link-guard.m +++ b/test/CodeGenObjC/availability-cf-link-guard.m @@ -37,9 +37,8 @@ void use_at_available() { // CHECK_NO_GUARD-NOT: __clang_at_available_requires_core_foundation_framework // CHECK_NO_GUARD-NOT: CFBundleGetVersionNumber -// CHECK_LINK_OPT: !"Linker Options", ![[OPTS:[0-9]+]] -// CHECK_LINK_OPT: ![[OPTS]] = !{![[FRAMEWORK:[0-9]+]] +// CHECK_LINK_OPT: !llvm.linker.options = !{![[FRAMEWORK:[0-9]+]] // CHECK_LINK_OPT: ![[FRAMEWORK]] = !{!"-framework", !"CoreFoundation"} -// CHECK_NO_GUARD-NOT: "Linker Options" +// CHECK_NO_GUARD-NOT: !llvm.linker.options // CHECK_NO_GUARD-NOT: CoreFoundation diff --git a/test/Coverage/ast-printing.c b/test/Coverage/ast-printing.c index eb22f92e66d7..dfda6c676f6f 100644 --- a/test/Coverage/ast-printing.c +++ b/test/Coverage/ast-printing.c @@ -3,6 +3,7 @@ // RUN: %clang_cc1 -ast-print %t.1.c -o %t.2.c // RUN: diff %t.1.c %t.2.c // RUN: %clang_cc1 -ast-dump %s +// RUN: %clang_cc1 -ast-dump-all %s // RUN: %clang_cc1 -print-decl-contexts %s #include "c-language-features.inc" diff --git a/test/Coverage/ast-printing.cpp b/test/Coverage/ast-printing.cpp index e03c51735335..bcd78be7d05b 100644 --- a/test/Coverage/ast-printing.cpp +++ b/test/Coverage/ast-printing.cpp @@ -3,6 +3,7 @@ // RUN: %clang_cc1 -std=c++14 -ast-print %t.1.cpp -o %t.2.cpp // RUN: diff %t.1.cpp %t.2.cpp // RUN: %clang_cc1 -std=c++14 -ast-dump %s +// RUN: %clang_cc1 -std=c++14 -ast-dump-all %s // RUN: %clang_cc1 -std=c++14 -print-decl-contexts %s // RUN: %clang_cc1 -std=c++14 -fdump-record-layouts %s diff --git a/test/Driver/m_and_mm.c b/test/Driver/m_and_mm.c index 18cf7abfa629..6e40c82cb16c 100644 --- a/test/Driver/m_and_mm.c +++ b/test/Driver/m_and_mm.c @@ -1,3 +1,15 @@ // RUN: %clang -### \ // RUN: -M -MM %s 2> %t // RUN: not grep '"-sys-header-deps"' %t + +// RUN: %clang -M -MM %s 2> %t +// RUN: not grep "warning" %t + +// RUN: %clang -MMD -MD %s 2> %t || true +// RUN: grep "warning" %t + +#warning "This warning shouldn't show up with -M and -MM" +int main (void) +{ + return 0; +} diff --git a/test/Index/Core/index-source.cpp b/test/Index/Core/index-source.cpp index 8b049314ffbe..10f2d8f77747 100644 --- a/test/Index/Core/index-source.cpp +++ b/test/Index/Core/index-source.cpp @@ -1,4 +1,4 @@ -// RUN: c-index-test core -print-source-symbols -- %s -std=c++14 -target x86_64-apple-macosx10.7 | FileCheck %s +// RUN: c-index-test core -print-source-symbols -- %s -std=c++1z -target x86_64-apple-macosx10.7 | FileCheck %s // CHECK: [[@LINE+1]]:7 | class/C++ | Cls | [[Cls_USR:.*]] | <no-cgname> | Def | rel: 0 class Cls { public: @@ -433,3 +433,45 @@ template<typename T> T varDecl = T(); } // end namespace ensureDefaultTemplateParamsAreRecordedOnce + +struct StaticAssertRef { + static constexpr bool constVar = true; +}; + +static_assert(StaticAssertRef::constVar, "index static asserts"); +// CHECK: [[@LINE-1]]:32 | static-property/C++ | constVar | c:@S@StaticAssertRef@constVar | __ZN15StaticAssertRef8constVarE | Ref | rel: 0 +// CHECK: [[@LINE-2]]:15 | struct/C++ | StaticAssertRef | c:@S@StaticAssertRef | <no-cgname> | Ref | rel: 0 + +void staticAssertInFn() { + static_assert(StaticAssertRef::constVar, "index static asserts"); +// CHECK: [[@LINE-1]]:34 | static-property/C++ | constVar | c:@S@StaticAssertRef@constVar | __ZN15StaticAssertRef8constVarE | Ref,RelCont | rel: 1 +// CHECK-NEXT: RelCont | staticAssertInFn | c:@F@staticAssertInFn# +// CHECK: [[@LINE-3]]:17 | struct/C++ | StaticAssertRef | c:@S@StaticAssertRef | <no-cgname> | Ref,RelCont | rel: 1 +// CHECK-NEXT: RelCont | staticAssertInFn | c:@F@staticAssertInFn# +} + +namespace cpp17structuredBinding { + +struct Cpp17StructuredBinding { + int x, y; + + Cpp17StructuredBinding(int x, int y): x(x), y(y) { } +}; + +auto [structuredBinding1, structuredBinding2] = Cpp17StructuredBinding(Record::C, 0); +// CHECK: [[@LINE-1]]:7 | variable/C++ | structuredBinding1 | c:@N@cpp17structuredBinding@structuredBinding1 | <no-cgname> | Decl,RelChild | rel: 1 +// CHECK-NEXT: RelChild | cpp17structuredBinding | c:@N@cpp17structuredBinding +// CHECK: [[@LINE-3]]:27 | variable/C++ | structuredBinding2 | c:@N@cpp17structuredBinding@structuredBinding2 | <no-cgname> | Decl,RelChild | rel: 1 +// CHECK-NEXT: RelChild | cpp17structuredBinding | c:@N@cpp17structuredBinding + +void localStructuredBindingAndRef() { + int ref = structuredBinding1; +// CHECK: [[@LINE-1]]:13 | variable/C++ | structuredBinding1 | c:@N@cpp17structuredBinding@structuredBinding1 | <no-cgname> | Ref,Read,RelCont | rel: 1 +// CHECK-NEXT: RelCont | localStructuredBindingAndRef | c:@N@cpp17structuredBinding@F@localStructuredBindingAndRef# + auto [localBinding1, localBinding2] = Cpp17StructuredBinding(ref, structuredBinding2); +// CHECK: [[@LINE-1]]:69 | variable/C++ | structuredBinding2 | c:@N@cpp17structuredBinding@structuredBinding2 | <no-cgname> | Ref,Read,RelCont | rel: 1 +// CHECK-NEXT: RelCont | localStructuredBindingAndRef | c:@N@cpp17structuredBinding@F@localStructuredBindingAndRef# +// CHECK-NOT: localBinding +} + +} diff --git a/test/Index/availability.c b/test/Index/availability.c index b9d2c6f449c1..206b8a2a7105 100644 --- a/test/Index/availability.c +++ b/test/Index/availability.c @@ -8,13 +8,15 @@ enum { enum { old_enum_plat -} __attribute__((availability(macosx,introduced=10.4,deprecated=10.5,obsoleted=10.7) +} __attribute__((availability(macosx,introduced=10.4,deprecated=10.5,obsoleted=10.7))); -// RUN: c-index-test -test-load-source all %s > %t -// RUN: FileCheck -check-prefix=CHECK-1 %s < %t -// RUN: FileCheck -check-prefix=CHECK-2 %s < %t -// CHECK-1: (ios, introduced=3.2, deprecated=4.1) -// CHECK-2: (macos, introduced=10.4, deprecated=10.5, obsoleted=10.7) +void bar(void) __attribute__((availability(macosx,introduced=10.4))) __attribute__((availability(macosx,obsoleted=10.6))) __attribute__((availability(ios,introduced=3.2))) __attribute__((availability(macosx,deprecated=10.5,message="use foobar"))); -// CHECK-2: EnumConstantDecl=old_enum:6:3 (Definition) (deprecated) -// CHECK-2: EnumConstantDecl=old_enum_plat:10:3 {{.*}} (macos, introduced=10.4, deprecated=10.5, obsoleted=10.7) +void bar2(void) __attribute__((availability(macosx,introduced=10.4,deprecated=10.5,obsoleted=10.7))) __attribute__((availability(ios,introduced=3.2,deprecated=10.0))) __attribute__((availability(macosx,introduced=10.4,deprecated=10.5,obsoleted=10.7))) __attribute__((availability(ios,introduced=3.2,deprecated=10.0))); + +// RUN: c-index-test -test-load-source all %s | FileCheck %s +// CHECK: FunctionDecl=foo:3:6{{.*}}(ios, introduced=3.2, deprecated=4.1) (macos, introduced=10.4, deprecated=10.5, obsoleted=10.7) +// CHECK: EnumConstantDecl=old_enum:6:3 (Definition) (deprecated) +// CHECK: EnumConstantDecl=old_enum_plat:10:3 {{.*}} (macos, introduced=10.4, deprecated=10.5, obsoleted=10.7) +// CHECK: FunctionDecl=bar:13:6{{.*}}(ios, introduced=3.2) (macos, introduced=10.4, deprecated=10.5, obsoleted=10.6, message="use foobar") +// CHECK: FunctionDecl=bar2:15:6{{.*}}(ios, introduced=3.2, deprecated=10.0) (macos, introduced=10.4, deprecated=10.5, obsoleted=10.7) diff --git a/test/Misc/pr32207.c b/test/Misc/pr32207.c new file mode 100644 index 000000000000..f738e41684c6 --- /dev/null +++ b/test/Misc/pr32207.c @@ -0,0 +1,4 @@ +// test for r305179 +// RUN: %clang_cc1 -emit-llvm -O -mllvm -print-after-all %s -o %t 2>&1 | FileCheck %s +// CHECK: *** IR Dump After Function Integration/Inlining *** +void foo() {} diff --git a/test/Modules/autolink.m b/test/Modules/autolink.m index 28b9e40678f6..6aee0e11b120 100644 --- a/test/Modules/autolink.m +++ b/test/Modules/autolink.m @@ -36,9 +36,7 @@ int use_autolink_sub3() { // NOTE: "autolink_sub" is intentionally not linked. -// CHECK: !llvm.module.flags = !{{{.*}}} -// CHECK: !{{[0-9]+}} = !{i32 6, !"Linker Options", ![[AUTOLINK_OPTIONS:[0-9]+]]} -// CHECK: ![[AUTOLINK_OPTIONS]] = !{![[AUTOLINK_PCH:[0-9]+]], ![[AUTOLINK_FRAMEWORK:[0-9]+]], ![[AUTOLINK:[0-9]+]], ![[DEPENDSONMODULE:[0-9]+]], ![[MODULE:[0-9]+]], ![[NOUMBRELLA:[0-9]+]]} +// CHECK: !llvm.linker.options = !{![[AUTOLINK_PCH:[0-9]+]], ![[AUTOLINK_FRAMEWORK:[0-9]+]], ![[AUTOLINK:[0-9]+]], ![[DEPENDSONMODULE:[0-9]+]], ![[MODULE:[0-9]+]], ![[NOUMBRELLA:[0-9]+]]} // CHECK: ![[AUTOLINK_PCH]] = !{!"{{(\\01|-l|/DEFAULTLIB:)}}autolink_from_pch{{(\.lib)?}}"} // CHECK: ![[AUTOLINK_FRAMEWORK]] = !{!"-framework", !"autolink_framework"} // CHECK: ![[AUTOLINK]] = !{!"{{(\\01|-l|/DEFAULTLIB:)}}autolink{{(\.lib)?}}"} @@ -47,4 +45,4 @@ int use_autolink_sub3() { // CHECK: ![[NOUMBRELLA]] = !{!"-framework", !"NoUmbrella"} // CHECK-AUTOLINK-DISABLED: !llvm.module.flags -// CHECK-AUTOLINK-DISABLED-NOT: "Linker Options" +// CHECK-AUTOLINK-DISABLED-NOT: !llvm.linker.options diff --git a/test/Modules/autolinkTBD.m b/test/Modules/autolinkTBD.m index 6107952c3b9b..d6b9e997b2f8 100644 --- a/test/Modules/autolinkTBD.m +++ b/test/Modules/autolinkTBD.m @@ -8,10 +8,8 @@ int f() { return foo(); } -// CHECK: !llvm.module.flags = !{{{.*}}} -// CHECK: !{{[0-9]+}} = !{i32 6, !"Linker Options", ![[AUTOLINK_OPTIONS:[0-9]+]]} -// CHECK: ![[AUTOLINK_OPTIONS]] = !{![[AUTOLINK_FRAMEWORK:[0-9]+]]} +// CHECK: !llvm.linker.options = !{![[AUTOLINK_FRAMEWORK:[0-9]+]]} // CHECK: ![[AUTOLINK_FRAMEWORK]] = !{!"-framework", !"AutolinkTBD"} // CHECK-AUTOLINK-DISABLED: !llvm.module.flags -// CHECK-AUTOLINK-DISABLED-NOT: "Linker Options" +// CHECK-AUTOLINK-DISABLED-NOT: !llvm.linker.options diff --git a/test/Modules/module-impl-with-link.c b/test/Modules/module-impl-with-link.c index 3bd4c4abd92b..ffd388c56b90 100644 --- a/test/Modules/module-impl-with-link.c +++ b/test/Modules/module-impl-with-link.c @@ -1,7 +1,6 @@ // RUN: rm -rf %t // RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -fmodule-name=Clib %s -I %S/Inputs/module-impl-with-link -emit-llvm -o - | FileCheck %s #include "foo.h" -// CHECK: !{{[0-9]+}} = !{i32 6, !"Linker Options", ![[LINK_OPTIONS:[0-9]+]]} // Make sure we don't generate linker option for module Clib since this TU is // an implementation of Clib. -// CHECK: ![[LINK_OPTIONS]] = !{} +// CHECK: !llvm.linker.options = !{} diff --git a/test/Modules/odr_hash.cpp b/test/Modules/odr_hash.cpp index a6a0b74743aa..c94940c73eb6 100644 --- a/test/Modules/odr_hash.cpp +++ b/test/Modules/odr_hash.cpp @@ -486,7 +486,8 @@ struct S12 { }; #else S12 s12; -// TODO: This should produce an error. +// expected-error@second.h:* {{'Method::S12' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' with 1st parameter without a default argument}} +// expected-note@first.h:* {{but in 'FirstModule' found method 'A' with 1st parameter with a default argument}} #endif #if defined(FIRST) @@ -499,7 +500,8 @@ struct S13 { }; #else S13 s13; -// TODO: This should produce an error. +// expected-error@second.h:* {{'Method::S13' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' with 1st parameter with a default argument}} +// expected-note@first.h:* {{but in 'FirstModule' found method 'A' with 1st parameter with a different default argument}} #endif #if defined(FIRST) @@ -586,6 +588,57 @@ S3 s3; // expected-error@first.h:* {{'TypeDef::S3::a' from module 'FirstModule' is not present in definition of 'TypeDef::S3' in module 'SecondModule'}} // expected-note@second.h:* {{declaration of 'a' does not match}} #endif + +#if defined(FIRST) +struct S4 { + typedef int a; + typedef int b; +}; +#elif defined(SECOND) +struct S4 { + typedef int b; + typedef int a; +}; +#else +S4 s4; +// expected-error@second.h:* {{'TypeDef::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found typedef name 'b'}} +// expected-note@first.h:* {{but in 'FirstModule' found typedef name 'a'}} +#endif + +#if defined(FIRST) +struct S5 { + typedef int a; + typedef int b; + int x; +}; +#elif defined(SECOND) +struct S5 { + int x; + typedef int b; + typedef int a; +}; +#else +S5 s5; +// expected-error@second.h:* {{'TypeDef::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found field}} +// expected-note@first.h:* {{but in 'FirstModule' found typedef}} +#endif + +#if defined(FIRST) +typedef float F; +struct S6 { + typedef int a; + typedef F b; +}; +#elif defined(SECOND) +struct S6 { + typedef int a; + typedef float b; +}; +#else +S6 s6; +// expected-error@second.h:* {{'TypeDef::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found typedef 'b' with underlying type 'float'}} +// expected-note@first.h:* {{but in 'FirstModule' found typedef 'b' with different underlying type 'TypeDef::F' (aka 'float')}} +#endif } // namespace TypeDef namespace Using { @@ -632,6 +685,57 @@ S3 s3; // expected-error@first.h:* {{'Using::S3::a' from module 'FirstModule' is not present in definition of 'Using::S3' in module 'SecondModule'}} // expected-note@second.h:* {{declaration of 'a' does not match}} #endif + +#if defined(FIRST) +struct S4 { + using a = int; + using b = int; +}; +#elif defined(SECOND) +struct S4 { + using b = int; + using a = int; +}; +#else +S4 s4; +// expected-error@second.h:* {{'Using::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found type alias name 'b'}} +// expected-note@first.h:* {{but in 'FirstModule' found type alias name 'a'}} +#endif + +#if defined(FIRST) +struct S5 { + using a = int; + using b = int; + int x; +}; +#elif defined(SECOND) +struct S5 { + int x; + using b = int; + using a = int; +}; +#else +S5 s5; +// expected-error@second.h:* {{'Using::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found field}} +// expected-note@first.h:* {{but in 'FirstModule' found type alias}} +#endif + +#if defined(FIRST) +typedef float F; +struct S6 { + using a = int; + using b = F; +}; +#elif defined(SECOND) +struct S6 { + using a = int; + using b = float; +}; +#else +S6 s6; +// expected-error@second.h:* {{'Using::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found type alias 'b' with underlying type 'float'}} +// expected-note@first.h:* {{but in 'FirstModule' found type alias 'b' with different underlying type 'Using::F' (aka 'float')}} +#endif } // namespace Using namespace RecordType { @@ -900,6 +1004,289 @@ S2 s2; #endif } +namespace TemplateArgument { +#if defined(FIRST) +template <class> struct U1{}; +struct S1 { + U1<int> x; +}; +#elif defined(SECOND) +template <int> struct U1{}; +struct S1 { + U1<1> x; +}; +#else +S1 s1; +// expected-error@first.h:* {{'TemplateArgument::S1::x' from module 'FirstModule' is not present in definition of 'TemplateArgument::S1' in module 'SecondModule'}} +// expected-note@second.h:* {{declaration of 'x' does not match}} +#endif + +#if defined(FIRST) +template <int> struct U2{}; +struct S2 { + using T = U2<2>; +}; +#elif defined(SECOND) +template <int> struct U2{}; +struct S2 { + using T = U2<(2)>; +}; +#else +S2 s2; +// expected-error@second.h:* {{'TemplateArgument::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found type alias 'T' with underlying type 'U2<(2)>'}} +// expected-note@first.h:* {{but in 'FirstModule' found type alias 'T' with different underlying type 'U2<2>'}} +#endif + +#if defined(FIRST) +template <int> struct U3{}; +struct S3 { + using T = U3<2>; +}; +#elif defined(SECOND) +template <int> struct U3{}; +struct S3 { + using T = U3<1 + 1>; +}; +#else +S3 s3; +// expected-error@second.h:* {{'TemplateArgument::S3' has different definitions in different modules; first difference is definition in module 'SecondModule' found type alias 'T' with underlying type 'U3<1 + 1>'}} +// expected-note@first.h:* {{but in 'FirstModule' found type alias 'T' with different underlying type 'U3<2>'}} +#endif + +#if defined(FIRST) +template<class> struct T4a {}; +template <template <class> class T> struct U4 {}; +struct S4 { + U4<T4a> x; +}; +#elif defined(SECOND) +template<class> struct T4b {}; +template <template <class> class T> struct U4 {}; +struct S4 { + U4<T4b> x; +}; +#else +S4 s4; +// expected-error@first.h:* {{'TemplateArgument::S4::x' from module 'FirstModule' is not present in definition of 'TemplateArgument::S4' in module 'SecondModule'}} +// expected-note@second.h:* {{declaration of 'x' does not match}} +#endif +} + +namespace TemplateTypeParmType { +#if defined(FIRST) +template <class T1, class T2> +struct S1 { + T1 x; +}; +#elif defined(SECOND) +template <class T1, class T2> +struct S1 { + T2 x; +}; +#else +using TemplateTypeParmType::S1; +// expected-error@first.h:* {{'TemplateTypeParmType::S1::x' from module 'FirstModule' is not present in definition of 'S1<T1, T2>' in module 'SecondModule'}} +// expected-note@second.h:* {{declaration of 'x' does not match}} +#endif + +#if defined(FIRST) +template <int ...Ts> +struct U2 {}; +template <int T, int U> +class S2 { + typedef U2<U, T> type; + type x; +}; +#elif defined(SECOND) +template <int ...Ts> +struct U2 {}; +template <int T, int U> +class S2 { + typedef U2<T, U> type; + type x; +}; +#else +using TemplateTypeParmType::S2; +// expected-error@first.h:* {{'TemplateTypeParmType::S2::x' from module 'FirstModule' is not present in definition of 'S2<T, U>' in module 'SecondModule'}} +// expected-note@second.h:* {{declaration of 'x' does not match}} +// expected-error@first.h:* {{'TemplateTypeParmType::S2::type' from module 'FirstModule' is not present in definition of 'S2<T, U>' in module 'SecondModule'}} +// expected-note@second.h:* {{declaration of 'type' does not match}} +#endif +} + +namespace VarDecl { +#if defined(FIRST) +struct S1 { + static int x; + static int y; +}; +#elif defined(SECOND) +struct S1 { + static int y; + static int x; +}; +#else +S1 s1; +// expected-error@second.h:* {{'VarDecl::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found data member with name 'y'}} +// expected-note@first.h:* {{but in 'FirstModule' found data member with name 'x'}} +#endif + +#if defined(FIRST) +struct S2 { + static int x; +}; +#elif defined(SECOND) +using I = int; +struct S2 { + static I x; +}; +#else +S2 s2; +// expected-error@second.h:* {{'VarDecl::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found data member 'x' with type 'VarDecl::I' (aka 'int')}} +// expected-note@first.h:* {{but in 'FirstModule' found data member 'x' with different type 'int'}} +#endif + +#if defined(FIRST) +struct S3 { + static const int x = 1; +}; +#elif defined(SECOND) +struct S3 { + static const int x; +}; +#else +S3 s3; +// expected-error@second.h:* {{'VarDecl::S3' has different definitions in different modules; first difference is definition in module 'SecondModule' found data member 'x' with an initializer}} +// expected-note@first.h:* {{but in 'FirstModule' found data member 'x' without an initializer}} +#endif + +#if defined(FIRST) +struct S4 { + static const int x = 1; +}; +#elif defined(SECOND) +struct S4 { + static const int x = 2; +}; +#else +S4 s4; +// expected-error@second.h:* {{'VarDecl::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found data member 'x' with an initializer}} +// expected-note@first.h:* {{but in 'FirstModule' found data member 'x' with a different initializer}} +#endif + +#if defined(FIRST) +struct S5 { + static const int x = 1; +}; +#elif defined(SECOND) +struct S5 { + static constexpr int x = 1; +}; +#else +S5 s5; +// expected-error@second.h:* {{'VarDecl::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found data member 'x' is not constexpr}} +// expected-note@first.h:* {{but in 'FirstModule' found data member 'x' is constexpr}} +#endif + +#if defined(FIRST) +struct S6 { + static const int x = 1; +}; +#elif defined(SECOND) +struct S6 { + static const int y = 1; +}; +#else +S6 s6; +// expected-error@first.h:* {{'VarDecl::S6::x' from module 'FirstModule' is not present in definition of 'VarDecl::S6' in module 'SecondModule'}} +// expected-note@second.h:* {{definition has no member 'x'}} +#endif + +#if defined(FIRST) +struct S7 { + static const int x = 1; +}; +#elif defined(SECOND) +struct S7 { + static const unsigned x = 1; +}; +#else +S7 s7; +// expected-error@first.h:* {{'VarDecl::S7::x' from module 'FirstModule' is not present in definition of 'VarDecl::S7' in module 'SecondModule'}} +// expected-note@second.h:* {{declaration of 'x' does not match}} +#endif + +#if defined(FIRST) +struct S8 { +public: + static const int x = 1; +}; +#elif defined(SECOND) +struct S8 { + static const int x = 1; +public: +}; +#else +S8 s8; +// expected-error@second.h:* {{'VarDecl::S8' has different definitions in different modules; first difference is definition in module 'SecondModule' found data member}} +// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}} +#endif + +#if defined(FIRST) +struct S9 { + static const int x = 1; +}; +#elif defined(SECOND) +struct S9 { + static int x; +}; +#else +S9 s9; +// expected-error@first.h:* {{'VarDecl::S9::x' from module 'FirstModule' is not present in definition of 'VarDecl::S9' in module 'SecondModule'}} +// expected-note@second.h:* {{declaration of 'x' does not match}} +#endif + +#if defined(FIRST) +template <typename T> +struct S { + struct R { + void foo(T x = 0) {} + }; +}; +#elif defined(SECOND) +template <typename T> +struct S { + struct R { + void foo(T x = 1) {} + }; +}; +#else +void run() { + S<int>::R().foo(); +} +// expected-error@second.h:* {{'VarDecl::S::R' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'foo' with 1st parameter with a default argument}} +// expected-note@first.h:* {{but in 'FirstModule' found method 'foo' with 1st parameter with a different default argument}} +#endif + +#if defined(FIRST) +template <typename alpha> struct Bravo { + void charlie(bool delta = false) {} +}; +typedef Bravo<char> echo; +echo foxtrot; +#elif defined(SECOND) +template <typename alpha> struct Bravo { + void charlie(bool delta = (false)) {} +}; +typedef Bravo<char> echo; +echo foxtrot; +#else +Bravo<char> golf; +// expected-error@second.h:* {{'VarDecl::Bravo' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'charlie' with 1st parameter with a default argument}} +// expected-note@first.h:* {{but in 'FirstModule' found method 'charlie' with 1st parameter with a different default argument}} +#endif +} + // Interesting cases that should not cause errors. struct S should not error // while struct T should error at the access specifier mismatch at the end. namespace AllDecls { diff --git a/test/Sema/integer-overflow.c b/test/Sema/integer-overflow.c index c2b6ba209b71..62ee33e3d181 100644 --- a/test/Sema/integer-overflow.c +++ b/test/Sema/integer-overflow.c @@ -151,14 +151,6 @@ uint64_t check_integer_overflows(int i) { uint64_t *b; uint64_t b2 = b[4608 * 1024 * 1024] + 1; -// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} - f0(4608 * 1024 * 1024); - f0(4608ul * 1024 * 1024); -// expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}} - f1(4608 * 1024 * 1024, 4608 * 1024 * 1024); -// expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}} - f2(4608 * 1024 * 1024, 4608 * 1024 * 1024); - // expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}} int j1 = i ? (4608 * 1024 * 1024) : (4608 * 1024 * 1024); diff --git a/test/Sema/xray-log-args-class.cpp b/test/Sema/xray-log-args-class.cpp new file mode 100644 index 000000000000..10da93f614fe --- /dev/null +++ b/test/Sema/xray-log-args-class.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 %s -verify -fsyntax-only -std=c++11 -x c++ + +class Class { + [[clang::xray_always_instrument, clang::xray_log_args(1)]] void Method(); + [[clang::xray_log_args(-1)]] void Invalid(); // expected-error {{'xray_log_args' attribute parameter 1 is out of bounds}} + [[clang::xray_log_args("invalid")]] void InvalidStringArg(); // expected-error {{'xray_log_args'}} +}; diff --git a/test/SemaCXX/co_await-range-for.cpp b/test/SemaCXX/co_await-range-for.cpp new file mode 100644 index 000000000000..4d999ea7db5e --- /dev/null +++ b/test/SemaCXX/co_await-range-for.cpp @@ -0,0 +1,165 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++14 -fcoroutines-ts \ +// RUN: -fsyntax-only -Wignored-qualifiers -Wno-error=return-type -verify \ +// RUN: -fblocks +#include "Inputs/std-coroutine.h" + +using namespace std::experimental; + + +template <class Begin> +struct Awaiter { + bool await_ready(); + void await_suspend(coroutine_handle<>); + Begin await_resume(); +}; + +template <class Iter> struct BeginTag { BeginTag() = delete; }; +template <class Iter> struct IncTag { IncTag() = delete; }; + +template <class Iter, bool Delete = false> +struct CoawaitTag { CoawaitTag() = delete; }; + +template <class T> +struct Iter { + using value_type = T; + using reference = T &; + using pointer = T *; + + IncTag<Iter> operator++(); + reference operator*(); + pointer operator->(); +}; +template <class T> bool operator==(Iter<T>, Iter<T>); +template <class T> bool operator!=(Iter<T>, Iter<T>); + +template <class T> +struct Range { + BeginTag<Iter<T>> begin(); + Iter<T> end(); +}; + +struct MyForLoopArrayAwaiter { + struct promise_type { + MyForLoopArrayAwaiter get_return_object() { return {}; } + void return_void(); + void unhandled_exception(); + suspend_never initial_suspend(); + suspend_never final_suspend(); + template <class T> + Awaiter<T *> await_transform(T *) = delete; // expected-note {{explicitly deleted}} + }; +}; +MyForLoopArrayAwaiter g() { + int arr[10] = {0}; + for co_await(auto i : arr) {} + // expected-error@-1 {{call to deleted member function 'await_transform'}} + // expected-note@-2 {{'await_transform' implicitly required by 'co_await' here}} +} + +struct ForLoopAwaiterBadBeginTransform { + struct promise_type { + ForLoopAwaiterBadBeginTransform get_return_object(); + void return_void(); + void unhandled_exception(); + suspend_never initial_suspend(); + suspend_never final_suspend(); + + template <class T> + Awaiter<T> await_transform(BeginTag<T>) = delete; // expected-note 1+ {{explicitly deleted}} + + template <class T> + CoawaitTag<T> await_transform(IncTag<T>); // expected-note 1+ {{candidate}} + }; +}; +ForLoopAwaiterBadBeginTransform bad_begin() { + Range<int> R; + for co_await(auto i : R) {} + // expected-error@-1 {{call to deleted member function 'await_transform'}} + // expected-note@-2 {{'await_transform' implicitly required by 'co_await' here}} +} +template <class Dummy> +ForLoopAwaiterBadBeginTransform bad_begin_template(Dummy) { + Range<Dummy> R; + for co_await(auto i : R) {} + // expected-error@-1 {{call to deleted member function 'await_transform'}} + // expected-note@-2 {{'await_transform' implicitly required by 'co_await' here}} +} +template ForLoopAwaiterBadBeginTransform bad_begin_template(int); // expected-note {{requested here}} + +template <class Iter> +Awaiter<Iter> operator co_await(CoawaitTag<Iter, true>) = delete; +// expected-note@-1 1+ {{explicitly deleted}} + +struct ForLoopAwaiterBadIncTransform { + struct promise_type { + ForLoopAwaiterBadIncTransform get_return_object(); + void return_void(); + void unhandled_exception(); + suspend_never initial_suspend(); + suspend_never final_suspend(); + + template <class T> + Awaiter<T> await_transform(BeginTag<T> e); + + template <class T> + CoawaitTag<T, true> await_transform(IncTag<T>); + }; +}; +ForLoopAwaiterBadIncTransform bad_inc_transform() { + Range<float> R; + for co_await(auto i : R) {} + // expected-error@-1 {{overload resolution selected deleted operator 'co_await'}} + // expected-note@-2 {{in implicit call to 'operator++' for iterator of type 'Range<float>'}} +} + +template <class Dummy> +ForLoopAwaiterBadIncTransform bad_inc_transform_template(Dummy) { + Range<Dummy> R; + for co_await(auto i : R) {} + // expected-error@-1 {{overload resolution selected deleted operator 'co_await'}} + // expected-note@-2 {{in implicit call to 'operator++' for iterator of type 'Range<long>'}} +} +template ForLoopAwaiterBadIncTransform bad_inc_transform_template(long); // expected-note {{requested here}} + +// Ensure we mark and check the function as a coroutine even if it's +// never instantiated. +template <class T> +constexpr void never_instant(T) { + static_assert(sizeof(T) != sizeof(T), "function should not be instantiated"); + for co_await(auto i : foo(T{})) {} + // expected-error@-1 {{'co_await' cannot be used in a constexpr function}} +} + +namespace NS { +struct ForLoopAwaiterCoawaitLookup { + struct promise_type { + ForLoopAwaiterCoawaitLookup get_return_object(); + void return_void(); + void unhandled_exception(); + suspend_never initial_suspend(); + suspend_never final_suspend(); + template <class T> + CoawaitTag<T, false> await_transform(BeginTag<T> e); + template <class T> + Awaiter<T> await_transform(IncTag<T>); + }; +}; +} // namespace NS +using NS::ForLoopAwaiterCoawaitLookup; + +template <class T> +ForLoopAwaiterCoawaitLookup test_coawait_lookup(T) { + Range<T> R; + for co_await(auto i : R) {} + // expected-error@-1 {{no member named 'await_ready' in 'CoawaitTag<Iter<int>, false>'}} +} +template ForLoopAwaiterCoawaitLookup test_coawait_lookup(int); // expected-note {{requested here}} + +// FIXME: This test should fail as well since the newly declared operator co_await +// should not be found by lookup. +namespace NS2 { +template <class Iter> +Awaiter<Iter> operator co_await(CoawaitTag<Iter, false>); +} +using NS2::operator co_await; +template ForLoopAwaiterCoawaitLookup test_coawait_lookup(long); diff --git a/test/SemaCXX/cxx1z-decomposition.cpp b/test/SemaCXX/cxx1z-decomposition.cpp index d457ace5d844..7a4221784ad3 100644 --- a/test/SemaCXX/cxx1z-decomposition.cpp +++ b/test/SemaCXX/cxx1z-decomposition.cpp @@ -70,4 +70,10 @@ int error_recovery() { return foobar_; // expected-error {{undeclared identifier 'foobar_'}} } +// PR32172 +template <class T> void dependent_foreach(T t) { + for (auto [a,b,c] : t) + a,b,c; +} + // FIXME: by-value array copies diff --git a/test/SemaCXX/nested-name-spec.cpp b/test/SemaCXX/nested-name-spec.cpp index 6ae45ff63332..725ac64cedb7 100644 --- a/test/SemaCXX/nested-name-spec.cpp +++ b/test/SemaCXX/nested-name-spec.cpp @@ -169,6 +169,13 @@ void N::f() { } // okay struct Y; // expected-note{{forward declaration of 'Y'}} Y::foo y; // expected-error{{incomplete type 'Y' named in nested name specifier}} +namespace PR25156 { +struct Y; // expected-note{{forward declaration of 'PR25156::Y'}} +void foo() { + Y::~Y(); // expected-error{{incomplete type 'PR25156::Y' named in nested name specifier}} +} +} + X::X() : a(5) { } // expected-error{{use of undeclared identifier 'X'}} struct foo_S { diff --git a/test/SemaCXX/warn-unused-lambda-capture.cpp b/test/SemaCXX/warn-unused-lambda-capture.cpp index 48f8bfea7e9a..6ad8e26604a4 100644 --- a/test/SemaCXX/warn-unused-lambda-capture.cpp +++ b/test/SemaCXX/warn-unused-lambda-capture.cpp @@ -142,11 +142,14 @@ void test_templated() { auto implicit_by_reference = [&] { i++; }; auto explicit_by_value_used = [i] { return i + 1; }; + auto explicit_by_value_used_generic = [i](auto c) { return i + 1; }; auto explicit_by_value_used_void = [i] { (void)i; }; + auto explicit_by_value_unused = [i] {}; // expected-warning{{lambda capture 'i' is not used}} auto explicit_by_value_unused_sizeof = [i] { return sizeof(i); }; // expected-warning{{lambda capture 'i' is not required to be captured for this use}} auto explicit_by_value_unused_decltype = [i] { decltype(i) j = 0; }; // expected-warning{{lambda capture 'i' is not used}} auto explicit_by_value_unused_const = [k] { return k + 1; }; // expected-warning{{lambda capture 'k' is not required to be captured for this use}} + auto explicit_by_value_unused_const_generic = [k](auto c) { return k + 1; }; // expected-warning{{lambda capture 'k' is not required to be captured for this use}} auto explicit_by_reference_used = [&i] { i++; }; auto explicit_by_reference_unused = [&i] {}; // expected-warning{{lambda capture 'i' is not used}} @@ -161,6 +164,8 @@ void test_templated() { auto explicit_initialized_value_trivial_init = [j = Trivial()]{}; // expected-warning{{lambda capture 'j' is not used}} auto explicit_initialized_value_non_trivial_init = [j = Trivial(42)]{}; auto explicit_initialized_value_with_side_effect = [j = side_effect()]{}; + auto explicit_initialized_value_generic_used = [i = 1](auto c) mutable { i++; }; + auto explicit_initialized_value_generic_unused = [i = 1](auto c) mutable {}; // expected-warning{{lambda capture 'i' is not used}} auto nested = [&i] { auto explicit_by_value_used = [i] { return i + 1; }; |
