Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ban building runtimes using compilers without SwiftCC/SwiftAsyncCC #64773

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

etcwilde
Copy link
Member

Building the runtime with a compiler that doesn't understand swift calling conventions is playing with fire, and not a fun fire. Also, swapping out swift async calling conventions with normal swift CC is not a great idea either. Emit an error message saying stopping folks from burning themselves.

Folks keep seeing this and thinking that they can build without the right compiler and arguing with me about not being able to use a random compiler to build the runtime "because it's just normal C++". The Swift async calling conventions are different enough that just falling back on synchronous calling conventions (especially without telling the Swift compiler) is a risky endeavor, if it works at all.

@etcwilde
Copy link
Member Author

@swift-ci please test

Copy link
Contributor

@al45tair al45tair left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I raised my eyebrows when I originally saw those #else cases, but assumed someone must think it was OK. #error does seem safer.

Comment on lines -211 to -214
#define SWIFT_CC_swift
#define SWIFT_CONTEXT
#define SWIFT_ERROR_RESULT
#define SWIFT_INDIRECT_RESULT
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit scary...

include/swift/Runtime/Config.h Outdated Show resolved Hide resolved
include/swift/Runtime/Config.h Show resolved Hide resolved
@etcwilde etcwilde force-pushed the ewilde/dont-go-alone-use-this branch 2 times, most recently from c840634 to 61e8229 Compare March 30, 2023 18:06
@etcwilde etcwilde requested a review from compnerd March 30, 2023 18:07
@etcwilde
Copy link
Member Author

@swift-ci please test

@etcwilde
Copy link
Member Author

Linux failure:

/home/build-user/swift/stdlib/public/SwiftRemoteMirror/SwiftRemoteMirror.cpp
In file included from /home/build-user/swift/stdlib/public/SwiftRemoteMirror/SwiftRemoteMirror.cpp:26:
In file included from /home/build-user/swift/include/swift/RemoteInspection/ReflectionContext.h:32:
In file included from /home/build-user/swift/include/swift/Remote/MetadataReader.h:20:
In file included from /home/build-user/swift/include/swift/Runtime/Metadata.h:20:
In file included from /home/build-user/swift/include/swift/ABI/Metadata.h:28:
/home/build-user/swift/include/swift/Runtime/Config.h:215:2: error: "The runtime must be built with a compiler that supports swiftasynccall calling conventions."
#error "The runtime must be built with a compiler that supports swiftasynccall calling conventions."
 ^

Windows failure:

C:\Users\swift-ci\jenkins\workspace\swift-PR-windows\swift\include\swift/Runtime/Config.h(217,44): note: expanded from macro 'SWIFT_CC_swiftasync'
#define SWIFT_CC_swiftasync __attribute__((swiftasynccall))
                                           ^
In file included from C:\Users\swift-ci\jenkins\workspace\swift-PR-windows\swift\stdlib\public\CompatibilityOverride\CompatibilityOverride.cpp:17:
In file included from C:\Users\swift-ci\jenkins\workspace\swift-PR-windows\swift\stdlib\public\CompatibilityOverride/CompatibilityOverride.h:85:
In file included from C:\Users\swift-ci\jenkins\workspace\swift-PR-windows\swift\include\swift/Runtime/Concurrency.h:20:
In file included from C:\Users\swift-ci\jenkins\workspace\swift-PR-windows\swift\include\swift/ABI/AsyncLet.h:20:
In file included from C:\Users\swift-ci\jenkins\workspace\swift-PR-windows\swift\include\swift/ABI/Task.h:21:
C:\Users\swift-ci\jenkins\workspace\swift-PR-windows\swift\include\swift/ABI/Executor.h(194,3): error: 'swiftasynccall' calling convention is not supported for this target
  SWIFT_CC(swiftasync)
  ^

@etcwilde etcwilde force-pushed the ewilde/dont-go-alone-use-this branch from 61e8229 to e0fa2b7 Compare March 30, 2023 21:40
@etcwilde
Copy link
Member Author

@swift-ci please test

@etcwilde
Copy link
Member Author

Windows failure:

