[clang] [Clang][Sema] Reject template arguments not equivalent to their copies (part of P2308R1) (PR #193754)
Corentin Jabot via cfe-commits
cfe-commits at lists.llvm.org
Thu Apr 30 02:40:28 PDT 2026
================
@@ -7130,6 +7130,97 @@ 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");
+
+ // Fast path. Try to find the copy constructor which will be selected by
+ // overload resolution. Trivial copy constructor performs per-element copy.
+ if (auto *CXXRecord = ParamType->castAsCXXRecordDecl();
+ !CXXRecord->hasUserDeclaredConstructor()) {
+
+ if (CXXRecord->hasTrivialCopyConstructor() &&
+ CXXRecord->implicitCopyConstructorHasConstParam() &&
+ !CXXRecord->needsOverloadResolutionForCopyConstructor())
+ return false;
+
+ } else {
+ // If there is a copy constructor with const parameter and without explicit,
+ // it should be selected by overload resolution.
+ CXXConstructorDecl *CopyCtor = nullptr;
+
+ // If there is trailing requires clause, let overload resolution handle it.
+ bool FindCopyCtorWithTrailingRequiresClause = false;
----------------
cor3ntin wrote:
You can use `Ctor->isIneligibleOrNotSelected`.
I think Overload resolution is only needed in cases where the constructor selected for copy is itself a template
ie
````cpp
struct S {
constexpr S(auto&&);
};
https://github.com/llvm/llvm-project/pull/193754
More information about the cfe-commits
mailing list