llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.12k stars 12.01k forks source link

[C++4OpenCL] Constructor address space overloading not prioritizing specific address spaces #49673

Open OleStrohm opened 3 years ago

OleStrohm commented 3 years ago
Bugzilla Link 50329
Version trunk
OS Linux
CC @AnastasiaStulova

Extended Description

struct Foo { int x;

Foo() __generic = default;
Foo() __private = default;

};

kernel void k() { __private Foo f; }

https://godbolt.org/z/nGrdPacWY

This gives the error: call to constructor of '__private Foo' is ambiguous

But since private is more specific than generic this should choose Foo() __private as it is the most specific constructor, rather than consider them equally specific.

AnastasiaStulova commented 3 years ago

I was checking the other special members and for dtor there seem to be another issue

struct Foo { int x;

 ~Foo() __generic;
 ~Foo() __private;

};

kernel void k() { __private Foo f; f.~Foo(); }

The overload resolution works fine but the automatic destructor is selected with generic address space instead of private.

call spir_func void @​_ZN3FooD1Ev(%struct.Foo nonnull dereferenceable(4) %1) #​3, !dbg !​24 %2 = addrspacecast %struct.Foo %1 to %struct.Foo addrspace(4), !dbg !​25 call spir_func void @​_ZNU3AS43FooD1Ev(%struct.Foo addrspace(4) nonnull dereferenceable(4) %2) #​3, !dbg !​25

AnastasiaStulova commented 3 years ago

It seems like it works for other member functions but not for the special members e.g ctors

struct Foo { int x;

void foo() __generic;
void foo() __private;

};

kernel void k() { __private Foo f; f.foo(); }

Perhaps there is a different logic for the overload selection in the special members.

HoBoIs commented 1 year ago

The originally found bug was solved in clang 13.0.0 https://godbolt.org/z/7ndacbbvq But the we still call the generic destructor in implicit destructor calls. https://godbolt.org/z/b5qzeoGKa