Looks like my r160121 change has regressed: $ cat cdecl.cpp void foo(); void __cdecl foo(); $ clang++ -c cdecl.cpp && echo "OK" OK $ clang++ -Xclang -cxx-abi -Xclang microsoft -c cdecl.cpp && echo "OK" cdecl.cpp:2:14: error: function declared 'cdecl' here was previously declared without calling convention void __cdecl foo(); ^ cdecl.cpp:1:6: note: previous declaration is here void foo(); ^ 1 error generated. $ cl -nologo -c cdecl.cpp && echo "OK" cdecl.cpp OK
Any suggestions? It looks like getCanonicalCallConv should know whether it's called for a free function or a CXX method :(
Let's not go down that road. This needs to be handled in the function-merging logic: it's okay to merge a function with CC_Default with a function with an explicit CC if the default CC for that kind of function is the same as the explicit CC. This is the code at SemaDecl.cpp:1962. If you do this right, you should also get the analogous case with _thiscall on a method (admittedly, it's harder to redeclare those).
> Let's not go down that road. > > This needs to be handled in the function-merging logic: it's okay to merge a > function with CC_Default with a function with an explicit CC if the default CC > for that kind of function is the same as the explicit CC. This is the code at > SemaDecl.cpp:1962. OK, I got some code like this working. Will send it for review when I'm sure what I'm doing :) But currently it assumes CC_Default == CC_C which is might not be true for free functions on some archs (right?). > If you do this right, you should also get the analogous > case with _thiscall on a method (admittedly, it's harder to redeclare those). Not that hard :) class A { public: void bar(); }; void __thiscall A::bar() {} Working on this...
Patch sent out for review a few days ago, assigning to myself.
One more thing to fix: $ cat cdecl_pointer.cpp typedef void (__cdecl * PTR)(); void foo() {} void bar(PTR h) {} int main() { bar(&foo); } $ clang -c cdecl_pointer.cpp && echo "OK" OK $ clang -c -Xclang -cxx-abi -Xclang microsoft cdecl_pointer.cpp && echo "OK" || echo "FAIL" cdecl_pointer.cpp:8:3: error: no matching function for call to 'bar' bar(&foo); ^~~ cdecl_pointer.cpp:5:6: note: candidate function not viable: no known conversion from 'void (*)()' to 'PTR' (aka 'void (*)() __attribute__((cdecl))') for 1st argument void bar(PTR h) {} ^ 1 error generated. FAIL
comment #5 repro is not PR13457
s/not/now
Fixed as of r162639. Good job, Timur.