FAILED: lib/SwiftRemoteInspection/CMakeFiles/swiftRemoteInspection.dir/__/__/stdlib/public/RemoteInspection/TypeRefBuilder.cpp.obj 
C:\PROGRA~2\MICROS~1\2019\COMMUN~1\VC\Tools\MSVC\1429~1.300\bin\Hostx64\x64\cl.exe  /nologo /TP -DCMARK_STATIC_DEFINE -DGTEST_HAS_RTTI=0 -DLLVM_ON_WIN32 -DSWIFT_THREADING_WIN32 -DUNICODE -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS -D_CRT_USE_WINAPI_FAMILY_DESKTOP_APP -D_DLL -D_ENABLE_ATOMIC_ALIGNMENT_FIX -D_ENABLE_EXTENDED_ALIGNED_STORAGE=1 -D_GLIBCXX_ASSERTIONS -D_HAS_EXCEPTIONS=0 -D_HAS_STATIC_RTTI=0 -D_LIBCPP_ENABLE_ASSERTIONS -D_MD -D_SCL_SECURE_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS -D_UNICODE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -Ilib\SwiftRemoteInspection -IC:\Users\swift-ci\jenkins\workspace\swift-PR-windows\swift\lib\SwiftRemoteInspection -IC:\Users\swift-ci\jenkins\workspace\swift-PR-windows\swift\stdlib\public\SwiftShims -Iinclude -IC:\Users\swift-ci\jenkins\workspace\swift-PR-windows\swift\include -IC:\Users\swift-ci\jenkins\workspace\swift-PR-windows\llvm-project\llvm\include -IT:\llvm\include -IC:\Users\swift-ci\jenkins\workspace\swift-PR-windows\llvm-project\clang\include -IT:\llvm\tools\clang\include -IC:\Users\swift-ci\jenkins\workspace\swift-PR-windows\cmark\src\include -IT:\cmark\src -IC:\Users\swift-ci\jenkins\workspace\swift-PR-windows\swift-corelibs-libdispatch\src\BlocksRuntime -IC:\Users\swift-ci\jenkins\workspace\swift-PR-windows\swift-corelibs-libdispatch -I"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\\include" -I"C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt" -I"C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\shared" -I"C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\um" /GS- /Oy /Zc:inline /Zc:__cplusplus /Oi /bigobj /permissive- /W4 -wd4141 -wd4146 -wd4244 -wd4267 -wd4291 -wd4351 -wd4456 -wd4457 -wd4458 -wd4459 -wd4503 -wd4624 -wd4722 -wd4100 -wd4127 -wd4512 -wd4505 -wd4610 -wd4510 -wd4702 -wd4245 -wd4706 -wd4310 -wd4701 -wd4703 -wd4389 -wd4611 -wd4805 -wd4204 -wd4577 -wd4091 -wd4592 -wd4319 -wd4709 -wd4324 -w14062 -we4238 /Gw /we4062 /wd4068 /permissive- -DOBJC_OLD_DISPATCH_PROTOTYPES=0 /O2 /Ob2  /MD -MD  /EHs-c- /GR- -UNDEBUG -O2 /GR- -U_DEBUG -DSWIFT_ENABLE_REFLECTION -std:c++17 /showIncludes /Folib\SwiftRemoteInspection\CMakeFiles\swiftRemoteInspection.dir\__\__\stdlib\public\RemoteInspection\TypeRefBuilder.cpp.obj /Fdlib\SwiftRemoteInspection\CMakeFiles\swiftRemoteInspection.dir\swiftRemoteInspection.pdb /FS -c C:\Users\swift-ci\jenkins\workspace\swift-PR-windows\swift\stdlib\public\RemoteInspection\TypeRefBuilder.cpp
C:\Users\swift-ci\jenkins\workspace\swift-PR-windows\swift\include\swift/Runtime/Config.h(204): fatal error C1189: #error:  "The runtime must be built with a compiler that supports swiftcall calling conventions."

