swiftlang / swift

The Swift Programming Language
https://swift.org
Apache License 2.0
67.27k stars 10.33k forks source link

DeclarationMacro adding a declaration with a PropertyWrapper crashes IR Generation #70807

Open planetMDX opened 8 months ago

planetMDX commented 8 months ago

Description

A Declaration Macro introducing a variable-declaration with a PropertyWrapper-attribute crashes if placed in a struct which isn't in a the scope of a function.

Reproduction

MacroCrashPropertyWrapper.zip macro:

public struct WrapperMacro: DeclarationMacro {
    public static func expansion(of node: some SwiftSyntax.FreestandingMacroExpansionSyntax, in context: some SwiftSyntaxMacros.MacroExpansionContext)
        throws -> [SwiftSyntax.DeclSyntax]
    {
        return [
            """
            @SomeWrapper
            var wrappedV: Int
            """
        ]
    }
}

main-code:

@propertyWrapper
struct SomeWrapper<T> {
    var actualVar: T
    var wrappedValue: T {
        get {
            actualVar
        }
        set {
            actualVar = newValue
        }
    }
}

@freestanding(declaration, names: arbitrary)
macro someDeclM() = #externalMacro(module: "MyMacrosPlugin", type: "WrapperMacro")

struct S {
    #someDeclM()
}

swift build crashes

Stack dump

Stack dump:
0.      Program arguments: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift-frontend -frontend -c -primary-file /Users/rolandambs/Documents/MacroCrashPropertyWrapper/Sources/MacroCrashPropertyWrapper/main.swift -emit-dependencies-path /Users/rolandambs/Documents/MacroCrashPropertyWrapper/.build/arm64-apple-macosx/debug/MacroCrashPropertyWrapper.build/main.d -emit-reference-dependencies-path /Users/rolandambs/Documents/MacroCrashPropertyWrapper/.build/arm64-apple-macosx/debug/MacroCrashPropertyWrapper.build/main.swiftdeps -target arm64-apple-macosx13.0 -Xllvm -aarch64-use-tbi -enable-objc-interop -stack-check -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.2.sdk -I /Users/rolandambs/Documents/MacroCrashPropertyWrapper/.build/arm64-apple-macosx/debug -I /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/lib -F /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Frameworks -color-diagnostics -enable-testing -g -module-cache-path /Users/rolandambs/Documents/MacroCrashPropertyWrapper/.build/arm64-apple-macosx/debug/ModuleCache -swift-version 5 -Onone -D SWIFT_PACKAGE -D DEBUG -new-driver-path /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift-driver -entry-point-function-name MacroCrashPropertyWrapper_main -load-plugin-executable /Users/rolandambs/Documents/MacroCrashPropertyWrapper/.build/arm64-apple-macosx/debug/MyMacrosPlugin#MyMacrosPlugin -empty-abi-descriptor -resource-dir /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift -enable-anonymous-context-mangled-names -Xcc -isysroot -Xcc /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.2.sdk -Xcc -F -Xcc /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Frameworks -Xcc -fPIC -module-name MacroCrashPropertyWrapper -package-name macrocrashpropertywrapper -disable-clang-spi -target-sdk-version 14.2 -target-sdk-name macosx14.2 -external-plugin-path /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.2.sdk/usr/lib/swift/host/plugins#/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.2.sdk/usr/bin/swift-plugin-server -external-plugin-path /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.2.sdk/usr/local/lib/swift/host/plugins#/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.2.sdk/usr/bin/swift-plugin-server -external-plugin-path /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/lib/swift/host/plugins#/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/bin/swift-plugin-server -external-plugin-path /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/local/lib/swift/host/plugins#/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/bin/swift-plugin-server -plugin-path /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/host/plugins -plugin-path /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/local/lib/swift/host/plugins -o /Users/rolandambs/Documents/MacroCrashPropertyWrapper/.build/arm64-apple-macosx/debug/MacroCrashPropertyWrapper.build/main.swift.o -index-store-path /Users/rolandambs/Documents/MacroCrashPropertyWrapper/.build/arm64-apple-macosx/debug/index/store -index-system-modules
1.      Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5)
2.      Compiling with the current language version
3.      While evaluating request IRGenRequest(IR Generation for file "/Users/rolandambs/Documents/MacroCrashPropertyWrapper/Sources/MacroCrashPropertyWrapper/main.swift")
4.      While emitting IR SIL function "@$s25MacroCrashPropertyWrapper1SV8wrappedVSivg".
 for getter for wrappedV (at @__swiftmacro_25MacroCrashPropertyWrapper1SV33_E73096BDB3F78A47FCE172885EB53921Ll9someDeclMfMf0_.swift:2:5)
