Index: lld/test/wasm/command-exports.s =================================================================== --- lld/test/wasm/command-exports.s +++ lld/test/wasm/command-exports.s @@ -39,17 +39,17 @@ i32.const 0 end_function - .section .text..Lcall_dtors.1,"",@ -.Lcall_dtors.1: - .functype .Lcall_dtors.1 (i32) -> () + .section .text.call_dtors.1,"",@ +call_dtors.1: + .functype call_dtors.1 (i32) -> () call some_dtor end_function - .section .text..Lregister_call_dtors.1,"",@ -.Lregister_call_dtors.1: - .functype .Lregister_call_dtors.1 () -> () + .section .text.register_call_dtors.1,"",@ +register_call_dtors.1: + .functype register_call_dtors.1 () -> () block - i32.const .Lcall_dtors.1 + i32.const call_dtors.1 i32.const 0 i32.const 0 call __cxa_atexit @@ -63,7 +63,7 @@ .section .init_array.1,"",@ .p2align 2 .int32 some_ctor - .int32 .Lregister_call_dtors.1 + .int32 register_call_dtors.1 .export_name foo_i32, foo_i32 .export_name foo_f64, foo_f64 @@ -104,9 +104,9 @@ # CHECK-NEXT: - Index: 5 # CHECK-NEXT: Name: __cxa_atexit # CHECK-NEXT: - Index: 6 -# CHECK-NEXT: Name: .Lcall_dtors.1 +# CHECK-NEXT: Name: call_dtors.1 # CHECK-NEXT: - Index: 7 -# CHECK-NEXT: Name: .Lregister_call_dtors.1 +# CHECK-NEXT: Name: register_call_dtors.1 # CHECK-NEXT: - Index: 8 # CHECK-NEXT: Name: foo_i32.command_export # CHECK-NEXT: - Index: 9 Index: llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp =================================================================== --- llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp +++ llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp @@ -216,7 +216,7 @@ // We track this to see if a .functype following a label is the same, // as this is how we recognize the start of a function. - MCSymbol *LastLabel = nullptr; + MCSymbol *LastNonLocalLabel = nullptr; MCSymbol *LastFunctionLabel = nullptr; public: @@ -679,8 +679,9 @@ } void onLabelParsed(MCSymbol *Symbol) override { - LastLabel = Symbol; CurrentState = Label; + if (!Symbol->getName().startswith(".L")) + LastNonLocalLabel = Symbol; } bool parseSignature(wasm::WasmSignature *Signature) { @@ -799,12 +800,12 @@ if (SymName.empty()) return true; auto WasmSym = cast(Ctx.getOrCreateSymbol(SymName)); - if (CurrentState == Label && WasmSym == LastLabel) { + if (CurrentState == Label && WasmSym == LastNonLocalLabel) { // This .functype indicates a start of a function. if (ensureEmptyNestingStack()) return true; CurrentState = FunctionStart; - LastFunctionLabel = LastLabel; + LastFunctionLabel = LastNonLocalLabel; push(Function); } auto Signature = std::make_unique(); @@ -872,7 +873,7 @@ if (DirectiveID.getString() == ".local") { if (CurrentState != FunctionStart) - return error(".local directive should follow the start of a function", + return error(".local directive should follow the start of a function: ", Lexer.getTok()); SmallVector Locals; if (parseRegTypeList(Locals)) Index: llvm/test/MC/WebAssembly/basic-assembly.s =================================================================== --- llvm/test/MC/WebAssembly/basic-assembly.s +++ llvm/test/MC/WebAssembly/basic-assembly.s @@ -8,6 +8,8 @@ end_function test0: +# local labels can appear between label and its .functype. +.Ltest0begin: # Test all types: .functype test0 (i32, i64) -> (i32) .eventtype __cpp_exception i32 @@ -116,17 +118,18 @@ .globaltype __stack_pointer, i32 .tabletype empty_eref_table, externref -empty_eref_table: +empty_eref_table: .tabletype empty_fref_table, funcref -empty_fref_table: +empty_fref_table: + - # CHECK: .text # CHECK-LABEL: empty_func: # CHECK-NEXT: .functype empty_func () -> () # CHECK-NEXT: end_function # CHECK-LABEL: test0: +# CHECK-NEXT: .Ltest0begin: # CHECK-NEXT: .functype test0 (i32, i64) -> (i32) # CHECK-NEXT: .eventtype __cpp_exception i32 # CHECK-NEXT: .local f32, f64 @@ -226,6 +229,6 @@ # CHECK: .tabletype empty_eref_table, externref # CHECK-NEXT: empty_eref_table: - + # CHECK: .tabletype empty_fref_table, funcref # CHECK-NEXT: empty_fref_table: