================
@@ -218,9 +218,31 @@ buildDeductionGuide(Sema &SemaRef, TemplateDecl 
*OriginalTemplate,
       TInfo->getTypeLoc().castAs<FunctionProtoTypeLoc>().getParams();
 
   // Build the implicit deduction guide template.
+  QualType GuideType = TInfo->getType();
+
+  // In CUDA/HIP mode, avoid creating duplicate implicit deduction guides with
+  // identical function types. This can happen when there are separate
+  // __host__ and __device__ constructors with the same signature; each would
+  // otherwise synthesize its own implicit deduction guide, leading to
+  // ambiguous CTAD purely due to target attributes. For such cases we keep the
+  // first guide we created and skip building another one.
+  if (IsImplicit && Ctor && SemaRef.getLangOpts().CUDA)
+    for (NamedDecl *Existing : DC->lookup(DeductionGuideName)) {
+      auto *ExistingFT = dyn_cast<FunctionTemplateDecl>(Existing);
+      auto *ExistingGuide =
+          ExistingFT
+              ? dyn_cast<CXXDeductionGuideDecl>(ExistingFT->getTemplatedDecl())
+              : dyn_cast<CXXDeductionGuideDecl>(Existing);
+      if (!ExistingGuide)
+        continue;
+
+      if (SemaRef.Context.hasSameType(ExistingGuide->getType(), GuideType))
+        return Existing;
+    }
----------------
cor3ntin wrote:

I don't think this is sufficient, 

Consider


```cpp
template <typename T>
struct S {
  S();
  __device__ S() requires true;
};
```

I think you want to check that `IsOverload(Ctr, ExistingGuide, 
/*UseMemberUsingDeclRules*/false, /*ConsiderCudaAttrs=*/true)` is false and 
`IsOverload(Ctr, ExistingGuide, /*UseMemberUsingDeclRules*/false, 
/*ConsiderCudaAttrs=*/false)` is true, or something along these line.

https://github.com/llvm/llvm-project/pull/168711
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to