FAILED: lib/LLVMPasses/CMakeFiles/swiftLLVMPasses.dir/LLVMARCOpts.cpp.obj 
C:\PROGRA~2\MICROS~1\2019\COMMUN~1\VC\Tools\MSVC\1429~1.300\bin\Hostx64\x64\cl.exe  /nologo /TP -DCMARK_STATIC_DEFINE -DGTEST_HAS_RTTI=0 -DLLVM_ON_WIN32 -DSWIFT_LLVM_SUPPORT_IS_AVAILABLE -DSWIFT_THREADING_WIN32 -DUNICODE -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS -D_CRT_USE_WINAPI_FAMILY_DESKTOP_APP -D_DLL -D_ENABLE_ATOMIC_ALIGNMENT_FIX -D_ENABLE_EXTENDED_ALIGNED_STORAGE=1 -D_GLIBCXX_ASSERTIONS -D_HAS_EXCEPTIONS=0 -D_HAS_STATIC_RTTI=0 -D_LIBCPP_ENABLE_ASSERTIONS -D_MD -D_SCL_SECURE_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS -D_UNICODE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -Ilib\LLVMPasses -IC:\Users\swift-ci\jenkins\workspace\swift-PR-windows\swift\lib\LLVMPasses -IC:\Users\swift-ci\jenkins\workspace\swift-PR-windows\swift\stdlib\public\SwiftShims -Iinclude -IC:\Users\swift-ci\jenkins\workspace\swift-PR-windows\swift\include -IC:\Users\swift-ci\jenkins\workspace\swift-PR-windows\llvm-project\llvm\include -IT:\llvm\include -IC:\Users\swift-ci\jenkins\workspace\swift-PR-windows\llvm-project\clang\include -IT:\llvm\tools\clang\include -IC:\Users\swift-ci\jenkins\workspace\swift-PR-windows\cmark\src\include -IT:\cmark\src -IC:\Users\swift-ci\jenkins\workspace\swift-PR-windows\swift-corelibs-libdispatch\src\BlocksRuntime -IC:\Users\swift-ci\jenkins\workspace\swift-PR-windows\swift-corelibs-libdispatch -I"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\\include" -I"C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt" -I"C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\shared" -I"C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\um" /GS- /Oy /Zc:inline /Zc:__cplusplus /Oi /bigobj /permissive- /W4 -wd4141 -wd4146 -wd4244 -wd4267 -wd4291 -wd4351 -wd4456 -wd4457 -wd4458 -wd4459 -wd4503 -wd4624 -wd4722 -wd4100 -wd4127 -wd4512 -wd4505 -wd4610 -wd4510 -wd4702 -wd4245 -wd4706 -wd4310 -wd4701 -wd4703 -wd4389 -wd4611 -wd4805 -wd4204 -wd4577 -wd4091 -wd4592 -wd4319 -wd4709 -wd4324 -w14062 -we4238 /Gw /we4062 /wd4068 /permissive- -DOBJC_OLD_DISPATCH_PROTOTYPES=0 /O2 /Ob2  /MD -MD  /EHs-c- /GR- -UNDEBUG -O2 /GR- -U_DEBUG -std:c++17 /showIncludes /Folib\LLVMPasses\CMakeFiles\swiftLLVMPasses.dir\LLVMARCOpts.cpp.obj /Fdlib\LLVMPasses\CMakeFiles\swiftLLVMPasses.dir\swiftLLVMPasses.pdb /FS -c C:\Users\swift-ci\jenkins\workspace\swift-PR-windows\swift\lib\LLVMPasses\LLVMARCOpts.cpp
C:\Users\swift-ci\jenkins\workspace\swift-PR-windows\swift\include\swift/Runtime/Config.h(204): fatal error C1189: #error:  "The runtime must be built with a compiler that supports swiftcall calling conventions."

@etcwilde
Copy link
Member Author

The error in swift\stdlib\public\RemoteInspection\TypeRefBuilder.cpp might be catching a real issue given that it's under the stdlib. Then the next failure in swift\lib\LLVMPasses\LLVMARCOpts.cpp is probably because we're munging the runtime/stdlib and compiler into one big project and we're bleeding between the layers.

@etcwilde
Copy link
Member Author

RemoteInspection is for swift-inspect, which should be able to be built with the host compiler. Otherwise we get into nasty bootstrapping requirements for bringing up the toolchain side of things, which I don't want to do.

I think the best we can do is just refrain from defining the macros, which will fail to compile if people try to use them in contexts where the C/C++ compiler doesn't have the necessary calling conventions.

@mikeash
Copy link
Contributor

mikeash commented Mar 31, 2023