Stack dump without symbol names (ensure you have llvm-symbolizer in your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point to it):
0  swift-frontend           0x00000001031d9abc llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) + 56
1  swift-frontend           0x0000000105e3fcb0 llvm::sys::RunSignalHandlers() + 112
2  swift-frontend           0x0000000105ba9054 SignalHandler(int) + 352
3  libsystem_platform.dylib 0x000000018243da24 _sigtramp + 56
4  swift-frontend           0x0000000102889cb4 swift::irgen::SingleScalarTypeInfo<(anonymous namespace)::PrimitiveTypeInfo, swift::irgen::LoadableTypeInfo>::storeAsBytes(swift::irgen::IRGenFunction&, swift::irgen::Explosion&, swift::irgen::Address) const + 108
5  swift-frontend           0x0000000102889cb4 swift::irgen::SingleScalarTypeInfo<(anonymous namespace)::PrimitiveTypeInfo, swift::irgen::LoadableTypeInfo>::storeAsBytes(swift::irgen::IRGenFunction&, swift::irgen::Explosion&, swift::irgen::Address) const + 108
6  swift-frontend           0x000000010287cf60 swift::irgen::SingleScalarTypeInfo<(anonymous namespace)::PrimitiveTypeInfo, swift::irgen::LoadableTypeInfo>::initialize(swift::irgen::IRGenFunction&, swift::irgen::Explosion&, swift::irgen::Address, bool) const + 48
7  swift-frontend           0x00000001016f3910 swift::irgen::RecordTypeInfo<(anonymous namespace)::LoadableStructTypeInfo, swift::irgen::LoadableTypeInfo, (anonymous namespace)::StructFieldInfo, true, true>::initialize(swift::irgen::IRGenFunction&, swift::irgen::Explosion&, swift::irgen::Address, bool) const + 200
8  swift-frontend           0x00000001016f3910 swift::irgen::RecordTypeInfo<(anonymous namespace)::LoadableStructTypeInfo, swift::irgen::LoadableTypeInfo, (anonymous namespace)::StructFieldInfo, true, true>::initialize(swift::irgen::IRGenFunction&, swift::irgen::Explosion&, swift::irgen::Address, bool) const + 200
9  swift-frontend           0x0000000102ddb0f4 (anonymous namespace)::IRGenSILFunction::visitSILBasicBlock(swift::SILBasicBlock*) + 71880
10 swift-frontend           0x000000010555dfdc swift::irgen::IRGenModule::emitSILFunction(swift::SILFunction*) + 11680
11 swift-frontend           0x000000010315c9c8 swift::irgen::IRGenerator::emitGlobalTopLevel(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>>> const&) + 2516
12 swift-frontend           0x00000001018019d0 swift::IRGenRequest::evaluate(swift::Evaluator&, swift::IRGenDescriptor) const + 6532
13 swift-frontend           0x00000001010d4adc swift::SimpleRequest<swift::IRGenRequest, swift::GeneratedModule (swift::IRGenDescriptor), (swift::RequestFlags)9>::evaluateRequest(swift::IRGenRequest const&, swift::Evaluator&) + 176
14 swift-frontend           0x0000000102aa5f64 llvm::Expected<swift::IRGenRequest::OutputType> swift::Evaluator::getResultUncached<swift::IRGenRequest>(swift::IRGenRequest const&) + 1480
15 swift-frontend           0x0000000104d4cfb8 swift::performIRGeneration(swift::FileUnit*, swift::IRGenOptions const&, swift::TBDGenOptions const&, std::__1::unique_ptr<swift::SILModule, std::__1::default_delete<swift::SILModule>>, llvm::StringRef, swift::PrimarySpecificPaths const&, llvm::StringRef, llvm::GlobalVariable**) + 264
16 swift-frontend           0x000000010571999c generateIR(swift::IRGenOptions const&, swift::TBDGenOptions const&, std::__1::unique_ptr<swift::SILModule, std::__1::default_delete<swift::SILModule>>, swift::PrimarySpecificPaths const&, llvm::StringRef, llvm::PointerUnion<swift::ModuleDecl*, swift::SourceFile*>, llvm::GlobalVariable*&, llvm::ArrayRef<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>>) + 156
17 swift-frontend           0x00000001057216d4 performCompileStepsPostSILGen(swift::CompilerInstance&, std::__1::unique_ptr<swift::SILModule, std::__1::default_delete<swift::SILModule>>, llvm::PointerUnion<swift::ModuleDecl*, swift::SourceFile*>, swift::PrimarySpecificPaths const&, int&, swift::FrontendObserver*) + 1596
18 swift-frontend           0x000000010571ca08 performCompile(swift::CompilerInstance&, int&, swift::FrontendObserver*) + 1748
19 swift-frontend           0x0000000105720854 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 4568
20 swift-frontend           0x0000000105787d44 swift::mainEntry(int, char const**) + 4408
21 dyld                     0x000000018208d0e0 start + 2360

