summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--clang/lib/Sema/SemaInit.cpp26
-rw-r--r--clang/test/SemaOpenCLCXX/address-space-references.cl10
3 files changed, 29 insertions, 9 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index c8674d781c9..2abf7d73c1e 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1852,7 +1852,7 @@ def err_lvalue_reference_bind_to_unrelated : Error<
"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 "
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 128809175e2..d2a4a0979d1 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -4631,7 +4631,10 @@ static void TryReferenceInitializationCore(Sema &S,
// - 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 TryReferenceInitializationCore(Sema &S,
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(Sema &S,
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;
}
diff --git a/clang/test/SemaOpenCLCXX/address-space-references.cl b/clang/test/SemaOpenCLCXX/address-space-references.cl
index c359bbd713a..851d3023df2 100644
--- a/clang/test/SemaOpenCLCXX/address-space-references.cl
+++ b/clang/test/SemaOpenCLCXX/address-space-references.cl
@@ -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}}
+}
OpenPOWER on IntegriCloud