diff options
Diffstat (limited to 'clang/test')
-rw-r--r-- | clang/test/AST/ByteCode/cxx11.cpp | 13 | ||||
-rw-r--r-- | clang/test/Analysis/store-to-immutable-basic.c | 121 | ||||
-rw-r--r-- | clang/test/Analysis/store-to-immutable-basic.cpp | 72 | ||||
-rw-r--r-- | clang/test/Analysis/store-to-immutable-lambda-init.cpp | 13 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/debug-info-class.cpp | 46 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/mangle-concept.cpp | 3 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/vtable-debug-info-inheritance-simple.cpp | 11 | ||||
-rw-r--r-- | clang/test/CodeGenOpenCL/preserve_vec3.cl | 22 | ||||
-rw-r--r-- | clang/test/Frontend/dump-minimization-hints-cpp20-modules.cpp | 117 | ||||
-rw-r--r-- | clang/test/Modules/ExtDebugInfo.cpp | 15 | ||||
-rw-r--r-- | clang/test/Parser/cxx-template-template-recovery.cpp | 12 | ||||
-rw-r--r-- | clang/test/Parser/cxx2a-concept-declaration.cpp | 5 | ||||
-rw-r--r-- | clang/test/Parser/cxx2c-template-template-param.cpp | 79 | ||||
-rw-r--r-- | clang/test/Sema/riscv-interrupt-attr-rnmi.c | 28 | ||||
-rw-r--r-- | clang/test/SemaCXX/cxx2c-template-template-param.cpp | 352 |
15 files changed, 861 insertions, 48 deletions
diff --git a/clang/test/AST/ByteCode/cxx11.cpp b/clang/test/AST/ByteCode/cxx11.cpp index 378702f..8a125a4 100644 --- a/clang/test/AST/ByteCode/cxx11.cpp +++ b/clang/test/AST/ByteCode/cxx11.cpp @@ -289,3 +289,16 @@ namespace OverlappingStrings { } + +namespace NonConstLocal { + int a() { + const int t=t; // both-note {{declared here}} + + switch(1) { + case t:; // both-note {{initializer of 't' is not a constant expression}} \ + // both-error {{case value is not a constant expression}} + } + } +} + + diff --git a/clang/test/Analysis/store-to-immutable-basic.c b/clang/test/Analysis/store-to-immutable-basic.c new file mode 100644 index 0000000..f7d8878 --- /dev/null +++ b/clang/test/Analysis/store-to-immutable-basic.c @@ -0,0 +1,121 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.core.StoreToImmutable -verify %s + +// Test basic functionality of StoreToImmutable checker for the C programming language. + +const int tentative_global_const; // expected-note {{Memory region is declared as immutable here}} + +void test_direct_write_to_tentative_const_global() { + *(int*)&tentative_global_const = 100; // expected-warning {{Trying to write to immutable memory in global read-only storage}} +} + +const int global_const = 42; // expected-note {{Memory region is declared as immutable here}} + +void test_direct_write_to_const_global() { + // This should trigger a warning about writing to immutable memory + *(int*)&global_const = 100; // expected-warning {{Trying to write to immutable memory in global read-only storage}} +} + +void test_write_through_const_pointer() { + const int local_const = 10; // expected-note {{Memory region is declared as immutable here}} + int *ptr = (int*)&local_const; + *ptr = 20; // expected-warning {{Trying to write to immutable memory}} +} + +void test_write_to_const_array() { + const int arr[5] = {1, 2, 3, 4, 5}; // expected-note {{Enclosing memory region is declared as immutable here}} + int *ptr = (int*)arr; + ptr[0] = 10; // expected-warning {{Trying to write to immutable memory}} +} + +struct TestStruct { + const int x; // expected-note 2 {{Memory region is declared as immutable here}} + int y; +}; + +void test_write_to_const_struct_member() { + struct TestStruct s = {1, 2}; + int *ptr = (int*)&s.x; + *ptr = 10; // expected-warning {{Trying to write to immutable memory}} +} + +const int global_array[3] = {1, 2, 3}; // expected-note {{Enclosing memory region is declared as immutable here}} + +void test_write_to_const_global_array() { + int *ptr = (int*)global_array; + ptr[0] = 10; // expected-warning {{Trying to write to immutable memory in global read-only storage}} +} + +const struct TestStruct global_struct = {1, 2}; + +void test_write_to_const_global_struct() { + int *ptr = (int*)&global_struct.x; + *ptr = 10; // expected-warning {{Trying to write to immutable memory in global read-only storage}} +} + + +void test_write_to_const_param(const int param) { // expected-note {{Memory region is declared as immutable here}} + *(int*)¶m = 100; // expected-warning {{Trying to write to immutable memory}} +} + +void test_write_to_const_ptr_param(const int *param) { + *(int*)param = 100; // expected-warning {{Trying to write to immutable memory}} +} + +void test_write_to_const_array_param(const int arr[5]) { + *(int*)arr = 100; // expected-warning {{Trying to write to immutable memory}} +} + +struct ParamStruct { + const int z; // expected-note 2 {{Memory region is declared as immutable here}} + int w; +}; + +void test_write_to_const_struct_param(const struct ParamStruct s) { + *(int*)&s.z = 100; // expected-warning {{Trying to write to immutable memory}} +} + +void test_write_to_const_struct_ptr_param(const struct ParamStruct *s) { + *(int*)&s->z = 100; // expected-warning {{Trying to write to immutable memory}} +} + +void test_write_to_nonconst() { + int non_const = 42; + *(int*)&non_const = 100; // No warning expected +} + +int global_non_const = 42; + +void test_write_to_nonconst_global() { + *(int*)&global_non_const = 100; // No warning expected +} + +struct NonConstStruct { + int x; + int y; +}; + +void test_write_to_nonconst_struct_member() { + struct NonConstStruct s = {1, 2}; + *(int*)&s.x = 100; // No warning expected +} + +void test_write_to_nonconst_param(int param) { + *(int*)¶m = 100; // No warning expected +} + +void test_normal_assignment() { + int x = 42; + x = 100; // No warning expected +} + +void test_const_ptr_to_nonconst_data() { + int data = 42; + const int *ptr = &data; + *(int*)ptr = 100; // No warning expected +} + +void test_const_ptr_to_const_data() { + const int data = 42; // expected-note {{Memory region is declared as immutable here}} + const int *ptr = &data; + *(int*)ptr = 100; // expected-warning {{Trying to write to immutable memory}} +} diff --git a/clang/test/Analysis/store-to-immutable-basic.cpp b/clang/test/Analysis/store-to-immutable-basic.cpp new file mode 100644 index 0000000..63319d9 --- /dev/null +++ b/clang/test/Analysis/store-to-immutable-basic.cpp @@ -0,0 +1,72 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.core.StoreToImmutable -std=c++17 -verify %s + +void test_write_to_const_ref_param(const int ¶m) { + *(int*)¶m = 100; // expected-warning {{Trying to write to immutable memory}} +} + +// FIXME: This should warn in C mode too. +void test_write_to_string_literal() { + char *str = (char*)"hello"; + str[0] = 'H'; // expected-warning {{Trying to write to immutable memory}} +} + +struct ParamStruct { + const int z; // expected-note {{Memory region is declared as immutable here}} + int w; +}; + +void test_write_to_const_struct_ref_param(const ParamStruct &s) { + *(int*)&s.z = 100; // expected-warning {{Trying to write to immutable memory}} +} + +void test_const_ref_to_nonconst_data() { + int data = 42; + const int &ref = data; + *(int*)&ref = 100; // No warning expected +} + +void test_const_ref_to_const_data() { + const int data = 42; // expected-note {{Memory region is declared as immutable here}} + const int &ref = data; + *(int*)&ref = 100; // expected-warning {{Trying to write to immutable memory}} +} + +void test_ref_to_nonconst_data() { + int data = 42; + int &ref = data; + ref = 100; // No warning expected +} + +void test_ref_to_const_data() { + const int data = 42; // expected-note {{Memory region is declared as immutable here}} + int &ref = *(int*)&data; + ref = 100; // expected-warning {{Trying to write to immutable memory}} +} + +struct MultipleLayerStruct { + MultipleLayerStruct(); + const int data; // expected-note {{Memory region is declared as immutable here}} + const int buf[10]; // expected-note {{Enclosing memory region is declared as immutable here}} +}; + +MultipleLayerStruct MLS[10]; + +void test_multiple_layer_struct_array_member() { + int *p = (int*)&MLS[2].data; + *p = 4; // expected-warning {{Trying to write to immutable memory}} +} + +void test_multiple_layer_struct_array_array_member() { + int *p = (int*)&MLS[2].buf[3]; + *p = 4; // expected-warning {{Trying to write to immutable memory}} +} + +struct StructWithNonConstMember { + int x; +}; + +const StructWithNonConstMember SWNCM{0}; // expected-note {{Enclosing memory region is declared as immutable here}} + +void test_write_to_non_const_member_of_const_struct() { + *(int*)&SWNCM.x = 100; // expected-warning {{Trying to write to immutable memory in global read-only storage}} +} diff --git a/clang/test/Analysis/store-to-immutable-lambda-init.cpp b/clang/test/Analysis/store-to-immutable-lambda-init.cpp new file mode 100644 index 0000000..764ce3f --- /dev/null +++ b/clang/test/Analysis/store-to-immutable-lambda-init.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.core.StoreToImmutable -std=c++11 -verify %s +// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.core.StoreToImmutable -std=c++14 -verify %s +// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.core.StoreToImmutable -std=c++17 -verify %s +// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.core.StoreToImmutable -std=c++20 -verify %s + +// expected-no-diagnostics + +// In C++14 and before, when initializing a lambda, the statement given in the checkBind callback is not the whole DeclExpr, but the CXXConstructExpr of the lambda object. +// FIXME: Once the API of checkBind provides more information about the statement, the checker should be simplified, and this test case will no longer be a cornercase in the checker. + +void test_const_lambda_initialization_pre_cpp17() { + const auto lambda = [](){}; // No warning expected +} diff --git a/clang/test/CodeGenCXX/debug-info-class.cpp b/clang/test/CodeGenCXX/debug-info-class.cpp index 0bc4fdaa..aa24a63 100644 --- a/clang/test/CodeGenCXX/debug-info-class.cpp +++ b/clang/test/CodeGenCXX/debug-info-class.cpp @@ -99,12 +99,12 @@ int main(int argc, char **argv) { return 0; } -// RUN: %clang_cc1 -triple x86_64-unknown_unknown -emit-llvm -debug-info-kind=limited -fexceptions -std=c++98 %s -o - | FileCheck -check-prefix=CHECK98 -check-prefix=CHECK %s -// RUN: %clang_cc1 -triple i686-cygwin -emit-llvm -debug-info-kind=limited -fexceptions -std=c++98 %s -o - | FileCheck -check-prefix=CHECK98 -check-prefix=CHECK %s -// RUN: %clang_cc1 -triple armv7l-unknown-linux-gnueabihf -emit-llvm -debug-info-kind=limited -fexceptions -std=c++98 %s -o - | FileCheck -check-prefix=CHECK98 -check-prefix=CHECK %s -// RUN: %clang_cc1 -triple x86_64-unknown_unknown -emit-llvm -debug-info-kind=limited -fexceptions -std=c++11 %s -o - | FileCheck -check-prefix=CHECK11 -check-prefix=CHECK %s -// RUN: %clang_cc1 -triple i686-cygwin -emit-llvm -debug-info-kind=limited -fexceptions -std=c++11 %s -o - | FileCheck -check-prefix=CHECK11 -check-prefix=CHECK %s -// RUN: %clang_cc1 -triple armv7l-unknown-linux-gnueabihf -emit-llvm -debug-info-kind=limited -fexceptions -std=c++11 %s -o - | FileCheck -check-prefix=CHECK11 -check-prefix=CHECK %s +// RUN: %clang_cc1 -triple x86_64-unknown_unknown -emit-llvm -debug-info-kind=limited -fexceptions -std=c++98 %s -o - | FileCheck -check-prefix=CHECK98 -check-prefix=CHECK -check-prefix=CHECKELF %s +// RUN: %clang_cc1 -triple i686-cygwin -emit-llvm -debug-info-kind=limited -fexceptions -std=c++98 %s -o - | FileCheck -check-prefix=CHECK98 -check-prefix=CHECK -check-prefix=CHECKCOFF %s +// RUN: %clang_cc1 -triple armv7l-unknown-linux-gnueabihf -emit-llvm -debug-info-kind=limited -fexceptions -std=c++98 %s -o - | FileCheck -check-prefix=CHECK98 -check-prefix=CHECK -check-prefix=CHECKELF %s +// RUN: %clang_cc1 -triple x86_64-unknown_unknown -emit-llvm -debug-info-kind=limited -fexceptions -std=c++11 %s -o - | FileCheck -check-prefix=CHECK11 -check-prefix=CHECK -check-prefix=CHECKELF %s +// RUN: %clang_cc1 -triple i686-cygwin -emit-llvm -debug-info-kind=limited -fexceptions -std=c++11 %s -o - | FileCheck -check-prefix=CHECK11 -check-prefix=CHECK -check-prefix=CHECKCOFF %s +// RUN: %clang_cc1 -triple armv7l-unknown-linux-gnueabihf -emit-llvm -debug-info-kind=limited -fexceptions -std=c++11 %s -o - | FileCheck -check-prefix=CHECK11 -check-prefix=CHECK -check-prefix=CHECKELF %s // CHECK98: invoke {{.+}} @_ZN1BD1Ev(ptr {{[^,]*}} %b) // CHECK98-NEXT: unwind label %{{.+}}, !dbg ![[EXCEPTLOC:.*]] @@ -122,6 +122,14 @@ int main(int argc, char **argv) { // CHECK-SAME: ){{$}} // CHECK: ![[INT:[0-9]+]] = !DIBasicType(name: "int" +// CHECKCOFF: !DICompositeType(tag: DW_TAG_structure_type, name: "foo" +// CHECKCOFF: !DICompositeType(tag: DW_TAG_class_type, name: "bar" +// CHECKCOFF: !DICompositeType(tag: DW_TAG_union_type, name: "baz" +// CHECKCOFF: !DICompositeType(tag: DW_TAG_class_type, name: "B" +// CHECKCOFF-NOT: DIFlagFwdDecl +// CHECKCOFF-SAME: ){{$}} +// CHECKCOFF: !DIDerivedType(tag: DW_TAG_member, name: "_vptr$B", +// CHECKCOFF-SAME: DIFlagArtificial // CHECK: [[C:![0-9]*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "C", // CHECK-NOT: DIFlagFwdDecl @@ -137,19 +145,19 @@ int main(int argc, char **argv) { // CHECK-SAME: DIFlagStaticMember // CHECK: [[C_DTOR]] = !DISubprogram(name: "~C" -// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "K" -// CHECK-SAME: identifier: "_ZTS1K" -// CHECK-SAME: ){{$}} +// CHECKELF: !DICompositeType(tag: DW_TAG_structure_type, name: "K" +// CHECKELF-SAME: identifier: "_ZTS1K" +// CHECKELF-SAME: ){{$}} -// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "B" -// CHECK-NOT: DIFlagFwdDecl -// CHECK-SAME: ){{$}} -// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "_vptr$B", -// CHECK-SAME: DIFlagArtificial +// CHECKELF: !DICompositeType(tag: DW_TAG_class_type, name: "B" +// CHECKELF-NOT: DIFlagFwdDecl +// CHECKELF-SAME: ){{$}} +// CHECKELF: !DIDerivedType(tag: DW_TAG_member, name: "_vptr$B", +// CHECKELF-SAME: DIFlagArtificial -// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "foo" -// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "bar" -// CHECK: !DICompositeType(tag: DW_TAG_union_type, name: "baz" +// CHECKELF: !DICompositeType(tag: DW_TAG_structure_type, name: "foo" +// CHECKELF: !DICompositeType(tag: DW_TAG_class_type, name: "bar" +// CHECKELF: !DICompositeType(tag: DW_TAG_union_type, name: "baz" // CHECK: [[D:![0-9]+]] = !DICompositeType(tag: DW_TAG_structure_type, name: "D" // CHECK-SAME: size: @@ -162,6 +170,10 @@ int main(int argc, char **argv) { // CHECK-NOT: identifier: // CHECK-SAME: ){{$}} +// CHECKCOFF: !DICompositeType(tag: DW_TAG_structure_type, name: "K" +// CHECKCOFF-SAME: identifier: "_ZTS1K" +// CHECKCOFF-SAME: ){{$}} + // CHECK: [[L:![0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "L" // CHECK-SAME: ){{$}} // CHECK: [[L_FUNC_DECL:![0-9]*]] = !DISubprogram(name: "func",{{.*}} scope: [[L]] diff --git a/clang/test/CodeGenCXX/mangle-concept.cpp b/clang/test/CodeGenCXX/mangle-concept.cpp index aa0940c..63e819b 100644 --- a/clang/test/CodeGenCXX/mangle-concept.cpp +++ b/clang/test/CodeGenCXX/mangle-concept.cpp @@ -6,7 +6,8 @@ namespace test1 { template <bool> struct S {}; template <typename> concept C = true; -template <typename T = int> S<C<T>> f0() { return S<C<T>>{}; } +template <typename T = int> +S<C<T>> f0() { return S<C<T>>{}; } template S<C<int>> f0<>(); // CHECK: @_ZN5test12f0IiEENS_1SIX1CIT_EEEEv( // CLANG17: @_ZN5test12f0IiEENS_1SIL_ZNS_1CIT_EEEEEv( diff --git a/clang/test/CodeGenCXX/vtable-debug-info-inheritance-simple.cpp b/clang/test/CodeGenCXX/vtable-debug-info-inheritance-simple.cpp index 249586f..b24ece1 100644 --- a/clang/test/CodeGenCXX/vtable-debug-info-inheritance-simple.cpp +++ b/clang/test/CodeGenCXX/vtable-debug-info-inheritance-simple.cpp @@ -1,5 +1,3 @@ -// REQUIRES: target={{x86_64.*-linux.*}} - // Simple inheritance case: // For CBase and CDerived we check: // - Generation of their vtables (including attributes). @@ -30,13 +28,20 @@ int main() { return 0; } -// RUN: %clang --target=x86_64-linux -Xclang -disable-O0-optnone -Xclang -disable-llvm-passes -emit-llvm -S -g %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-linux -emit-llvm -mrelocation-model pic -pic-is-pie -debug-info-kind=limited -dwarf-version=5 -disable-O0-optnone -disable-llvm-passes %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-windows-gnu -emit-llvm -mrelocation-model pic -pic-is-pie -debug-info-kind=limited -dwarf-version=5 -disable-O0-optnone -disable-llvm-passes %s -o - | FileCheck %s --check-prefix=COFF // CHECK: $_ZTVN3NSP5CBaseE = comdat any // CHECK: $_ZTV8CDerived = comdat any // CHECK: @_ZTVN3NSP5CBaseE = linkonce_odr {{dso_local|hidden}} unnamed_addr constant {{.*}}, comdat, align 8, !dbg [[BASE_VTABLE_VAR:![0-9]*]] // CHECK: @_ZTV8CDerived = linkonce_odr {{dso_local|hidden}} unnamed_addr constant {{.*}}, comdat, align 8, !dbg [[DERIVED_VTABLE_VAR:![0-9]*]] +// COFF: @_ZTVN3NSP5CBaseE = linkonce_odr {{dso_local|hidden}} unnamed_addr constant {{.*}}, comdat, align 8 +// COFF-NOT: !dbg +// COFF-SAME: {{$}} +// COFF: @_ZTV8CDerived = linkonce_odr {{dso_local|hidden}} unnamed_addr constant {{.*}}, comdat, align 8 +// COFF-NOT: !dbg +// COFF-SAME: {{$}} // CHECK: [[BASE_VTABLE_VAR]] = !DIGlobalVariableExpression(var: [[BASE_VTABLE:![0-9]*]], expr: !DIExpression()) // CHECK-NEXT: [[BASE_VTABLE]] = distinct !DIGlobalVariable(name: "_vtable$", linkageName: "_ZTVN3NSP5CBaseE" diff --git a/clang/test/CodeGenOpenCL/preserve_vec3.cl b/clang/test/CodeGenOpenCL/preserve_vec3.cl index 49ebae6..e73657e 100644 --- a/clang/test/CodeGenOpenCL/preserve_vec3.cl +++ b/clang/test/CodeGenOpenCL/preserve_vec3.cl @@ -11,8 +11,8 @@ typedef float float4 __attribute__((ext_vector_type(4))); // CHECK-LABEL: define dso_local spir_kernel void @foo( // CHECK-SAME: ptr addrspace(1) noundef readonly align 16 captures(none) [[A:%.*]], ptr addrspace(1) noundef writeonly align 16 captures(none) initializes((0, 16)) [[B:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] !kernel_arg_addr_space [[META3:![0-9]+]] !kernel_arg_access_qual [[META4:![0-9]+]] !kernel_arg_type [[META5:![0-9]+]] !kernel_arg_base_type [[META6:![0-9]+]] !kernel_arg_type_qual [[META7:![0-9]+]] { // CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[LOADVECN:%.*]] = load <4 x float>, ptr addrspace(1) [[A]], align 16 -// CHECK-NEXT: [[EXTRACTVEC1:%.*]] = shufflevector <4 x float> [[LOADVECN]], <4 x float> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison> +// CHECK-NEXT: [[TMP0:%.*]] = load <3 x float>, ptr addrspace(1) [[A]], align 16 +// CHECK-NEXT: [[EXTRACTVEC1:%.*]] = shufflevector <3 x float> [[TMP0]], <3 x float> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison> // CHECK-NEXT: store <4 x float> [[EXTRACTVEC1]], ptr addrspace(1) [[B]], align 16, !tbaa [[TBAA8:![0-9]+]] // CHECK-NEXT: ret void // @@ -23,8 +23,8 @@ void kernel foo(global float3 *a, global float3 *b) { // CHECK-LABEL: define dso_local spir_kernel void @float4_to_float3( // CHECK-SAME: ptr addrspace(1) noundef writeonly align 16 captures(none) initializes((0, 16)) [[A:%.*]], ptr addrspace(1) noundef readonly align 16 captures(none) [[B:%.*]]) local_unnamed_addr #[[ATTR0]] !kernel_arg_addr_space [[META3]] !kernel_arg_access_qual [[META4]] !kernel_arg_type [[META11:![0-9]+]] !kernel_arg_base_type [[META12:![0-9]+]] !kernel_arg_type_qual [[META7]] { // CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[TMP0:%.*]] = load <4 x float>, ptr addrspace(1) [[B]], align 16, !tbaa [[TBAA8]] -// CHECK-NEXT: [[EXTRACTVEC:%.*]] = shufflevector <4 x float> [[TMP0]], <4 x float> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison> +// CHECK-NEXT: [[TMP0:%.*]] = load <3 x float>, ptr addrspace(1) [[B]], align 16, !tbaa [[TBAA8]] +// CHECK-NEXT: [[EXTRACTVEC:%.*]] = shufflevector <3 x float> [[TMP0]], <3 x float> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison> // CHECK-NEXT: store <4 x float> [[EXTRACTVEC]], ptr addrspace(1) [[A]], align 16, !tbaa [[TBAA8]] // CHECK-NEXT: ret void // @@ -35,8 +35,8 @@ void kernel float4_to_float3(global float3 *a, global float4 *b) { // CHECK-LABEL: define dso_local spir_kernel void @float3_to_float4( // CHECK-SAME: ptr addrspace(1) noundef readonly align 16 captures(none) [[A:%.*]], ptr addrspace(1) noundef writeonly align 16 captures(none) initializes((0, 16)) [[B:%.*]]) local_unnamed_addr #[[ATTR0]] !kernel_arg_addr_space [[META3]] !kernel_arg_access_qual [[META4]] !kernel_arg_type [[META11]] !kernel_arg_base_type [[META12]] !kernel_arg_type_qual [[META7]] { // CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[LOADVECN:%.*]] = load <4 x float>, ptr addrspace(1) [[A]], align 16 -// CHECK-NEXT: [[ASTYPE:%.*]] = shufflevector <4 x float> [[LOADVECN]], <4 x float> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison> +// CHECK-NEXT: [[TMP0:%.*]] = load <3 x float>, ptr addrspace(1) [[A]], align 16 +// CHECK-NEXT: [[ASTYPE:%.*]] = shufflevector <3 x float> [[TMP0]], <3 x float> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison> // CHECK-NEXT: store <4 x float> [[ASTYPE]], ptr addrspace(1) [[B]], align 16, !tbaa [[TBAA8]] // CHECK-NEXT: ret void // @@ -47,9 +47,9 @@ void kernel float3_to_float4(global float3 *a, global float4 *b) { // CHECK-LABEL: define dso_local spir_kernel void @float3_to_double2( // CHECK-SAME: ptr addrspace(1) noundef readonly align 16 captures(none) [[A:%.*]], ptr addrspace(1) noundef writeonly align 16 captures(none) initializes((0, 16)) [[B:%.*]]) local_unnamed_addr #[[ATTR0]] !kernel_arg_addr_space [[META3]] !kernel_arg_access_qual [[META4]] !kernel_arg_type [[META13:![0-9]+]] !kernel_arg_base_type [[META14:![0-9]+]] !kernel_arg_type_qual [[META7]] { // CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[LOADVECN:%.*]] = load <4 x float>, ptr addrspace(1) [[A]], align 16 -// CHECK-NEXT: [[TMP0:%.*]] = shufflevector <4 x float> [[LOADVECN]], <4 x float> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison> -// CHECK-NEXT: store <4 x float> [[TMP0]], ptr addrspace(1) [[B]], align 16, !tbaa [[TBAA8]] +// CHECK-NEXT: [[TMP0:%.*]] = load <3 x float>, ptr addrspace(1) [[A]], align 16 +// CHECK-NEXT: [[TMP1:%.*]] = shufflevector <3 x float> [[TMP0]], <3 x float> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison> +// CHECK-NEXT: store <4 x float> [[TMP1]], ptr addrspace(1) [[B]], align 16, !tbaa [[TBAA8]] // CHECK-NEXT: ret void // void kernel float3_to_double2(global float3 *a, global double2 *b) { @@ -59,8 +59,8 @@ void kernel float3_to_double2(global float3 *a, global double2 *b) { // CHECK-LABEL: define dso_local spir_kernel void @char8_to_short3( // CHECK-SAME: ptr addrspace(1) noundef writeonly align 8 captures(none) initializes((0, 8)) [[A:%.*]], ptr addrspace(1) noundef readonly align 8 captures(none) [[B:%.*]]) local_unnamed_addr #[[ATTR0]] !kernel_arg_addr_space [[META3]] !kernel_arg_access_qual [[META4]] !kernel_arg_type [[META15:![0-9]+]] !kernel_arg_base_type [[META16:![0-9]+]] !kernel_arg_type_qual [[META7]] { // CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[TMP0:%.*]] = load <4 x i16>, ptr addrspace(1) [[B]], align 8, !tbaa [[TBAA8]] -// CHECK-NEXT: [[EXTRACTVEC:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison> +// CHECK-NEXT: [[TMP0:%.*]] = load <3 x i16>, ptr addrspace(1) [[B]], align 8, !tbaa [[TBAA8]] +// CHECK-NEXT: [[EXTRACTVEC:%.*]] = shufflevector <3 x i16> [[TMP0]], <3 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison> // CHECK-NEXT: store <4 x i16> [[EXTRACTVEC]], ptr addrspace(1) [[A]], align 8, !tbaa [[TBAA8]] // CHECK-NEXT: ret void // diff --git a/clang/test/Frontend/dump-minimization-hints-cpp20-modules.cpp b/clang/test/Frontend/dump-minimization-hints-cpp20-modules.cpp new file mode 100644 index 0000000..a28acba --- /dev/null +++ b/clang/test/Frontend/dump-minimization-hints-cpp20-modules.cpp @@ -0,0 +1,117 @@ +// RUN: rm -rf %t +// RUN: mkdir -p %t +// RUN: split-file %s %t +// RUN: %clang_cc1 -std=c++20 %t/foo.cppm -emit-module-interface -o %t/foo.pcm +// RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t %t/use.cpp -dump-minimization-hints=%t/decls +// RUN: cat %t/decls +// RUN: cat %t/decls | FileCheck -check-prefix=RANGE %s +// RANGE:{ +// RANGE-NEXT:"required_ranges": [ +// RANGE-NEXT: { +// RANGE-NEXT: "file": "{{.+}}foo.cppm", +// RANGE-NEXT: "range": [ +// RANGE-NEXT: { +// RANGE-NEXT: "from": { +// RANGE-NEXT: "line": 3, +// RANGE-NEXT: "column": 1 +// RANGE-NEXT: }, +// RANGE-NEXT: "to": { +// RANGE-NEXT: "line": 3, +// RANGE-NEXT: "column": 22 +// RANGE-NEXT: } +// RANGE-NEXT: }, +// RANGE-NEXT: { +// RANGE-NEXT: "from": { +// RANGE-NEXT: "line": 4, +// RANGE-NEXT: "column": 3 +// RANGE-NEXT: }, +// RANGE-NEXT: "to": { +// RANGE-NEXT: "line": 4, +// RANGE-NEXT: "column": 9 +// RANGE-NEXT: } +// RANGE-NEXT: }, +// RANGE-NEXT: { +// RANGE-NEXT: "from": { +// RANGE-NEXT: "line": 4, +// RANGE-NEXT: "column": 10 +// RANGE-NEXT: }, +// RANGE-NEXT: "to": { +// RANGE-NEXT: "line": 4, +// RANGE-NEXT: "column": 43 +// RANGE-NEXT: } +// RANGE-NEXT: }, +// RANGE-NEXT: { +// RANGE-NEXT: "from": { +// RANGE-NEXT: "line": 6, +// RANGE-NEXT: "column": 1 +// RANGE-NEXT: }, +// RANGE-NEXT: "to": { +// RANGE-NEXT: "line": 6, +// RANGE-NEXT: "column": 2 +// RANGE-NEXT: } +// RANGE-NEXT: }, +// RANGE-NEXT: { +// RANGE-NEXT: "from": { +// RANGE-NEXT: "line": 8, +// RANGE-NEXT: "column": 1 +// RANGE-NEXT: }, +// RANGE-NEXT: "to": { +// RANGE-NEXT: "line": 8, +// RANGE-NEXT: "column": 7 +// RANGE-NEXT: } +// RANGE-NEXT: }, +// RANGE-NEXT: { +// RANGE-NEXT: "from": { +// RANGE-NEXT: "line": 8, +// RANGE-NEXT: "column": 8 +// RANGE-NEXT: }, +// RANGE-NEXT: "to": { +// RANGE-NEXT: "line": 8, +// RANGE-NEXT: "column": 25 +// RANGE-NEXT: } +// RANGE-NEXT: }, +// RANGE-NEXT: { +// RANGE-NEXT: "from": { +// RANGE-NEXT: "line": 9, +// RANGE-NEXT: "column": 3 +// RANGE-NEXT: }, +// RANGE-NEXT: "to": { +// RANGE-NEXT: "line": 9, +// RANGE-NEXT: "column": 36 +// RANGE-NEXT: } +// RANGE-NEXT: }, +// RANGE-NEXT: { +// RANGE-NEXT: "from": { +// RANGE-NEXT: "line": 11, +// RANGE-NEXT: "column": 1 +// RANGE-NEXT: }, +// RANGE-NEXT: "to": { +// RANGE-NEXT: "line": 11, +// RANGE-NEXT: "column": 2 +// RANGE-NEXT: } +// RANGE-NEXT: } +// RANGE-NEXT: ] +// RANGE-NEXT: } +// RANGE-NEXT:] +// RANGE-NEXT:} + +//--- foo.cppm +export module foo; + +namespace piecemeal { // line 3 + export int used(int n) { return n + 1; } + export int unused(int n) { return n + 2; } +} + +export namespace whole { // line 8 + int used(int n) { return n + 1; } + int unused(int n) { return n + 3; } +} // line 11 + +//--- use.cpp +import foo; + +int main() { + piecemeal::used(4); // only one of the functions used from each namespace. + whole::used(4); +} diff --git a/clang/test/Modules/ExtDebugInfo.cpp b/clang/test/Modules/ExtDebugInfo.cpp index 184973b..3e74e22 100644 --- a/clang/test/Modules/ExtDebugInfo.cpp +++ b/clang/test/Modules/ExtDebugInfo.cpp @@ -8,7 +8,7 @@ // RUN: -fmodule-format=obj -fimplicit-module-maps -DMODULES \ // RUN: -triple %itanium_abi_triple \ // RUN: -fmodules-cache-path=%t %s -I %S/Inputs -I %t -emit-llvm -o %t-mod.ll -// RUN: cat %t-mod.ll | FileCheck %s +// RUN: cat %t-mod.ll | FileCheck %s --check-prefix=CHECK %if target={{.*-(win|mingw|cyg).*}} %{--check-prefix=CHECKCOFF%} %else %{--check-prefix=CHECKELF%} // PCH: // RUN: %clang_cc1 -x c++ -std=c++11 -fmodule-format=obj -emit-pch -I%S/Inputs \ @@ -18,7 +18,7 @@ // RUN: -dwarf-ext-refs -fmodule-format=obj \ // RUN: -triple %itanium_abi_triple \ // RUN: -include-pch %t.pch %s -emit-llvm -o %t-pch.ll -// RUN: cat %t-pch.ll | FileCheck %s +// RUN: cat %t-pch.ll | FileCheck %s --check-prefix=CHECK %if target={{.*-(win|mingw|cyg).*}} %{--check-prefix=CHECKCOFF%} %else %{--check-prefix=CHECKELF%} // RUN: cat %t-pch.ll | FileCheck %s --check-prefix=CHECK-PCH #ifdef MODULES @@ -208,9 +208,9 @@ void foo() { // CHECK-SAME: name: "InAnonymousNamespace", {{.*}}DIFlagFwdDecl) // There is a full definition of the type available in the module. -// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Virtual", -// CHECK-SAME: DIFlagFwdDecl -// CHECK-SAME: identifier: "_ZTS7Virtual") +// CHECKELF: !DICompositeType(tag: DW_TAG_structure_type, name: "Virtual", +// CHECKELF-SAME: DIFlagFwdDecl +// CHECKELF-SAME: identifier: "_ZTS7Virtual") // CHECK: !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !{{[0-9]+}}, entity: ![[STRUCT]], file: ![[CPP]], line: 50) @@ -222,3 +222,8 @@ void foo() { // CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "A", // CHECK-SAME: DIFlagFwdDecl + +// There is a full definition of the type available in the module. +// CHECKCOFF: !DICompositeType(tag: DW_TAG_structure_type, name: "Virtual", +// CHECKCOFF-SAME: DIFlagFwdDecl +// CHECKCOFF-SAME: identifier: "_ZTS7Virtual") diff --git a/clang/test/Parser/cxx-template-template-recovery.cpp b/clang/test/Parser/cxx-template-template-recovery.cpp index 5700b16..61ef82d 100644 --- a/clang/test/Parser/cxx-template-template-recovery.cpp +++ b/clang/test/Parser/cxx-template-template-recovery.cpp @@ -22,18 +22,18 @@ auto V3 = true; // #V3 template <template <typename T> typename C> constexpr bool test = true; -static_assert(test<a::C1>); // expected-error {{too few template arguments for concept 'C1'}} \ +static_assert(test<a::C1>); // expected-error {{template argument does not refer to a class or alias template, or template template parameter}} \ // expected-note@#C1 {{here}} -static_assert(test<a::b::C2>); // expected-error {{too few template arguments for concept 'C2'}} \ +static_assert(test<a::b::C2>); // expected-error {{template argument does not refer to a class or alias template, or template template parameter}} \ // expected-note@#C2 {{here}} -static_assert(test<C3>); // expected-error {{too few template arguments for concept 'C3'}} \ +static_assert(test<C3>); // expected-error {{template argument does not refer to a class or alias template, or template template parameter}} \ // expected-note@#C3 {{here}} -static_assert(test<a::V1>); // expected-error {{use of variable template 'a::V1' requires template arguments}} \ +static_assert(test<a::V1>); // expected-error {{template argument does not refer to a class or alias template, or template template parameter}} \ // expected-note@#V1 {{here}} -static_assert(test<a::b::V2>); // expected-error {{use of variable template 'a::b::V2' requires template arguments}} \ +static_assert(test<a::b::V2>); // expected-error {{template argument does not refer to a class or alias template, or template template parameter}} \ // expected-note@#V2 {{here}} -static_assert(test<V3>); // expected-error {{use of variable template 'V3' requires template arguments}} \ +static_assert(test<V3>); // expected-error {{template argument does not refer to a class or alias template, or template template parameter}} \ // expected-note@#V3 {{here}} diff --git a/clang/test/Parser/cxx2a-concept-declaration.cpp b/clang/test/Parser/cxx2a-concept-declaration.cpp index 0a7af84..fea6084 100644 --- a/clang/test/Parser/cxx2a-concept-declaration.cpp +++ b/clang/test/Parser/cxx2a-concept-declaration.cpp @@ -9,11 +9,6 @@ template<concept T> concept D1 = true; // expected-error@-1{{expected template parameter}} // expected-error@-2{{concept template parameter list must have at least one parameter; explicit specialization of concepts is not allowed}} -template<template<typename> concept T> concept D2 = true; -// expected-error@-1{{expected identifier}} -// expected-error@-2{{template template parameter requires 'class' or 'typename' after the parameter list}} -// expected-error@-3{{concept template parameter list must have at least one parameter; explicit specialization of concepts is not allowed}} - struct S1 { template<typename T> concept C1 = true; // expected-error {{concept declarations may only appear in global or namespace scope}} }; diff --git a/clang/test/Parser/cxx2c-template-template-param.cpp b/clang/test/Parser/cxx2c-template-template-param.cpp new file mode 100644 index 0000000..e8c7621 --- /dev/null +++ b/clang/test/Parser/cxx2c-template-template-param.cpp @@ -0,0 +1,79 @@ +// RUN: %clang_cc1 -std=c++2c -verify %s + +template<template<typename> auto Var> +struct A{}; +template<template<auto> auto Var> +struct B{}; +template<template<typename> auto Var> +struct C{}; +template<template<typename> concept C> +struct D{}; +template<template<auto> concept C> +struct E{}; + +template<template<typename> auto Var> +int V1; +template<template<auto> auto Var> +int V2; +template<template<typename> auto Var> +int V3; +template<template<typename> concept C> +int V4; +template<template<auto> concept C> +int V5; + +namespace packs { + +template<template<typename> auto... Var> +struct A{}; +template<template<auto> auto... Var> +struct B{}; +template<template<typename> auto... Var> +struct C{}; +template<template<typename> concept... C> +struct D{}; +template<template<auto> concept... C> +struct E{}; + +template<template<typename> auto... Var> +int V1; +template<template<auto> auto... Var> +int V2; +template<template<typename> auto... Var> +int V3; +template<template<typename> concept... C> +int V4; +template<template<auto> concept... C> +int V5; + +} + +namespace concepts { +template<template<auto> concept...> +struct A{}; +template<template<auto> concept... C> +struct B{}; +template<template<auto> concept& C> // expected-error{{expected identifier}} \ + // expected-error {{in declaration of struct 'C'}} +struct C{}; +} + +namespace vars { +template<template<auto> auto...> +struct A{}; +template<template<auto> auto & C> // expected-error {{expected identifier}} \ + // expected-error {{extraneous 'template<>'}} +struct B{}; +template<template<auto> const auto> // expected-error {{expected identifier}} \ + // expected-error {{extraneous 'template<>'}} +struct C{}; +} + +namespace errors { +template<concept> // expected-error {{expected template parameter}} \ + // expected-error {{extraneous 'template<>' in declaration of struct 'A'}} +struct A{}; +template<template<concept> auto> // expected-error {{expected template parameter}} \ + // expected-error {{template template parameter must have its own template parameters}} +struct B{}; +} diff --git a/clang/test/Sema/riscv-interrupt-attr-rnmi.c b/clang/test/Sema/riscv-interrupt-attr-rnmi.c new file mode 100644 index 0000000..964bae5 --- /dev/null +++ b/clang/test/Sema/riscv-interrupt-attr-rnmi.c @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -triple riscv32-unknown-elf -target-feature +smrnmi -emit-llvm -DCHECK_IR < %s | FileCheck %s +// RUN: %clang_cc1 %s -triple riscv32-unknown-elf -target-feature +smrnmi -verify=enabled,both -fsyntax-only +// RUN: %clang_cc1 %s -triple riscv32-unknown-elf -verify=disabled,both -fsyntax-only +// RUN: %clang_cc1 %s -triple riscv32-unknown-elf -target-feature -srnmi -verify=disabled,both -fsyntax-only + +#if defined(CHECK_IR) +// CHECK-LABEL: foo_rnmi_interrupt() #0 +// CHECK: ret void +__attribute__((interrupt("rnmi"))) +void foo_rnmi_interrupt(void) {} + +// CHECK-LABEL: @foo_rnmi_rnmi_interrupt() #0 +// CHECK: ret void +__attribute__((interrupt("rnmi", "rnmi"))) +void foo_rnmi_rnmi_interrupt(void) {} + +// CHECK: attributes #0 +// CHECK: "interrupt"="rnmi" +#else + +__attribute__((interrupt("rnmi"))) void test_rnmi(void) {} // disabled-error {{RISC-V 'interrupt' attribute 'rnmi' requires extension 'Smrnmi'}} +__attribute__((interrupt("rnmi", "rnmi"))) void test_rnmi_rnmi(void) {} // disabled-error {{RISC-V 'interrupt' attribute 'rnmi' requires extension 'Smrnmi'}} + +__attribute__((interrupt("rnmi", "supervisor"))) void foo_rnmi_supervisor(void) {} // both-error {{RISC-V 'interrupt' attribute contains invalid combination of interrupt types}} +__attribute__((interrupt("rnmi", "machine"))) void foo_rnmi_machine(void) {} // both-error {{RISC-V 'interrupt' attribute contains invalid combination of interrupt types}} + +__attribute__((interrupt("RNMI"))) void test_RNMI(void) {} // both-warning {{'interrupt' attribute argument not supported: "RNMI"}} +#endif diff --git a/clang/test/SemaCXX/cxx2c-template-template-param.cpp b/clang/test/SemaCXX/cxx2c-template-template-param.cpp new file mode 100644 index 0000000..ed55a059 --- /dev/null +++ b/clang/test/SemaCXX/cxx2c-template-template-param.cpp @@ -0,0 +1,352 @@ +// RUN: %clang_cc1 -std=c++2c -verify %s + +namespace Errors { + +template <template<typename T> auto> +struct S1; +template <template<auto T> auto> +struct S2; +template <template<typename T> concept> +struct S3; +template <template<auto T> concept> +struct S4; +int a; + +template <typename T> +concept C = true; // expected-note 2{{template argument refers to a concept 'C', here}} +template <typename T> +auto Var = 0; // expected-note 2{{template argument refers to a variable template 'Var', here}} + +S1<1> t1; // expected-error {{template argument for template template parameter must be a variable template}} +S1<a> t2; // expected-error {{template argument for template template parameter must be a variable template}} +S1<int> t3; // expected-error {{template argument for template template parameter must be a variable template}} +S1<C> t4; // expected-error {{template argument does not refer to a variable template, or template template parameter}} +S2<1> t5; // expected-error {{template argument for template template parameter must be a variable template}} +S2<a> t6; // expected-error {{template argument for template template parameter must be a variable template}} +S2<int> t7; // expected-error {{template argument for template template parameter must be a variable template}} +S2<C> t8; // expected-error {{template argument does not refer to a variable template, or template template parameter}} +S3<1> t9; // expected-error {{template argument for template template parameter must be a concept}} +S3<a> t10; // expected-error {{template argument for template template parameter must be a concept}} +S3<int> t11; // expected-error {{template argument for template template parameter must be a concept}} +S3<Var> t12; // expected-error {{template argument does not refer to a concept, or template template parameter}} +S4<1> t13; // expected-error {{template argument for template template parameter must be a concept}} +S4<a> t14; // expected-error {{template argument for template template parameter must be a concept}} +S4<int> t15; // expected-error {{template argument for template template parameter must be a concept}} +S4<Var> t16; // expected-error {{template argument does not refer to a concept, or template template parameter}} + +} + +template <template<typename T> auto V> // expected-note {{previous template template parameter is here}} \ + // expected-error{{template argument for non-type template parameter must be an expression}} +struct S1 { + static_assert(V<int> == 42); + static_assert(V<const int> == 84); + static_assert(V<double> == 0); +}; +template <template<auto T> auto V> // expected-error {{template argument for template type parameter must be a type}} \ + // expected-note {{previous template template parameter is here}} +struct S2 { + static_assert(V<0> == 1); + static_assert(V<1> == 0); +}; +template <template<typename T> concept C > // expected-error {{template argument for non-type template parameter must be an expression}} \ + // expected-note {{previous template template parameter is here}} +struct S3 { + static_assert(C<int>); +}; +template <template<auto> concept C> // expected-error {{template argument for template type parameter must be a type}} \ + // expected-note {{previous template template parameter is here}} +struct S4 { + static_assert(C<0>); +}; + +template <typename T> // expected-note {{template parameter is declared here}} +concept C = true; + +template <auto I> // expected-note {{template parameter is declared here}} +concept CI = true; + +template <typename T> // expected-note {{template parameter is declared here}} +constexpr auto Var = 42; +template <typename T> +constexpr auto Var<const T> = 84; +template <> +constexpr auto Var<double> = 0; + +template <auto N> // expected-note {{template parameter is declared here}} +constexpr auto Var2 = 0; +template <auto N> +requires (N%2 == 0) +constexpr auto Var2<N> = 1; + +void test () { + S1<Var2> sE; // expected-note {{template template argument has different template parameters than its corresponding template template parameter}} + S2<Var> sE; // expected-note {{template template argument has different template parameters than its corresponding template template parameter}} + S1<Var> s1; + S2<Var2> s2; + S3<C> s3; + S4<C> sE; // expected-note {{template template argument has different template parameters than its corresponding template template parameter}} + S4<CI> s4; + S3<CI> sE; // expected-note {{template template argument has different template parameters than its corresponding template template parameter}} +} + + +namespace template_type_constraints { + + +template <typename T> +concept Unary = true; +template <typename T, typename = int> +concept BinaryDefaulted = true; + +template <typename T> +concept UnaryFalse = false; // expected-note 3{{because 'false' evaluated to false}} +template <typename T, typename = int> +concept BinaryDefaultedFalse = false; + +template <template <typename...> concept C, typename T> +struct S { + template <C TT> // expected-note {{because 'int' does not satisfy 'UnaryFalse'}} + void f(TT); // expected-note {{ignored}} + void g(C auto); // expected-note {{ignored}} \ + // expected-note {{because 'int' does not satisfy 'UnaryFalse'}} + + auto h() -> C auto { // expected-error {{deduced type 'int' does not satisfy 'UnaryFalse'}} + return 0; + }; + + void test() { + C auto a = 0; + } +}; + +template <template <typename...> concept C, typename T> +struct SArg { + template <C<int> TT> + void f(TT); + void g(C<int> auto); + + auto h() -> C<int> auto { + return 0; + }; + void test() { + C<int> auto a = 0; + } +}; + +void test() { + S<Unary, int> s; + s.f(0); + s.g(0); + s.h(); + S<BinaryDefaulted, int> s2; + s2.f(0); + s2.g(0); + s2.h(); + + SArg<BinaryDefaulted, int> s3; + s3.f(0); + s3.g(0); + s3.h(); +} + +void test_errors() { + S<UnaryFalse, int> s; + s.f(0); // expected-error {{no matching member function for call to 'f'}} + s.g(0); // expected-error {{no matching member function for call to 'g'}} + s.h(); // expected-note {{in instantiation of member function 'template_type_constraints::S<template_type_constraints::UnaryFalse, int>::h'}} +} + +} + +template <typename T> +concept Unary = true; +template <typename T, typename = int> +concept BinaryDefaulted = true; + +template <typename T> +concept UnaryFalse = false; // expected-note 3{{because 'false' evaluated to false}} +template <typename T, typename = int> +concept BinaryDefaultedFalse = false; + +template <template <typename...> concept C, typename T> +struct S { + template <C TT> // expected-note {{because 'int' does not satisfy 'UnaryFalse'}} + void f(TT); // expected-note {{ignored}} + void g(C auto); // expected-note {{ignored}} \ + // expected-note {{because 'int' does not satisfy 'UnaryFalse'}} + + auto h() -> C auto { // expected-error {{deduced type 'int' does not satisfy 'UnaryFalse'}} + return 0; + }; + + void test() { + C auto a = 0; + } +}; + +template <template <typename...> concept C, typename T> +struct SArg { + template <C<int> TT> + void f(TT); + void g(C<int> auto); + + auto h() -> C<int> auto { + return 0; + }; + void test() { + C<int> auto a = 0; + } +}; + +void test_args() { + S<Unary, int> s; + s.f(0); + s.g(0); + s.h(); + S<BinaryDefaulted, int> s2; + s2.f(0); + s2.g(0); + s2.h(); + + SArg<BinaryDefaulted, int> s3; + s3.f(0); + s3.g(0); + s3.h(); +} + +void test_errors() { + S<UnaryFalse, int> s; + s.f(0); // expected-error {{no matching member function for call to 'f'}} + s.g(0); // expected-error {{no matching member function for call to 'g'}} + s.h(); // expected-note {{in instantiation of member function 'S<UnaryFalse, int>::h'}} +} + +namespace non_type { + +template <auto> +concept Unary = true; + +template <template <auto> concept C> +struct S { + template <C Foo> // expected-error {{concept named in type constraint is not a type concept}} + void f(); + // FIXME, bad diagnostic + void g(C auto); // expected-error{{concept named in type constraint is not a type concept}} + auto h() -> C auto { // expected-error{{concept named in type constraint is not a type concept}} + } + void i() { + C auto a = 0; // expected-error{{concept named in type constraint is not a type concept}} + } +}; + +} + +namespace default_args { + +template <typename T> +concept Concept = false; // expected-note 2{{template argument refers to a concept 'Concept', here}} \ + // expected-note 2{{because 'false' evaluated to false}} + +template <typename T> +constexpr auto Var = false; // expected-note 2{{template argument refers to a variable template 'Var', here}} + +template <typename T> +struct Type; // expected-note 2{{template argument refers to a class template 'Type', here}} + + +template <template <typename> auto = Concept> // expected-error {{template argument does not refer to a variable template, or template template parameter}} +struct E1; + +template <template <typename> auto = Type> // expected-error {{template argument does not refer to a variable template, or template template parameter}} +struct E2; + +template <template <typename> typename = Concept> // expected-error {{template argument does not refer to a class or alias template, or template template parameter}} +struct E3; + +template <template <typename> typename = Var> // expected-error {{template argument does not refer to a class or alias template, or template template parameter}} +struct E4; + +template <template <typename> concept = Var> // expected-error {{template argument does not refer to a concept, or template template parameter}} +struct E4; + +template <template <typename> concept = Type> // expected-error {{template argument does not refer to a concept, or template template parameter}} +struct E4; + +template < + template <typename> concept TConcept, // expected-note 2{{template argument refers to a concept 'TConcept', here}} + template <typename> auto TVar, // expected-note 2{{template argument refers to a variable template 'TVar', here}} + template <typename> typename TType // expected-note 2{{template argument refers to a class template 'TType', here}} +> +struct Nested { + template <template <typename> auto = TConcept> // expected-error {{template argument does not refer to a variable template, or template template parameter}} + struct E1; + + template <template <typename> auto = TType> // expected-error {{template argument does not refer to a variable template, or template template parameter}} + struct E2; + + template <template <typename> typename = TConcept> // expected-error {{template argument does not refer to a class or alias template, or template template parameter}} + struct E3; + + template <template <typename> typename = TVar> // expected-error {{template argument does not refer to a class or alias template, or template template parameter}} + struct E4; + + template <template <typename> concept = TVar> // expected-error {{template argument does not refer to a concept, or template template parameter}} + struct E4; + + template <template <typename> concept = TType> // expected-error {{template argument does not refer to a concept, or template template parameter}} + struct E4; +}; + + +template <template <typename> concept C = Concept> +struct TestDefaultConcept { + template <template <typename> concept CC = C> + void f() { + static_assert(C<int>); // expected-error {{static assertion failed}} \ + // expected-note {{because 'int' does not satisfy 'Concept'}} + static_assert(CC<int>); // expected-error {{static assertion failed}} \ + // expected-note {{because 'int' does not satisfy 'Concept'}} + } +}; +void do_test_concept() { + TestDefaultConcept<>{}.f(); // expected-note {{in instantiation}} +} + +template <template <typename> auto V = Var> +struct TestDefaultVar { + template <template <typename> auto VV = V> + void f() { + static_assert(V<int>); // expected-error {{static assertion failed}} + static_assert(VV<int>); // expected-error {{static assertion failed}} + } +}; +void do_test_var() { + TestDefaultVar<>{}.f(); // expected-note {{in instantiation}} +} + +} + +namespace TTPDependence { +template <template <typename... > concept C> +concept A = C<>; +template <template <typename... > concept C> +concept B = C<int>; + +template <template <typename... > auto Var> +concept C = Var<>; +template <template <typename... > auto Var> +concept D = Var<int>; + +} + +namespace InvalidName { +template <typename T, template <typename> concept C> +concept A = C<T>; // expected-note {{here}} + +template <A<concept missing<int>> T> // expected-error {{expected expression}} \ + // expected-error {{too few template arguments for concept 'A'}} \ + // expected-error {{unknown type name 'T'}} \ + // expected-error {{expected unqualified-id}} +auto f(); +} |