diff options
author | Anastasia Stulova <anastasia.stulova@arm.com> | 2019-06-20 16:23:28 +0000 |
---|---|---|
committer | Anastasia Stulova <anastasia.stulova@arm.com> | 2019-06-20 16:23:28 +0000 |
commit | c25ea86d43929c02dcc19512fb26a99ca256657d (patch) | |
tree | 0ad87beb7adde675054e9fa58282c99d0a0cfcc2 /clang/lib | |
parent | 1fffe8d6eede5afedb6da94443229657df724d22 (diff) | |
download | bcm5719-llvm-c25ea86d43929c02dcc19512fb26a99ca256657d.tar.gz bcm5719-llvm-c25ea86d43929c02dcc19512fb26a99ca256657d.zip |
[Sema] Diagnose addr space mismatch while constructing objects
If we construct an object in some arbitrary non-default addr space
it should fail unless either:
- There is an implicit conversion from the address space to default
/generic address space.
- There is a matching ctor qualified with an address space that is
either exactly matching or convertible to the address space of an
object.
Differential Revision: https://reviews.llvm.org/D62156
llvm-svn: 363944
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 9 | ||||
-rw-r--r-- | clang/lib/Sema/SemaInit.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 26 |
3 files changed, 34 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 6686b855c3b..6dda693c6ad 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -8232,12 +8232,19 @@ QualType Sema::CheckConstructorDeclarator(Declarator &D, QualType R, DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo(); if (FTI.hasMethodTypeQualifiers()) { + bool DiagOccured = false; FTI.MethodQualifiers->forEachQualifier( [&](DeclSpec::TQ TypeQual, StringRef QualName, SourceLocation SL) { + // This diagnostic should be emitted on any qualifier except an addr + // space qualifier. However, forEachQualifier currently doesn't visit + // addr space qualifiers, so there's no way to write this condition + // right now; we just diagnose on everything. Diag(SL, diag::err_invalid_qualified_constructor) << QualName << SourceRange(SL); + DiagOccured = true; }); - D.setInvalidType(); + if (DiagOccured) + D.setInvalidType(); } // C++0x [class.ctor]p4: diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index d5ef5eddf3e..16c396890a9 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -3733,6 +3733,7 @@ ResolveConstructorOverload(Sema &S, SourceLocation DeclLoc, bool OnlyListConstructors, bool IsListInit, bool SecondStepOfCopyInit = false) { CandidateSet.clear(OverloadCandidateSet::CSK_InitByConstructor); + CandidateSet.setDestAS(DestType.getQualifiers().getAddressSpace()); for (NamedDecl *D : Ctors) { auto Info = getConstructorInfo(D); @@ -4985,6 +4986,7 @@ static void TryUserDefinedConversion(Sema &S, // structure, so that it will persist if we fail. OverloadCandidateSet &CandidateSet = Sequence.getFailedCandidateSet(); CandidateSet.clear(OverloadCandidateSet::CSK_InitByUserDefinedConversion); + CandidateSet.setDestAS(DestType.getQualifiers().getAddressSpace()); // Determine whether we are allowed to call explicit constructors or // explicit conversion operators. diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 70bb757607d..11595fac2cb 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -6101,6 +6101,15 @@ void Sema::AddOverloadCandidate( return; } } + + // Check that the constructor is capable of constructing an object in the + // destination address space. + if (!Qualifiers::isAddressSpaceSupersetOf( + Constructor->getMethodQualifiers().getAddressSpace(), + CandidateSet.getDestAS())) { + Candidate.Viable = false; + Candidate.FailureKind = ovl_fail_object_addrspace_mismatch; + } } unsigned NumParams = Proto->getNumParams(); @@ -10392,9 +10401,12 @@ static void DiagnoseOpenCLExtensionDisabled(Sema &S, OverloadCandidate *Cand) { /// It would be great to be able to express per-candidate problems /// more richly for those diagnostic clients that cared, but we'd /// still have to be just as careful with the default diagnostics. +/// \param CtorDestAS Addr space of object being constructed (for ctor +/// candidates only). static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand, unsigned NumArgs, - bool TakingCandidateAddress) { + bool TakingCandidateAddress, + LangAS CtorDestAS = LangAS::Default) { FunctionDecl *Fn = Cand->Function; // Note deleted candidates, but only if they're viable. @@ -10432,6 +10444,16 @@ static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand, return; } + case ovl_fail_object_addrspace_mismatch: { + Qualifiers QualsForPrinting; + QualsForPrinting.setAddressSpace(CtorDestAS); + S.Diag(Fn->getLocation(), + diag::note_ovl_candidate_illegal_constructor_adrspace_mismatch) + << QualsForPrinting; + MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); + return; + } + case ovl_fail_trivial_conversion: case ovl_fail_bad_final_conversion: case ovl_fail_final_conversion_not_exact: @@ -10862,7 +10884,7 @@ void OverloadCandidateSet::NoteCandidates(Sema &S, ArrayRef<Expr *> Args, if (Cand->Function) NoteFunctionCandidate(S, Cand, Args.size(), - /*TakingCandidateAddress=*/false); + /*TakingCandidateAddress=*/false, DestAS); else if (Cand->IsSurrogate) NoteSurrogateCandidate(S, Cand); else { |