[clang] [CUDA][HIP] Fix CTAD for host/device constructors (PR #168711)

Yaxun Liu via cfe-commits cfe-commits at lists.llvm.org
Mon Dec 1 07:32:04 PST 2025


================
@@ -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;
+    }
----------------
yxsamliu wrote:

I tried your suggested approach, but IsOverload doesn't treat constraints as part of the function signature. It can distinguish differences in CUDA target attributes, but not differences in requires-clauses: two constructors with identical parameter types but different constraints both look the same to IsOverload, regardless of the ConsiderCudaAttrs flag. Using only that check would therefore merge deduction guides that differ only by constraints, which is precisely what we need to avoid. I took another approach that uses IsOverload to ignore CUDA attrs and then separately compares associated constraints with AreConstraintExpressionsEqual, so we deduplicate only when both signature and constraints match.


https://github.com/llvm/llvm-project/pull/168711


More information about the cfe-commits mailing list