Anastasia created this revision. Anastasia added reviewers: rjmccall, ebevhan.
This is a straw-man idea for solving binding references with address spaces to temporaries. If the logic below makes sense I will apply it elsewhere in similar checks. Arbitrary address space references can't be bound to temporaries. The reference binding logic should check that the address space of temporary can be implicitly converted to address space in reference when temporary materialization is performed. Example: _AS1 float gf; ... _AS1 const int& ref = gf; //this can only be accepted if implicit conversion from _AS1 to LangAS::Default is allowed This review depends on: https://reviews.llvm.org/D58060 https://reviews.llvm.org/D61318 Files: include/clang/Basic/DiagnosticIDs.h include/clang/Basic/DiagnosticSemaKinds.td include/clang/Sema/Initialization.h lib/Sema/SemaInit.cpp test/SemaOpenCLCXX/address-space-references.cl
Index: test/SemaOpenCLCXX/address-space-references.cl =================================================================== --- test/SemaOpenCLCXX/address-space-references.cl +++ test/SemaOpenCLCXX/address-space-references.cl @@ -9,3 +9,7 @@ void foo() { bar(1) // expected-error{{binding reference of type 'const __global unsigned int' to value of type 'int' changes address space}} } + +__global const int &f(__global float &ref) { + return ref; // expected-error{{reference of type 'const __global int &' cannot bind to a temporary object because of address space mismatch}} +} Index: lib/Sema/SemaInit.cpp =================================================================== --- lib/Sema/SemaInit.cpp +++ lib/Sema/SemaInit.cpp @@ -3336,6 +3336,7 @@ case FK_NonConstLValueReferenceBindingToVectorElement: case FK_NonConstLValueReferenceBindingToUnrelated: case FK_RValueReferenceBindingToLValue: + case FK_ReferenceAddrspaceMismatchTemporary: case FK_ReferenceInitDropsQualifiers: case FK_ReferenceInitFailed: case FK_ConversionFailed: @@ -4831,9 +4832,15 @@ Sequence.AddReferenceBindingStep(cv1T1IgnoreAS, /*bindingTemporary=*/true); - if (T1Quals.hasAddressSpace()) + if (T1Quals.hasAddressSpace()) { + if (!T1Quals.isAddressSpaceSupersetOf(cv1T1IgnoreAS.getQualifiers())) { + Sequence.SetFailed( + InitializationSequence::FK_ReferenceAddrspaceMismatchTemporary); + return; + } Sequence.AddQualificationConversionStep(cv1T1, isLValueRef ? VK_LValue : VK_XValue); + } } /// Attempt character array initialization from a string literal @@ -8497,6 +8504,11 @@ << Args[0]->getSourceRange(); break; + case FK_ReferenceAddrspaceMismatchTemporary: + S.Diag(Kind.getLocation(), diag::err_reference_bind_temporary_addrspace) + << DestType << Args[0]->getSourceRange(); + break; + case FK_ReferenceInitDropsQualifiers: { QualType SourceType = OnlyArg->getType(); QualType NonRefType = DestType.getNonReferenceType(); @@ -8832,6 +8844,10 @@ OS << "reference initialization drops qualifiers"; break; + case FK_ReferenceAddrspaceMismatchTemporary: + OS << "reference with mismatching address space bound to temporary"; + break; + case FK_ReferenceInitFailed: OS << "reference initialization failed"; break; Index: include/clang/Sema/Initialization.h =================================================================== --- include/clang/Sema/Initialization.h +++ include/clang/Sema/Initialization.h @@ -1010,6 +1010,9 @@ /// Reference binding drops qualifiers. FK_ReferenceInitDropsQualifiers, + /// Reference with mismatching address space binding to temporary. + FK_ReferenceAddrspaceMismatchTemporary, + /// Reference binding failed. FK_ReferenceInitFailed, Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -1840,6 +1840,9 @@ "reference %diff{to %select{type|incomplete type}1 $ could not bind to an " "%select{rvalue|lvalue}2 of type $|could not bind to %select{rvalue|lvalue}2 of " "incompatible type}0,3">; +def err_reference_bind_temporary_addrspace : Error< + "reference of type %0 cannot bind to a temporary object because of " + "address space mismatch">; def err_reference_bind_init_list : Error< "reference to type %0 cannot bind to an initializer list">; def err_init_list_bad_dest_type : Error< Index: include/clang/Basic/DiagnosticIDs.h =================================================================== --- include/clang/Basic/DiagnosticIDs.h +++ include/clang/Basic/DiagnosticIDs.h @@ -36,7 +36,7 @@ DIAG_SIZE_AST = 150, DIAG_SIZE_COMMENT = 100, DIAG_SIZE_CROSSTU = 100, - DIAG_SIZE_SEMA = 3500, + DIAG_SIZE_SEMA = 3600, DIAG_SIZE_ANALYSIS = 100, DIAG_SIZE_REFACTORING = 1000, };
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits