diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 57115b10ebf57..e5696be6c6f7a 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -383,8 +383,8 @@ class Qualifiers { | (((uint32_t) space) << AddressSpaceShift); } void removeAddressSpace() { setAddressSpace(LangAS::Default); } - void addAddressSpace(LangAS space) { - assert(space != LangAS::Default); + void addAddressSpace(LangAS space, bool AllowDefaultAddrSpace = false) { + assert(space != LangAS::Default || AllowDefaultAddrSpace); setAddressSpace(space); } diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index ef3061ee514fd..01e4b6ea01917 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -4897,7 +4897,8 @@ static void TryReferenceInitializationCore(Sema &S, // Add addr space conversion if required. if (T1Quals.getAddressSpace() != T2Quals.getAddressSpace()) { auto T4Quals = cv1T4.getQualifiers(); - T4Quals.addAddressSpace(T1Quals.getAddressSpace()); + T4Quals.addAddressSpace(T1Quals.getAddressSpace(), + S.getLangOpts().SYCLIsDevice); QualType cv1T4WithAS = S.Context.getQualifiedType(T2, T4Quals); Sequence.AddQualificationConversionStep(cv1T4WithAS, ValueKind); cv1T4 = cv1T4WithAS; diff --git a/clang/test/SemaSYCL/sycl-templ-addr-space.cpp b/clang/test/SemaSYCL/sycl-templ-addr-space.cpp new file mode 100644 index 0000000000000..64e1a3659d7de --- /dev/null +++ b/clang/test/SemaSYCL/sycl-templ-addr-space.cpp @@ -0,0 +1,52 @@ +// RUN: %clang_cc1 -fsycl -fsycl-is-device -triple spir64 -verify %s + +// Test that the compiler no longer asserts while processing this test case. + +template +struct integral_constant { + static constexpr int val = N; +}; +template +T &&convert(int); +template +auto declval(convert(0)); +template +class sub_group { + template )> + // expected-note@+1 {{possible target for call}} + static integral_constant binary_op(); + // expected-error@+1 {{reference to overloaded function could not be resolved; did you mean to call it?}} + decltype(binary_op) i; +}; +// expected-note-re@+2 {{in instantiation {{.*}} requested here}} +template +struct group : sub_group { +}; +template +struct wrapper { + typedef T val; +}; +class element_type { +}; +struct Container { + using __element_type = __attribute__((opencl_global)) element_type; +}; +template using BaseImpl = Base; +// expected-note-re@+1 2{{candidate constructor {{.*}} not viable: {{.*}}}} +template class id_type { + template struct Base; + // expected-note-re@+1 {{in instantiation {{.*}} requested here}} + template struct Base : BaseImpl, Der> {}; + // expected-note-re@+1 {{in instantiation {{.*}} requested here}} + template using Base2 = wrapper>::val>; + // expected-note-re@+3 {{in instantiation {{.*}} requested here}} + // expected-note-re@+2 {{in instantiation {{.*}} required here}} + // expected-note-re@+1 {{candidate template ignored: {{.*}}}} + template > id_type(T &); +}; +id_type<1> get() { + Container::__element_type *ElemPtr; + // expected-error@+2 {{no viable conversion from returned value of type 'Container::__element_type' (aka '__global element_type') to function return type 'id_type<1>'}} + // expected-note-re@+1 {{while substituting {{.*}}}} + return ElemPtr[0]; +}