Does #error work in macros? We could make a better error message with that if so. Worst case, you could do something like #define SWIFT_CC_swift this code must be built with a compiler that supports Swift calling conventions and let that produce a syntax error.

@etcwilde
Copy link
Member Author

Does #error work in macros? We could make a better error message with that if so. Worst case, you could do something like #define SWIFT_CC_swift this code must be built with a compiler that supports Swift calling conventions and let that produce a syntax error.

No, unfortunately it doesn't expand nicely. I'm pretty sure you're not supposed to have multiple layers of recursive macros.

For this program

#define FOO #error "Hi, this is an error"
FOO void test() { return; }

Clang says:

test.c:2:1: error: expected identifier or '('
FOO void test() { return; }
^
test.c:1:13: note: expanded from macro 'FOO'
#define FOO #error "Hi, this is an error"
            ^

GCC says:

<source>:1:13: error: stray '#' in program
    1 | #define FOO #error "Hi, this is an error"
      |             ^
<source>:2:1: note: in expansion of macro 'FOO'
    2 | FOO void test() { return; }
      | ^~~
<source>:1:20: error: expected '=', ',', ';', 'asm' or '__attribute__' before string constant
    1 | #define FOO #error "Hi, this is an error"
      |                    ^~~~~~~~~~~~~~~~~~~~~~
<source>:2:1: note: in expansion of macro 'FOO'
    2 | FOO void test() { return; }
      | ^~~

MSVC says:

example.c
<source>(2): error C2121: '#': invalid character: possibly the result of a macro expansion
<source>(2): error C2143: syntax error: missing '{' before 'string'
<source>(2): error C2059: syntax error: 'string'

And lastly ICC:

<source>(2): error: "#" not expected here
  FOO void test() { return; }
  ^

<source>(2): error: expected a declaration
  FOO void test() { return; }
  ^

Clang and GCC are almost tolerable if people read diagnostic notes, but MSVC is pretty bad, unfortunately.

@etcwilde etcwilde force-pushed the ewilde/dont-go-alone-use-this branch from e0fa2b7 to b5da077 Compare April 12, 2023 17:10
@etcwilde
Copy link
Member Author

@swift-ci please test

Building the runtime with a compiler that doesn't understand swift
calling conventions is playing with fire, and not a fun fire because the
Swift compiler will emit calls expecting swift calling conventions,
resulting in an ABI mismatch and lots of pain. This patch stops us from
defining the offending macros in cases where the C/C++ compiler building
the runtime doesn't understand Swift calling conventions, so attempted
usage will result in a hard build failure.

Unfortunately, the runtime-inspection library includes this header, but
is part of the toolchain build, which should be buildable with the host
C/C++ compiler (msvc, gcc, etc...), so I can't outright `#error` the
failing clause or it will cause that library to fail to build.
Sadly, unknown attributes are either handled as soft warnings or ignored
altogether, which is not a great situation when building a broken ABI.
We could use `_Pragma("clang diagnostic error
\"-Wattribute-ignored\"")`, but that only works for clang, where my main
target is gcc. I've gone with not defining the macro in cases where the
compiler doesn't understand the calling conventions so that it is a hard
error at the point of use, and emitting a warning saying that we're not
defining the macro because the compiler doesn't understand the calling
convention to explain why.

I've done the same with the swift async calling convention, removing the
fallback on the Swift CC. Windows added swift async calling convention
support in apple/llvm-project commit
e5198240d982c635129cf1a2ae2f2251747a981d, and apple/swift commit
4f6a054.
@etcwilde etcwilde force-pushed the ewilde/dont-go-alone-use-this branch from b5da077 to ac4a5d6 Compare April 12, 2023 18:19
@etcwilde
Copy link
Member Author

@swift-ci please test

@etcwilde
Copy link
Member Author

Linux failure:

