From 5145b1e4421adb3ac7e558cb88c9a2100ccb2b44 Mon Sep 17 00:00:00 2001 From: Anastasia Stulova Date: Wed, 5 Jun 2019 14:03:34 +0000 Subject: [Sema] Prevent binding incompatible addr space ref to temporaries References to arbitrary address spaces can't always be bound to temporaries. This change extends the reference binding logic to check that the address space of a temporary can be implicitly converted to the address space in a reference when temporary materialization is performed. Differential Revision: https://reviews.llvm.org/D61318 llvm-svn: 362604 --- clang/lib/Sema/SemaInit.cpp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'clang/lib/Sema/SemaInit.cpp') diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 45456aff364..25aff40f26f 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -3344,6 +3344,7 @@ bool InitializationSequence::isAmbiguous() const { case FK_NonConstLValueReferenceBindingToVectorElement: case FK_NonConstLValueReferenceBindingToUnrelated: case FK_RValueReferenceBindingToLValue: + case FK_ReferenceAddrspaceMismatchTemporary: case FK_ReferenceInitDropsQualifiers: case FK_ReferenceInitFailed: case FK_ConversionFailed: @@ -4837,9 +4838,16 @@ static void TryReferenceInitializationCore(Sema &S, Sequence.AddReferenceBindingStep(cv1T1IgnoreAS, /*bindingTemporary=*/true); - if (T1Quals.hasAddressSpace()) + if (T1Quals.hasAddressSpace()) { + if (!Qualifiers::isAddressSpaceSupersetOf(T1Quals.getAddressSpace(), + LangAS::Default)) { + Sequence.SetFailed( + InitializationSequence::FK_ReferenceAddrspaceMismatchTemporary); + return; + } Sequence.AddQualificationConversionStep(cv1T1, isLValueRef ? VK_LValue : VK_XValue); + } } /// Attempt character array initialization from a string literal @@ -8516,6 +8524,11 @@ bool InitializationSequence::Diagnose(Sema &S, << 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(); @@ -8851,6 +8864,10 @@ void InitializationSequence::dump(raw_ostream &OS) const { 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; -- cgit v1.2.3