summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorAnastasia Stulova <anastasia.stulova@arm.com>2019-06-20 16:23:28 +0000
committerAnastasia Stulova <anastasia.stulova@arm.com>2019-06-20 16:23:28 +0000
commitc25ea86d43929c02dcc19512fb26a99ca256657d (patch)
tree0ad87beb7adde675054e9fa58282c99d0a0cfcc2 /clang/lib
parent1fffe8d6eede5afedb6da94443229657df724d22 (diff)
downloadbcm5719-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.cpp9
-rw-r--r--clang/lib/Sema/SemaInit.cpp2
-rw-r--r--clang/lib/Sema/SemaOverload.cpp26
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 {
OpenPOWER on IntegriCloud