[clang] [Clang][Sema] Reject template arguments not equivalent to their copies (part of P2308R1) (PR #193754)
Yanzuo Liu via cfe-commits
cfe-commits at lists.llvm.org
Tue Apr 28 06:33:12 PDT 2026
================
@@ -7130,6 +7130,71 @@ static bool CheckTemplateArgumentPointerToMember(
return true;
}
+// P2308R1 C++26 [temp.arg.nontype]p4:
+// ... If, for the initialization from any candidate initializer,
+// - ...
+// - the initialization would cause P to not be
+// template-argument-equivalent ([temp.type]) to v,
+// the program is ill-formed.
+static bool CheckTemplateArgumentCopyEquivalence(Sema &S, NamedDecl *Param,
+ QualType ParamType,
+ const APValue &Value,
+ SourceLocation ArgLoc) {
+ assert(ParamType->isRecordType() && "no need to check copy equivalence");
+
+ if (ParamType->castAsCXXRecordDecl()->isTriviallyCopyTemplateParam())
+ return false;
+
+ SourceLocation ParamLoc = Param->getLocation();
+
+ // Instead of creating a variable (C++26 [temp.arg.nontype]p3),
+ // create a template parameter object to represent the candidate initializer.
+ // They are equivalent during creating a copy.
+ auto *CandidateInitializer =
+ S.BuildDeclRefExpr(S.Context.getTemplateParamObjectDecl(ParamType, Value),
+ ParamType.withConst(), VK_LValue, ArgLoc);
+ InitializationKind Kind = InitializationKind::CreateForInit(
+ ArgLoc, /*DirectInit=*/false, CandidateInitializer);
+ Expr *Inits[1] = {CandidateInitializer};
+ InitializedEntity Entity =
+ InitializedEntity::InitializeTemplateParameter(ParamType, Param);
+ InitializationSequence InitSeq(S, Entity, Kind, Inits);
+ ExprResult Result = InitSeq.Perform(S, Entity, Kind, Inits);
+ if (Result.isInvalid())
+ return S.Diag(ParamLoc, diag::note_template_arg_requires_copy);
+
+ if (cast<CXXConstructExpr>(Result.get())->getConstructor()->isTrivial()) {
+ ParamType->castAsCXXRecordDecl()->setTriviallyCopyTemplateParam();
+ return false;
+ }
----------------
zwuis wrote:
AFAIK, to deal with `explicit`, we need to perform name lookup, and traverse all constructors to find the copy constructor.
Please let me know whether you are happy with it or not.
https://github.com/llvm/llvm-project/pull/193754
More information about the cfe-commits
mailing list