llvm / llvm-project

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

Compilation error #47742

Open silver-popov opened 3 years ago

silver-popov commented 3 years ago
Bugzilla Link 48398
Version 10.0
OS Windows NT
Attachments The file which demonstrates the compilation error.
CC @DougGregor,@zygoloid

Extended Description

Hello

It seems like a compiler bug. I detected it during the compilation of MSVC runtime sources with CLang. For your convenience, I have created a file which demonstrates the problem. See the attached "error.cpp".

Best wishes, Igor Popov

wheatman commented 1 year ago

confirming that this behavior still happens in post 16 trunk(8a62d6ba7edc3a7d397e52884a9ce63b4e579ae1) https://godbolt.org/z/8PP41r8oc

code

// compile with  -target i686-pc-win32
typedef void (__stdcall* _tls_callback_type)(void*, unsigned long, void*);

extern "C" _tls_callback_type const* __cdecl __scrt_get_dyn_tls_init_callback ();

/* Next line causes the compilation error:
error: cannot initialize a variable of type 
'const _tls_callback_type *const' (aka 'void (*const *const)(void *, unsigned long, void *) __attribute__((stdcall))')
with an rvalue of type 'const _tls_callback_type * __attribute__((cdecl))'
*/
_tls_callback_type const* const tls_init_callback = __scrt_get_dyn_tls_init_callback ();

error

clang++: warning: argument unused during compilation: '--gcc-toolchain=/opt/compiler-explorer/gcc-snapshot' [-Wunused-command-line-argument]
<source>:11:33: error: cannot initialize a variable of type 'const _tls_callback_type *const' (aka 'void (*const *const)(void *, unsigned long, void *) __attribute__((stdcall))') with an rvalue of type 'const _tls_callback_type * __attribute__((cdecl))'
   11 | _tls_callback_type const* const tls_init_callback = __scrt_get_dyn_tls_init_callback ();
      |                                 ^                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
Compiler returned: 1
llvmbot commented 1 year ago

@llvm/issue-subscribers-clang-frontend

shafik commented 1 year ago

CC @AaronBallman

AaronBallman commented 1 year ago

We seem to be associating the __cdecl qualifier with the return type and not the function declaration. You can work around this with code like extern "C" _tls_callback_type const* __scrt_get_dyn_tls_init_callback () __attribute__((cdecl)); which isn't great if you're aiming for source compatibility with MSVC.

extern "C" _tls_callback_type const* __scrt_get_dyn_tls_init_callback () __attribute__((cdecl)); gives:

-LinkageSpecDecl <line:4:1, col:96> col:8 C
| `-FunctionDecl <col:12, col:96> col:39 used __scrt_get_dyn_tls_init_callback 'const _tls_callback_type *() __attribute__((cdecl))':'const _tls_callback_type *()'

whereas the original code: extern "C" _tls_callback_type const* __cdecl __scrt_get_dyn_tls_init_callback () gives:

|-LinkageSpecDecl <line:4:1, col:81> col:8 C
| `-FunctionDecl <col:12, col:81> col:47 used __scrt_get_dyn_tls_init_callback 'const _tls_callback_type *() __attribute__((cdecl))'