Expected behavior

The macro should expand to this:

@SomeWrapper
var wrappedV: Int

Environment

swift-driver version: 1.87.3 Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5) Target: arm64-apple-macosx14.0

Additional information

If the macro gets expanded before the compilation no crash occurs.

rastersize commented 1 month ago

I just tested this with both Swift 5.10+SwiftSyntax 510.0.2 and Swift 6.0 beta 3+SwiftSyntax 600.0.0-prerelease-2024-06-12 using my #Environment macro and both still crash.

Stack dump when running swift build from the swift-6 branch in the linked repo.

error: compile command failed due to signal 5 (use -v to see invocation)
Please submit a bug report (https://swift.org/contributing/#reporting-bugs) and include the crash backtrace.
Stack dump:
0.  Program arguments: /Applications/Xcode-16.0.0-Beta.3.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift-frontend -frontend -c -primary-file /Users/rastersize/Developer/Personal/EnvironmentMacro/Sources/EnvironmentMacroClient/main.swift -emit-dependencies-path /Users/rastersize/Developer/Personal/EnvironmentMacro/.build/arm64-apple-macosx/debug/EnvironmentMacroClient.build/main.d -emit-reference-dependencies-path /Users/rastersize/Developer/Personal/EnvironmentMacro/.build/arm64-apple-macosx/debug/EnvironmentMacroClient.build/main.swiftdeps -target arm64-apple-macosx12.0 -Xllvm -aarch64-use-tbi -enable-objc-interop -stack-check -sdk /Applications/Xcode-16.0.0-Beta.3.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.0.sdk -I /Users/rastersize/Developer/Personal/EnvironmentMacro/.build/arm64-apple-macosx/debug/Modules -I /Applications/Xcode-16.0.0-Beta.3.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/lib -F /Applications/Xcode-16.0.0-Beta.3.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Frameworks -color-diagnostics -enable-testing -g -debug-info-format=dwarf -dwarf-version=4 -module-cache-path /Users/rastersize/Developer/Personal/EnvironmentMacro/.build/arm64-apple-macosx/debug/ModuleCache -swift-version 6 -Onone -D SWIFT_PACKAGE -D DEBUG -new-driver-path /Applications/Xcode-16.0.0-Beta.3.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift-driver -entry-point-function-name EnvironmentMacroClient_main -load-plugin-executable /Users/rastersize/Developer/Personal/EnvironmentMacro/.build/arm64-apple-macosx/debug/EnvironmentMacroMacros-tool#EnvironmentMacroMacros -empty-abi-descriptor -resource-dir /Applications/Xcode-16.0.0-Beta.3.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift -enable-anonymous-context-mangled-names -file-compilation-dir /Users/rastersize/Developer/Personal/EnvironmentMacro -Xcc -fmodule-map-file=/Users/rastersize/Developer/Personal/EnvironmentMacro/.build/checkouts/swift-syntax/Sources/_SwiftSyntaxCShims/include/module.modulemap -Xcc -I -Xcc /Users/rastersize/Developer/Personal/EnvironmentMacro/.build/checkouts/swift-syntax/Sources/_SwiftSyntaxCShims/include -Xcc -isysroot -Xcc /Applications/Xcode-16.0.0-Beta.3.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.0.sdk -Xcc -F -Xcc /Applications/Xcode-16.0.0-Beta.3.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Frameworks -Xcc -fPIC -Xcc -g -module-name EnvironmentMacroClient -package-name environmentmacro -disable-clang-spi -target-sdk-version 15.0 -target-sdk-name macosx15.0 -external-plugin-path /Applications/Xcode-16.0.0-Beta.3.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/lib/swift/host/plugins#/Applications/Xcode-16.0.0-Beta.3.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/bin/swift-plugin-server -external-plugin-path /Applications/Xcode-16.0.0-Beta.3.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/local/lib/swift/host/plugins#/Applications/Xcode-16.0.0-Beta.3.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/bin/swift-plugin-server -plugin-path /Applications/Xcode-16.0.0-Beta.3.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/host/plugins -plugin-path /Applications/Xcode-16.0.0-Beta.3.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/local/lib/swift/host/plugins -o /Users/rastersize/Developer/Personal/EnvironmentMacro/.build/arm64-apple-macosx/debug/EnvironmentMacroClient.build/main.swift.o -index-store-path /Users/rastersize/Developer/Personal/EnvironmentMacro/.build/arm64-apple-macosx/debug/index/store -index-system-modules
1.  Apple Swift version 6.0 (swiftlang-6.0.0.5.15 clang-1600.0.22.6)
2.  Compiling with the current language version
3.  While evaluating request ASTLoweringRequest(Lowering AST to SIL for file "/Users/rastersize/Developer/Personal/EnvironmentMacro/Sources/EnvironmentMacroClient/main.swift")
4.  While silgen emitFunction SIL function "@$s22EnvironmentMacroClient6MyViewV15dynamicTypeSize33_9F7B18EE84A365320104438E0B059EA8LL7SwiftUI07DynamicgH0Ovg".
 for getter for dynamicTypeSize (at @__swiftmacro_22EnvironmentMacroClient0015mainswift_tzEGbfMX7_4_33_9F7B18EE84A365320104438E0B059EA8Ll0A0fMf_.swift:1:45)
Stack dump without symbol names (ensure you have llvm-symbolizer in your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point to it):
0  swift-frontend           0x000000010a865da8 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) + 56
1  swift-frontend           0x000000010a863ffc llvm::sys::RunSignalHandlers() + 112
2  swift-frontend           0x000000010a866374 SignalHandler(int) + 292
3  libsystem_platform.dylib 0x000000018bfc7584 _sigtramp + 56
4  swift-frontend           0x0000000105c2696c swift::Lowering::ManagedValue::copy(swift::Lowering::SILGenFunction&, swift::SILLocation) const + 356
5  swift-frontend           0x0000000105d1d988 swift::Lowering::SILGenFunction::emitLoadOfLValue(swift::SILLocation, swift::Lowering::LValue&&, swift::Lowering::SGFContext, bool) + 1428
6  swift-frontend           0x0000000105cd1528 (anonymous namespace)::RValueEmitter::visitSubscriptExpr(swift::SubscriptExpr*, swift::Lowering::SGFContext) + 188
7  swift-frontend           0x0000000105cc1744 swift::Lowering::SILGenFunction::emitRValueAsSingleValue(swift::Expr*, swift::Lowering::SGFContext) + 40
8  swift-frontend           0x0000000105d1b710 SILGenLValue::visitRec(swift::Expr*, swift::Lowering::SGFAccessKind, swift::Lowering::LValueOptions, swift::Lowering::AbstractionPattern) + 1408
9  swift-frontend           0x0000000105d1f4fc SILGenLValue::visitMemberRefExpr(swift::MemberRefExpr*, swift::Lowering::SGFAccessKind, swift::Lowering::LValueOptions) + 1324
10 swift-frontend           0x0000000105d1ac68 swift::Lowering::SILGenFunction::emitLValue(swift::Expr*, swift::Lowering::SGFAccessKind, swift::Lowering::LValueOptions) + 48
11 swift-frontend           0x0000000105cd14e4 (anonymous namespace)::RValueEmitter::visitSubscriptExpr(swift::SubscriptExpr*, swift::Lowering::SGFContext) + 120
12 swift-frontend           0x0000000105cbe540 swift::Lowering::SILGenFunction::emitExprInto(swift::Expr*, swift::Lowering::Initialization*, std::__1::optional<swift::SILLocation>) + 128
13 swift-frontend           0x0000000105d7bd24 swift::Lowering::SILGenFunction::emitReturnExpr(swift::SILLocation, swift::Expr*) + 1032
14 swift-frontend           0x0000000105d79558 swift::ASTVisitor<(anonymous namespace)::StmtEmitter, void, void, void, void, void, void>::visit(swift::Stmt*) + 8632
15 swift-frontend           0x0000000105d789b8 swift::ASTVisitor<(anonymous namespace)::StmtEmitter, void, void, void, void, void, void>::visit(swift::Stmt*) + 5656
16 swift-frontend           0x0000000105cf0bd4 swift::Lowering::SILGenFunction::emitFunction(swift::FuncDecl*) + 492
17 swift-frontend           0x0000000105c3ea04 swift::Lowering::SILGenModule::emitFunctionDefinition(swift::SILDeclRef, swift::SILFunction*) + 8416
18 swift-frontend           0x0000000105c43080 swift::ASTLoweringRequest::evaluate(swift::Evaluator&, swift::ASTLoweringDescriptor) const + 3776
19 swift-frontend           0x0000000105d76fe0 swift::SimpleRequest<swift::ASTLoweringRequest, std::__1::unique_ptr<swift::SILModule, std::__1::default_delete<swift::SILModule>> (swift::ASTLoweringDescriptor), (swift::RequestFlags)9>::evaluateRequest(swift::ASTLoweringRequest const&, swift::Evaluator&) + 196
20 swift-frontend           0x0000000105c477c8 swift::ASTLoweringRequest::OutputType swift::Evaluator::getResultUncached<swift::ASTLoweringRequest, swift::ASTLoweringRequest::OutputType swift::evaluateOrFatal<swift::ASTLoweringRequest>(swift::Evaluator&, swift::ASTLoweringRequest)::'lambda'()>(swift::ASTLoweringRequest const&, swift::ASTLoweringRequest::OutputType swift::evaluateOrFatal<swift::ASTLoweringRequest>(swift::Evaluator&, swift::ASTLoweringRequest)::'lambda'()) + 528
21 swift-frontend           0x000000010522bdfc swift::performCompileStepsPostSema(swift::CompilerInstance&, int&, swift::FrontendObserver*) + 920
22 swift-frontend           0x000000010523023c performCompile(swift::CompilerInstance&, int&, swift::FrontendObserver*) + 1680
23 swift-frontend           0x000000010522e0e4 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 4280
24 swift-frontend           0x00000001051b4c84 swift::mainEntry(int, char const**) + 3680
25 dyld                     0x000000018bc0e0e0 start + 2360
struct SomeView: View {
    #Environment(\.foo)
}
// expected to expand to
struct SomeView: View {
    @Environment(\.foo) private var foo
}