aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaInit.cpp
diff options
context:
space:
mode:
authorYang Fan <nullptr.cpp@gmail.com>2021-01-04 17:36:58 +0800
committerYang Fan <nullptr.cpp@gmail.com>2021-01-06 10:05:40 +0800
commit74f93bc373d089e757bb65cf8b30b63a4eae8b69 (patch)
tree6e94d1bd564abf9d189c7a439bbe4b33ee89548a /clang/lib/Sema/SemaInit.cpp
parentf4bcbdf9cea16bf91ba342268f681de45e15733c (diff)
downloadllvm-74f93bc373d089e757bb65cf8b30b63a4eae8b69.zip
llvm-74f93bc373d089e757bb65cf8b30b63a4eae8b69.tar.gz
llvm-74f93bc373d089e757bb65cf8b30b63a4eae8b69.tar.bz2
[Sema] Fix deleted function problem in implicitly movable test
In implicitly movable test, a two-stage overload resolution is performed. If the first overload resolution selects a deleted function, Clang directly performs the second overload resolution, without checking whether the deleted function matches the additional criteria. This patch fixes the above problem. Reviewed By: Quuxplusone Differential Revision: https://reviews.llvm.org/D92936
Diffstat (limited to 'clang/lib/Sema/SemaInit.cpp')
-rw-r--r--clang/lib/Sema/SemaInit.cpp90
1 files changed, 56 insertions, 34 deletions
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 6d2e609..b5f31bf 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -4115,11 +4115,13 @@ static void TryConstructorInitialization(Sema &S,
IsListInit);
}
if (Result) {
- Sequence.SetOverloadFailure(IsListInit ?
- InitializationSequence::FK_ListConstructorOverloadFailed :
- InitializationSequence::FK_ConstructorOverloadFailed,
- Result);
- return;
+ Sequence.SetOverloadFailure(
+ IsListInit ? InitializationSequence::FK_ListConstructorOverloadFailed
+ : InitializationSequence::FK_ConstructorOverloadFailed,
+ Result);
+
+ if (Result != OR_Deleted)
+ return;
}
bool HadMultipleCandidates = (CandidateSet.size() > 1);
@@ -4140,31 +4142,45 @@ static void TryConstructorInitialization(Sema &S,
return;
}
- // C++11 [dcl.init]p6:
- // If a program calls for the default initialization of an object
- // of a const-qualified type T, T shall be a class type with a
- // user-provided default constructor.
- // C++ core issue 253 proposal:
- // If the implicit default constructor initializes all subobjects, no
- // initializer should be required.
- // The 253 proposal is for example needed to process libstdc++ headers in 5.x.
CXXConstructorDecl *CtorDecl = cast<CXXConstructorDecl>(Best->Function);
- if (Kind.getKind() == InitializationKind::IK_Default &&
- Entity.getType().isConstQualified()) {
- if (!CtorDecl->getParent()->allowConstDefaultInit()) {
- if (!maybeRecoverWithZeroInitialization(S, Sequence, Entity))
- Sequence.SetFailed(InitializationSequence::FK_DefaultInitOfConst);
+ if (Result != OR_Deleted) {
+ // C++11 [dcl.init]p6:
+ // If a program calls for the default initialization of an object
+ // of a const-qualified type T, T shall be a class type with a
+ // user-provided default constructor.
+ // C++ core issue 253 proposal:
+ // If the implicit default constructor initializes all subobjects, no
+ // initializer should be required.
+ // The 253 proposal is for example needed to process libstdc++ headers
+ // in 5.x.
+ if (Kind.getKind() == InitializationKind::IK_Default &&
+ Entity.getType().isConstQualified()) {
+ if (!CtorDecl->getParent()->allowConstDefaultInit()) {
+ if (!maybeRecoverWithZeroInitialization(S, Sequence, Entity))
+ Sequence.SetFailed(InitializationSequence::FK_DefaultInitOfConst);
+ return;
+ }
+ }
+
+ // C++11 [over.match.list]p1:
+ // In copy-list-initialization, if an explicit constructor is chosen, the
+ // initializer is ill-formed.
+ if (IsListInit && !Kind.AllowExplicit() && CtorDecl->isExplicit()) {
+ Sequence.SetFailed(InitializationSequence::FK_ExplicitConstructor);
return;
}
}
- // C++11 [over.match.list]p1:
- // In copy-list-initialization, if an explicit constructor is chosen, the
- // initializer is ill-formed.
- if (IsListInit && !Kind.AllowExplicit() && CtorDecl->isExplicit()) {
- Sequence.SetFailed(InitializationSequence::FK_ExplicitConstructor);
+ // [class.copy.elision]p3:
+ // In some copy-initialization contexts, a two-stage overload resolution
+ // is performed.
+ // If the first overload resolution selects a deleted function, we also
+ // need the initialization sequence to decide whether to perform the second
+ // overload resolution.
+ // For deleted functions in other contexts, there is no need to get the
+ // initialization sequence.
+ if (Result == OR_Deleted && Kind.getKind() != InitializationKind::IK_Copy)
return;
- }
// Add the constructor initialization step. Any cv-qualification conversion is
// subsumed by the initialization.
@@ -5258,9 +5274,17 @@ static void TryUserDefinedConversion(Sema &S,
if (OverloadingResult Result
= CandidateSet.BestViableFunction(S, DeclLoc, Best)) {
Sequence.SetOverloadFailure(
- InitializationSequence::FK_UserConversionOverloadFailed,
- Result);
- return;
+ InitializationSequence::FK_UserConversionOverloadFailed, Result);
+
+ // [class.copy.elision]p3:
+ // In some copy-initialization contexts, a two-stage overload resolution
+ // is performed.
+ // If the first overload resolution selects a deleted function, we also
+ // need the initialization sequence to decide whether to perform the second
+ // overload resolution.
+ if (!(Result == OR_Deleted &&
+ Kind.getKind() == InitializationKind::IK_Copy))
+ return;
}
FunctionDecl *Function = Best->Function;
@@ -5564,13 +5588,11 @@ static bool TryOCLZeroOpaqueTypeInitialization(Sema &S,
return false;
}
-InitializationSequence::InitializationSequence(Sema &S,
- const InitializedEntity &Entity,
- const InitializationKind &Kind,
- MultiExprArg Args,
- bool TopLevelOfInitList,
- bool TreatUnavailableAsInvalid)
- : FailedCandidateSet(Kind.getLocation(), OverloadCandidateSet::CSK_Normal) {
+InitializationSequence::InitializationSequence(
+ Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind,
+ MultiExprArg Args, bool TopLevelOfInitList, bool TreatUnavailableAsInvalid)
+ : FailedOverloadResult(OR_Success),
+ FailedCandidateSet(Kind.getLocation(), OverloadCandidateSet::CSK_Normal) {
InitializeFrom(S, Entity, Kind, Args, TopLevelOfInitList,
TreatUnavailableAsInvalid);
}