Author: stulova Date: Fri Jun 21 04:36:15 2019 New Revision: 364032 URL: http://llvm.org/viewvc/llvm-project?rev=364032&view=rev Log: [Sema] Fix diagnostic for addr spaces in reference binding
Extend reference binding behavior to account for address spaces. Differential Revision: https://reviews.llvm.org/D62914 Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/lib/Sema/SemaInit.cpp cfe/trunk/test/SemaOpenCLCXX/address-space-references.cl Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=364032&r1=364031&r2=364032&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Jun 21 04:36:15 2019 @@ -1852,7 +1852,7 @@ def err_lvalue_reference_bind_to_unrelat "cannot bind to a value of unrelated type}1,2">; def err_reference_bind_drops_quals : Error< "binding reference %diff{of type $ to value of type $|to value}0,1 " - "drops %2 qualifier%plural{1:|2:|4:|:s}3">; + "%select{drops %3 qualifier%plural{1:|2:|4:|:s}4|changes address space}2">; def err_reference_bind_failed : Error< "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 " Modified: cfe/trunk/lib/Sema/SemaInit.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=364032&r1=364031&r2=364032&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaInit.cpp (original) +++ cfe/trunk/lib/Sema/SemaInit.cpp Fri Jun 21 04:36:15 2019 @@ -4631,7 +4631,10 @@ static void TryReferenceInitializationCo // - Otherwise, the reference shall be an lvalue reference to a // non-volatile const type (i.e., cv1 shall be const), or the reference // shall be an rvalue reference. - if (isLValueRef && !(T1Quals.hasConst() && !T1Quals.hasVolatile())) { + // For address spaces, we interpret this to mean that an addr space + // of a reference "cv1 T1" is a superset of addr space of "cv2 T2". + if (isLValueRef && !(T1Quals.hasConst() && !T1Quals.hasVolatile() && + T1Quals.isAddressSpaceSupersetOf(T2Quals))) { if (S.Context.getCanonicalType(T2) == S.Context.OverloadTy) Sequence.SetFailed(InitializationSequence::FK_AddressOfOverloadFailed); else if (ConvOvlResult && !Sequence.getFailedCandidateSet().empty()) @@ -4640,7 +4643,10 @@ static void TryReferenceInitializationCo ConvOvlResult); else if (!InitCategory.isLValue()) Sequence.SetFailed( - InitializationSequence::FK_NonConstLValueReferenceBindingToTemporary); + T1Quals.isAddressSpaceSupersetOf(T2Quals) + ? InitializationSequence:: + FK_NonConstLValueReferenceBindingToTemporary + : InitializationSequence::FK_ReferenceInitDropsQualifiers); else { InitializationSequence::FailureKind FK; switch (RefRelationship) { @@ -8521,12 +8527,16 @@ bool InitializationSequence::Diagnose(Se Qualifiers DroppedQualifiers = SourceType.getQualifiers() - NonRefType.getQualifiers(); - S.Diag(Kind.getLocation(), diag::err_reference_bind_drops_quals) - << NonRefType - << SourceType - << Qualifiers::fromCVRMask(DroppedQualifiers.getCVRQualifiers()) - << DroppedQualifiers.getCVRQualifiers() - << Args[0]->getSourceRange(); + if (!NonRefType.getQualifiers().isAddressSpaceSupersetOf( + SourceType.getQualifiers())) + S.Diag(Kind.getLocation(), diag::err_reference_bind_drops_quals) + << NonRefType << SourceType << 1 /*addr space*/ + << Args[0]->getSourceRange(); + else + S.Diag(Kind.getLocation(), diag::err_reference_bind_drops_quals) + << NonRefType << SourceType << 0 /*cv quals*/ + << Qualifiers::fromCVRMask(DroppedQualifiers.getCVRQualifiers()) + << DroppedQualifiers.getCVRQualifiers() << Args[0]->getSourceRange(); break; } Modified: cfe/trunk/test/SemaOpenCLCXX/address-space-references.cl URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaOpenCLCXX/address-space-references.cl?rev=364032&r1=364031&r2=364032&view=diff ============================================================================== --- cfe/trunk/test/SemaOpenCLCXX/address-space-references.cl (original) +++ cfe/trunk/test/SemaOpenCLCXX/address-space-references.cl Fri Jun 21 04:36:15 2019 @@ -3,3 +3,13 @@ __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}} } + +int bar(const __global unsigned int &i); // expected-note{{passing argument to parameter 'i' here}} +//FIXME: With the overload below the call should be resolved +// successfully. However, current overload resolution logic +// can't detect this case and therefore fails. +int bar(const unsigned int &i); + +void foo() { + bar(1) // expected-error{{binding reference of type 'const __global unsigned int' to value of type 'int' changes address space}} +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits