================
@@ -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
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to