Index: clang/lib/Sema/SemaOverload.cpp =================================================================== --- clang/lib/Sema/SemaOverload.cpp +++ clang/lib/Sema/SemaOverload.cpp @@ -9534,7 +9534,7 @@ auto EmitThreshold = (S.getLangOpts().CUDAIsDevice && IsCallerImplicitHD && (IsCand1ImplicitHD || IsCand2ImplicitHD)) - ? Sema::CFP_HostDevice + ? Sema::CFP_Never : Sema::CFP_WrongSide; auto Cand1Emittable = P1 > EmitThreshold; auto Cand2Emittable = P2 > EmitThreshold; Index: clang/test/SemaCUDA/function-overload.cu =================================================================== --- clang/test/SemaCUDA/function-overload.cu +++ clang/test/SemaCUDA/function-overload.cu @@ -541,3 +541,51 @@ } }; } + +// Implicit HD candidate competes with device candidate. +// a and b have implicit HD copy ctor. In copy ctor of b, ctor of a is resolved. +// copy ctor of a should win over a(short), otherwise there will be ambiguity +// due to conversion operator. +namespace TestImplicitHDWithD { + struct a { + __attribute__((device)) a(short); + __attribute__((device)) operator unsigned() const; + __attribute__((device)) operator int() const; + }; + struct b { + a d; + }; + void f(b g) { b e = g; } +} + +// Implicit HD candidate competes with host candidate. +// a and b have implicit HD copy ctor. In copy ctor of b, ctor of a is resolved. +// copy ctor of a should win over a(short), otherwise there will be ambiguity +// due to conversion operator. +namespace TestImplicitHDWithH { + struct a { + a(short); + __attribute__((device)) operator unsigned() const; + __attribute__((device)) operator int() const; + }; + struct b { + a d; + }; + void f(b g) { b e = g; } +} + +// Implicit HD candidate comptes with HD candidate. +// a and b have implicit HD copy ctor. In copy ctor of b, ctor of a is resolved. +// copy ctor of a should win over a(short), otherwise there will be ambiguity +// due to conversion operator. +namespace TestImplicitHDWithHD { + struct a { + __attribute__((host,device)) a(short); + __attribute__((device)) operator unsigned() const; + __attribute__((device)) operator int() const; + }; + struct b { + a d; + }; + void f(b g) { b e = g; } +}