shafik updated this revision to Diff 514091.
shafik marked 3 inline comments as done.
shafik added a comment.
- Fix up A3 test to be less malformed
- Fix other test so we confirm we are attempting to call the right contructor
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D148474/new/
https://reviews.llvm.org/D148474
Files:
clang/lib/Sema/SemaInit.cpp
clang/lib/Sema/SemaTemplateInstantiate.cpp
clang/test/SemaCXX/cxx1z-copy-omission.cpp
Index: clang/test/SemaCXX/cxx1z-copy-omission.cpp
===================================================================
--- clang/test/SemaCXX/cxx1z-copy-omission.cpp
+++ clang/test/SemaCXX/cxx1z-copy-omission.cpp
@@ -171,3 +171,30 @@
Foo f(Derived d) { return d; } // expected-error {{invokes a deleted function}}
Foo g(Derived d) { return Foo(d); } // ok, calls constructor
}
+
+// Make sure we don't consider conversion functions for guaranteed copy elision
+namespace GH39319 {
+struct A {
+ A();
+ A(const A&) = delete; // expected-note {{'A' has been explicitly marked deleted here}}
+};
+struct B {
+ operator A();
+} C;
+A::A() : A(C) {} // expected-error {{call to deleted constructor of}}
+
+struct A2 {
+ struct B2 {
+ operator A2();
+ };
+ A2() : A2(B2()) {} // expected-error {{call to deleted constructor of}}
+ A2(const A2&) = delete; // expected-note {{'A2' has been explicitly marked deleted here}}
+};
+
+template<typename A3>
+class B3 : A3 {
+ template<bool = C3<B3>()> // expected-warning 2{{use of function template name with no prior declaration in function call with explicit}}
+ B3();
+}; B3(); // expected-error {{deduction guide declaration without trailing return type}} \
+ // expected-note {{in instantiation of template class}}
+}
Index: clang/lib/Sema/SemaTemplateInstantiate.cpp
===================================================================
--- clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -740,6 +740,10 @@
Diags.Report(Active->PointOfInstantiation,
diag::note_template_nsdmi_here)
<< FD << Active->InstantiationRange;
+ } else if (ClassTemplateDecl *CTD = dyn_cast<ClassTemplateDecl>(D)) {
+ Diags.Report(Active->PointOfInstantiation,
+ diag::note_template_class_instantiation_here)
+ << CTD << Active->InstantiationRange;
} else {
Diags.Report(Active->PointOfInstantiation,
diag::note_template_type_alias_instantiation_here)
Index: clang/lib/Sema/SemaInit.cpp
===================================================================
--- clang/lib/Sema/SemaInit.cpp
+++ clang/lib/Sema/SemaInit.cpp
@@ -3981,16 +3981,13 @@
return Ctx.hasSameUnqualifiedType(ParmT, ClassT);
}
-static OverloadingResult
-ResolveConstructorOverload(Sema &S, SourceLocation DeclLoc,
- MultiExprArg Args,
- OverloadCandidateSet &CandidateSet,
- QualType DestType,
- DeclContext::lookup_result Ctors,
- OverloadCandidateSet::iterator &Best,
- bool CopyInitializing, bool AllowExplicit,
- bool OnlyListConstructors, bool IsListInit,
- bool SecondStepOfCopyInit = false) {
+static OverloadingResult ResolveConstructorOverload(
+ Sema &S, SourceLocation DeclLoc, MultiExprArg Args,
+ OverloadCandidateSet &CandidateSet, QualType DestType,
+ DeclContext::lookup_result Ctors, OverloadCandidateSet::iterator &Best,
+ bool CopyInitializing, bool AllowExplicit, bool OnlyListConstructors,
+ bool IsListInit, bool RequireActualConstructor,
+ bool SecondStepOfCopyInit = false) {
CandidateSet.clear(OverloadCandidateSet::CSK_InitByConstructor);
CandidateSet.setDestAS(DestType.getQualifiers().getAddressSpace());
@@ -4053,7 +4050,7 @@
// Note: SecondStepOfCopyInit is only ever true in this case when
// evaluating whether to produce a C++98 compatibility warning.
if (S.getLangOpts().CPlusPlus17 && Args.size() == 1 &&
- !SecondStepOfCopyInit) {
+ !RequireActualConstructor && !SecondStepOfCopyInit) {
Expr *Initializer = Args[0];
auto *SourceRD = Initializer->getType()->getAsCXXRecordDecl();
if (SourceRD && S.isCompleteType(DeclLoc, Initializer->getType())) {
@@ -4121,6 +4118,12 @@
return;
}
+ bool RequireActualConstructor =
+ !(Entity.getKind() != InitializedEntity::EK_Base &&
+ Entity.getKind() != InitializedEntity::EK_Delegating &&
+ Entity.getKind() !=
+ InitializedEntity::EK_LambdaToBlockConversionBlockElement);
+
// C++17 [dcl.init]p17:
// - If the initializer expression is a prvalue and the cv-unqualified
// version of the source type is the same class as the class of the
@@ -4130,11 +4133,7 @@
// class or delegating to another constructor from a mem-initializer.
// ObjC++: Lambda captured by the block in the lambda to block conversion
// should avoid copy elision.
- if (S.getLangOpts().CPlusPlus17 &&
- Entity.getKind() != InitializedEntity::EK_Base &&
- Entity.getKind() != InitializedEntity::EK_Delegating &&
- Entity.getKind() !=
- InitializedEntity::EK_LambdaToBlockConversionBlockElement &&
+ if (S.getLangOpts().CPlusPlus17 && !RequireActualConstructor &&
UnwrappedArgs.size() == 1 && UnwrappedArgs[0]->isPRValue() &&
S.Context.hasSameUnqualifiedType(UnwrappedArgs[0]->getType(), DestType)) {
// Convert qualifications if necessary.
@@ -4182,11 +4181,10 @@
// If the initializer list has no elements and T has a default constructor,
// the first phase is omitted.
if (!(UnwrappedArgs.empty() && S.LookupDefaultConstructor(DestRecordDecl)))
- Result = ResolveConstructorOverload(S, Kind.getLocation(), Args,
- CandidateSet, DestType, Ctors, Best,
- CopyInitialization, AllowExplicit,
- /*OnlyListConstructors=*/true,
- IsListInit);
+ Result = ResolveConstructorOverload(
+ S, Kind.getLocation(), Args, CandidateSet, DestType, Ctors, Best,
+ CopyInitialization, AllowExplicit,
+ /*OnlyListConstructors=*/true, IsListInit, RequireActualConstructor);
}
// C++11 [over.match.list]p1:
@@ -4196,11 +4194,10 @@
// elements of the initializer list.
if (Result == OR_No_Viable_Function) {
AsInitializerList = false;
- Result = ResolveConstructorOverload(S, Kind.getLocation(), UnwrappedArgs,
- CandidateSet, DestType, Ctors, Best,
- CopyInitialization, AllowExplicit,
- /*OnlyListConstructors=*/false,
- IsListInit);
+ Result = ResolveConstructorOverload(
+ S, Kind.getLocation(), UnwrappedArgs, CandidateSet, DestType, Ctors,
+ Best, CopyInitialization, AllowExplicit,
+ /*OnlyListConstructors=*/false, IsListInit, RequireActualConstructor);
}
if (Result) {
Sequence.SetOverloadFailure(
@@ -6608,6 +6605,7 @@
S, Loc, CurInitExpr, CandidateSet, T, Ctors, Best,
/*CopyInitializing=*/false, /*AllowExplicit=*/true,
/*OnlyListConstructors=*/false, /*IsListInit=*/false,
+ /*RequireActualConstructor=*/false,
/*SecondStepOfCopyInit=*/true)) {
case OR_Success:
break;
@@ -6753,6 +6751,7 @@
S, Loc, CurInitExpr, CandidateSet, CurInitExpr->getType(), Ctors, Best,
/*CopyInitializing=*/false, /*AllowExplicit=*/true,
/*OnlyListConstructors=*/false, /*IsListInit=*/false,
+ /*RequireActualConstructor=*/false,
/*SecondStepOfCopyInit=*/true);
PartialDiagnostic Diag = S.PDiag(diag::warn_cxx98_compat_temp_copy)
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits