llvm / llvm-project

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

[Clang-17][C++20 Modules] Different definitions of same functions in different modules #63796

Open 24bit-xjkp opened 1 year ago

24bit-xjkp commented 1 year ago

I use Clang 17 with target of x86_64-w64-mingw32 to compile std header units. But I get errors blow.

In module 'D:/Tools/gcc/include/c++/14.0.0/random':
D:/Tools/gcc/include/sec_api/stdio_s.h:309:27: error: 'sprintf_s' has different definitions in different modules; definition in module 'D:/Tools/gcc/include/c++/14.0.0/random' first difference is function body
  309 |   __mingw_ovr int __cdecl sprintf_s(char *_DstBuf, size_t _DstSize, const char *_Format, ...)
      |   ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  310 |   {
      |   ~
  311 |     __builtin_va_list _ArgList;
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  312 |     int _Ret;
      |     ~~~~~~~~~
  313 |     __builtin_va_start(_ArgList, _Format);
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  314 |     _Ret = _vsprintf_s_l(_DstBuf, _DstSize, _Format, NULL, _ArgList);
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  315 |     __builtin_va_end(_ArgList);
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  316 |     return _Ret;
      |     ~~~~~~~~~~~~
  317 |   }
      |   ~
D:/Tools/gcc/include/sec_api/stdio_s.h:309:27: note: but in 'C:\Users\22835\AppData\Local\.xmake\packages\b\benchmark\1.7.0\ef2ea2997db34a0cb9be0597c54ddf80\include/benchmark/benchmark.h' found a different body
  309 |   __mingw_ovr int __cdecl sprintf_s(char *_DstBuf, size_t _DstSize, const char *_Format, ...)
      |   ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  310 |   {
      |   ~
  311 |     __builtin_va_list _ArgList;
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  312 |     int _Ret;
      |     ~~~~~~~~~
  313 |     __builtin_va_start(_ArgList, _Format);
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  314 |     _Ret = _vsprintf_s_l(_DstBuf, _DstSize, _Format, NULL, _ArgList);
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  315 |     __builtin_va_end(_ArgList);
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  316 |     return _Ret;
      |     ~~~~~~~~~~~~
  317 |   }
      |   ~
In module 'D:/Tools/gcc/include/c++/14.0.0/random':
D:/Tools/gcc/include/sec_api/stdio_s.h:296:27: error: 'vsprintf_s' has different definitions in different modules; definition in module 'D:/Tools/gcc/include/c++/14.0.0/random' first difference is function body
  296 |   __mingw_ovr int __cdecl vsprintf_s(char *_DstBuf, size_t _Size, const char *_Format, va_list _ArgList)
      |   ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  297 |   {
      |   ~
  298 |     return _vsprintf_s_l(_DstBuf, _Size, _Format, NULL, _ArgList);
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  299 |   }
      |   ~
D:/Tools/gcc/include/sec_api/stdio_s.h:296:27: note: but in 'C:\Users\22835\AppData\Local\.xmake\packages\b\benchmark\1.7.0\ef2ea2997db34a0cb9be0597c54ddf80\include/benchmark/benchmark.h' found a different body
  296 |   __mingw_ovr int __cdecl vsprintf_s(char *_DstBuf, size_t _Size, const char *_Format, va_list _ArgList)
      |   ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  297 |   {
      |   ~
  298 |     return _vsprintf_s_l(_DstBuf, _Size, _Format, NULL, _ArgList);
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  299 |   }
      |   ~
9 warnings and 2 errors generated.

Use MSVC STL will also casue errors like these. The definitions in different modules are same, so it should not cause an error. I can use MSVC or GCC to compile the code.

24bit-xjkp commented 1 year ago

clang version 17.0.0 (https://github.com/llvm/llvm-project.git 9da4b6db9b3c27ee5864b6257084f6a9974a89d4) Target: x86_64-w64-windows-gnu Thread model: posix

ChuanqiXu9 commented 1 year ago

Thanks for reporting this. It is better to report a reduced minimal example with the corresponding command line options. https://github.com/llvm/llvm-project/issues/61360 is a pretty good example.

llvmbot commented 1 year ago

@llvm/issue-subscribers-clang-modules

24bit-xjkp commented 1 year ago

Build Options

  1. clang++ -Qunused-arguments -m64 -g -std=c++23 -DUNICODE -D_UNICODE -D_DLL -DDEBUG -D_DEBUG -fexceptions -fcxx-exceptions -march=native -c -Wno-everything -o cstdio.pcm -x c++-system-header cstdio
  2. clang++ -Qunused-arguments -m64 -g -std=c++23 -DUNICODE -D_UNICODE -D_DLL -DDEBUG -D_DEBUG -fexceptions -fcxx-exceptions -march=native -c -Wno-everything -o iostream.pcm -x c++-system-header iostream
  3. clang++ -Qunused-arguments -m64 -g -std=c++23 -DUNICODE -D_UNICODE -D_DLL -DDEBUG -D_DEBUG -fexceptions -fcxx-exceptions -march=native -c -Wno-everything -o random.pcm -x c++-system-header random
  4. clang++ -Qunused-arguments -m64 -g -std=c++23 -DUNICODE -D_UNICODE -D_DLL -DDEBUG -D_DEBUG -fexceptions -fcxx-exceptions -march=native -c -Wno-everything -o sstream.pcm -x c++-system-header sstream
  5. clang++ -Qunused-arguments -m64 -g -std=c++23 -DUNICODE -D_UNICODE -D_DLL -DDEBUG -D_DEBUG -fexceptions -fcxx-exceptions -march=native -c -Wextra -Wall -march=native -fmodule-file=iostream.pcm -fmodule-file=random.pcm -fmodule-file=cstdio.pcm -fmodule-file=sstream.pcm -o test.cpp.o test.cpp

Errors

test.cpp:1:4: warning: the implementation of header units is in an experimental phase [-Wexperimental-header-units]
    1 | <U+FEFF>import <cstdio>;
      |         ^
test.cpp:2:1: warning: the implementation of header units is in an experimental phase [-Wexperimental-header-units]
    2 | import <iostream>;
      | ^
test.cpp:3:1: warning: the implementation of header units is in an experimental phase [-Wexperimental-header-units]
    3 | import <random>;
      | ^
test.cpp:4:1: warning: the implementation of header units is in an experimental phase [-Wexperimental-header-units]
    4 | import <sstream>;
      | ^
In module 'D:/Tools/gcc/include/c++/14.0.0/random':
D:/Tools/gcc/include/sec_api/stdio_s.h:309:27: error: 'sprintf_s' has different definitions in different modules; definition in module 'D:/Tools/gcc/include/c++/14.0.0/random'
      first difference is function body
  309 |   __mingw_ovr int __cdecl sprintf_s(char *_DstBuf, size_t _DstSize, const char *_Format, ...)
      |   ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  310 |   {
      |   ~
  311 |     __builtin_va_list _ArgList;
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  312 |     int _Ret;
      |     ~~~~~~~~~
  313 |     __builtin_va_start(_ArgList, _Format);
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  314 |     _Ret = _vsprintf_s_l(_DstBuf, _DstSize, _Format, NULL, _ArgList);
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  315 |     __builtin_va_end(_ArgList);
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  316 |     return _Ret;
      |     ~~~~~~~~~~~~
  317 |   }
      |   ~
D:/Tools/gcc/include/sec_api/stdio_s.h:309:27: note: but in 'D:/Tools/gcc/include/c++/14.0.0/iostream' found a different body
  309 |   __mingw_ovr int __cdecl sprintf_s(char *_DstBuf, size_t _DstSize, const char *_Format, ...)
      |   ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  310 |   {
      |   ~
  311 |     __builtin_va_list _ArgList;
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  312 |     int _Ret;
      |     ~~~~~~~~~
  313 |     __builtin_va_start(_ArgList, _Format);
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  314 |     _Ret = _vsprintf_s_l(_DstBuf, _DstSize, _Format, NULL, _ArgList);
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  315 |     __builtin_va_end(_ArgList);
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  316 |     return _Ret;
      |     ~~~~~~~~~~~~
  317 |   }
      |   ~
In module 'D:/Tools/gcc/include/c++/14.0.0/cstdio':
D:/Tools/gcc/include/sec_api/stdio_s.h:309:27: error: 'sprintf_s' has different definitions in different modules; definition in module 'D:/Tools/gcc/include/c++/14.0.0/cstdio'
      first difference is function body
  309 |   __mingw_ovr int __cdecl sprintf_s(char *_DstBuf, size_t _DstSize, const char *_Format, ...)
      |   ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  310 |   {
      |   ~
  311 |     __builtin_va_list _ArgList;
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  312 |     int _Ret;
      |     ~~~~~~~~~
  313 |     __builtin_va_start(_ArgList, _Format);
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  314 |     _Ret = _vsprintf_s_l(_DstBuf, _DstSize, _Format, NULL, _ArgList);
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  315 |     __builtin_va_end(_ArgList);
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  316 |     return _Ret;
      |     ~~~~~~~~~~~~
  317 |   }
      |   ~
D:/Tools/gcc/include/sec_api/stdio_s.h:309:27: note: but in 'D:/Tools/gcc/include/c++/14.0.0/iostream' found a different body
  309 |   __mingw_ovr int __cdecl sprintf_s(char *_DstBuf, size_t _DstSize, const char *_Format, ...)
      |   ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  310 |   {
      |   ~
  311 |     __builtin_va_list _ArgList;
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  312 |     int _Ret;
      |     ~~~~~~~~~
  313 |     __builtin_va_start(_ArgList, _Format);
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  314 |     _Ret = _vsprintf_s_l(_DstBuf, _DstSize, _Format, NULL, _ArgList);
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  315 |     __builtin_va_end(_ArgList);
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  316 |     return _Ret;
      |     ~~~~~~~~~~~~
  317 |   }
      |   ~
In module 'D:/Tools/gcc/include/c++/14.0.0/random':
D:/Tools/gcc/include/sec_api/stdio_s.h:296:27: error: 'vsprintf_s' has different definitions in different modules; definition in module 'D:/Tools/gcc/include/c++/14.0.0/random'
      first difference is function body
  296 |   __mingw_ovr int __cdecl vsprintf_s(char *_DstBuf, size_t _Size, const char *_Format, va_list _ArgList)
      |   ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  297 |   {
      |   ~
  298 |     return _vsprintf_s_l(_DstBuf, _Size, _Format, NULL, _ArgList);
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  299 |   }
      |   ~
D:/Tools/gcc/include/sec_api/stdio_s.h:296:27: note: but in 'D:/Tools/gcc/include/c++/14.0.0/iostream' found a different body
  296 |   __mingw_ovr int __cdecl vsprintf_s(char *_DstBuf, size_t _Size, const char *_Format, va_list _ArgList)
      |   ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  297 |   {
      |   ~
  298 |     return _vsprintf_s_l(_DstBuf, _Size, _Format, NULL, _ArgList);
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  299 |   }
      |   ~
In module 'D:/Tools/gcc/include/c++/14.0.0/cstdio':
D:/Tools/gcc/include/sec_api/stdio_s.h:296:27: error: 'vsprintf_s' has different definitions in different modules; definition in module 'D:/Tools/gcc/include/c++/14.0.0/cstdio'
      first difference is function body
  296 |   __mingw_ovr int __cdecl vsprintf_s(char *_DstBuf, size_t _Size, const char *_Format, va_list _ArgList)
      |   ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  297 |   {
      |   ~
  298 |     return _vsprintf_s_l(_DstBuf, _Size, _Format, NULL, _ArgList);
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  299 |   }
      |   ~
D:/Tools/gcc/include/sec_api/stdio_s.h:296:27: note: but in 'D:/Tools/gcc/include/c++/14.0.0/iostream' found a different body
  296 |   __mingw_ovr int __cdecl vsprintf_s(char *_DstBuf, size_t _Size, const char *_Format, va_list _ArgList)
      |   ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  297 |   {
      |   ~
  298 |     return _vsprintf_s_l(_DstBuf, _Size, _Format, NULL, _ArgList);
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  299 |   }
      |   ~
4 warnings and 4 errors generated.

Files

Here are my test file, some libstdc++ headers and BMI files. test.zip

Other information

g++ version

Using built-in specs.
COLLECT_GCC=D:\Tools\gcc\bin\g++.exe
COLLECT_LTO_WRAPPER=D:/Tools/gcc/bin/../libexec/gcc/x86_64-w64-mingw32/14.0.0/lto-wrapper.exe
Target: x86_64-w64-mingw32
Configured with: ../configure --disable-werror --enable-multilib --enable-threads=win32 --disable-sjlj-exceptions --prefix=/home/luo/mingw_native --target=x86_64-w64-mingw32 --host=x86_64-w64-mingw32 --enable-languages=c,c++ --enable-nls
Thread model: win32
Supported LTO compression algorithms: zlib
gcc version 14.0.0 20230709 (experimental) (GCC)

clang++ version

clang version 17.0.0 (https://github.com/llvm/llvm-project.git 9da4b6db9b3c27ee5864b6257084f6a9974a89d4)
Target: x86_64-w64-windows-gnu
Thread model: posix
InstalledDir: D:/Tools/clang/bin

Hope the information will help you solve the problem.

davidstone commented 1 year ago

This looks like a duplicate of https://github.com/llvm/llvm-project/issues/60027

ChuanqiXu9 commented 1 year ago

This looks like a duplicate of #60027

As I explained in #60027, I prefer such standalone issues instead of a merged one. Since we probably can't fix them in one shot.

koplas commented 12 months ago

@2283572185 Your minimal reproducer works for me on Linux with clang 18 (b3d454950c4d05a179e0d584ca482af97704f19b) and clang 16.06, if you change sprintf_s to sprintf. Could you include the preprocessor output? Your test.zip does not include the headers that are used in the header units, so it is hard to reproduce this issue.