[clang] [Clang] Reapply CWG2369 "Ordering between constraints and substitution" (PR #122423)
Younan Zhang via cfe-commits
cfe-commits at lists.llvm.org
Fri Apr 25 05:11:13 PDT 2025
================
@@ -8058,6 +8061,46 @@ bool Sema::CheckNonDependentConversions(
}
}
+ // A speculative workaround for self-dependent constraint bugs that manifest
+ // after CWG2369.
+ // FIXME: Add references to the standard once P3606 is adopted.
+ auto MaybeInvolveUserDefinedConversion = [&](QualType ParmType,
+ QualType ArgType) {
+ ParmType = ParmType.getNonReferenceType();
+ ArgType = ArgType.getNonReferenceType();
+ bool PointerConv = ParmType->isPointerType() && ArgType->isPointerType();
+ if (PointerConv) {
+ ParmType = ParmType->getPointeeType();
+ ArgType = ArgType->getPointeeType();
+ }
+
+ if (auto *RT = ParmType->getAs<RecordType>())
+ if (auto *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
+ RD && RD->hasDefinition()) {
+ if (llvm::any_of(LookupConstructors(RD), [](NamedDecl *ND) {
+ auto Info = getConstructorInfo(ND);
+ if (!Info)
+ return false;
+ CXXConstructorDecl *Ctor = Info.Constructor;
+ /// isConvertingConstructor takes copy/move constructors into
+ /// account!
+ return !Ctor->isCopyOrMoveConstructor() &&
+ Ctor->isConvertingConstructor(
+ /*AllowExplicit=*/true);
+ }))
+ return true;
+ }
----------------
zyn0217 wrote:
For the `{foo,bar}_tag` issue, GCC still rejects it if the ParamType is not an aggregation:
```cpp
struct bar_tag {
bar_tag() {} // user-defined constructor
};
struct foo_tag {
};
template <class T>
concept fooable = requires(T it) {
invoke_tag(foo_tag{}, it); // <-- here
};
template <class T> auto invoke_tag(foo_tag, T in) { return in; }
template <fooable T> auto invoke_tag(bar_tag, T it) { return it; }
int main() {
// Neither line below compiles in GCC 11, independently of the other
return invoke_tag(foo_tag{}, 2) + invoke_tag(bar_tag{}, 2);
}
```
https://godbolt.org/z/bYcve4xqb
While checking user-defined conversions helps, we still end up with self-dependent diagnostics if `bar_tag` includes a conversion constructor:
```cpp
struct bar_tag {
bar_tag(int) {}
};
```
https://github.com/llvm/llvm-project/pull/122423
More information about the cfe-commits
mailing list