FAILED: source/Plugins/LanguageRuntime/Swift/CMakeFiles/lldbPluginSwiftLanguageRuntime.dir/SwiftLanguageRuntimeNames.cpp.o 
/usr/bin/clang++ -DGTEST_HAS_RTTI=0 -DHAVE_ROUND -DLLDB_ENABLE_SWIFT -D_DEBUG -D_GLIBCXX_ASSERTIONS -D_LIBCPP_ENABLE_ASSERTIONS -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -Isource/Plugins/LanguageRuntime/Swift -I/home/build-user/llvm-project/lldb/source/Plugins/LanguageRuntime/Swift -I/home/build-user/llvm-project/lldb/include -Iinclude -I/home/build-user/llvm-project/llvm/include -I/home/build-user/build/buildbot_linux/llvm-linux-x86_64/include -I/home/build-user/llvm-project/clang/include -I/home/build-user/build/buildbot_linux/llvm-linux-x86_64/tools/clang/include -I/home/build-user/llvm-project/lldb/source -I/home/build-user/build/buildbot_linux/swift-linux-x86_64/include -I/home/build-user/swift/include -I/home/build-user/swift/stdlib/public/SwiftShims -I/usr/include/python3.8 -I/home/build-user/llvm-project/lldb/tools/clang/include -I../clang/include -Isource -isystem /usr/include/libxml2 -Wno-unknown-warning-option -Werror=unguarded-availability-new -fno-stack-protector -fPIC -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -Wimplicit-fallthrough -Wcovered-switch-default -Wno-class-memaccess -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -Wno-deprecated-declarations -Wno-unknown-pragmas -Wno-strict-aliasing -Wno-stringop-truncation -Wno-deprecated-register -Wno-vla-extension -O3 -DNDEBUG  -fno-exceptions -fno-rtti -UNDEBUG -std=c++17 -MD -MT source/Plugins/LanguageRuntime/Swift/CMakeFiles/lldbPluginSwiftLanguageRuntime.dir/SwiftLanguageRuntimeNames.cpp.o -MF source/Plugins/LanguageRuntime/Swift/CMakeFiles/lldbPluginSwiftLanguageRuntime.dir/SwiftLanguageRuntimeNames.cpp.o.d -o source/Plugins/LanguageRuntime/Swift/CMakeFiles/lldbPluginSwiftLanguageRuntime.dir/SwiftLanguageRuntimeNames.cpp.o -c /home/build-user/llvm-project/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeNames.cpp
In file included from /home/build-user/llvm-project/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeNames.cpp:13:
In file included from /home/build-user/llvm-project/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeImpl.h:16:
In file included from /home/build-user/llvm-project/lldb/source/Plugins/LanguageRuntime/Swift/LLDBMemoryReader.h:10:
In file included from /home/build-user/swift/include/swift/RemoteInspection/ReflectionContext.h:32:
In file included from /home/build-user/swift/include/swift/Remote/MetadataReader.h:20:
In file included from /home/build-user/swift/include/swift/Runtime/Metadata.h:20:
In file included from /home/build-user/swift/include/swift/ABI/Metadata.h:28:
/home/build-user/swift/include/swift/Runtime/Config.h:243:2: warning: "C++ Compiler does not support async-swift calling conventions. SWIFT_CC_swiftasync macros not defined!" [-W#warnings]
#warning                                                                       \
 ^
In file included from /home/build-user/llvm-project/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeNames.cpp:26:
In file included from /home/build-user/swift/include/swift/ABI/Task.h:21:
/home/build-user/swift/include/swift/ABI/Executor.h:186:3: error: unknown type name 'SWIFT_CC_swiftasync'
  SWIFT_CC(swiftasync)
  ^
/home/build-user/swift/include/swift/Runtime/Config.h:195:22: note: expanded from macro 'SWIFT_CC'
#define SWIFT_CC(CC) SWIFT_CC_##CC
                     ^
<scratch space>:70:1: note: expanded from here
SWIFT_CC_swiftasync
^
In file included from /home/build-user/llvm-project/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeNames.cpp:26:
In file included from /home/build-user/swift/include/swift/ABI/Task.h:21:
/home/build-user/swift/include/swift/ABI/Executor.h:190:3: error: unknown type name 'SWIFT_CC_swiftasync'
  SWIFT_CC(swiftasync)
  ^
/home/build-user/swift/include/swift/Runtime/Config.h:195:22: note: expanded from macro 'SWIFT_CC'
#define SWIFT_CC(CC) SWIFT_CC_##CC
                     ^
<scratch space>:71:1: note: expanded from here
SWIFT_CC_swiftasync
^

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants