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

build errors #1

Closed
drom opened this issue Nov 6, 2015 · 6 comments
Closed

build errors #1

drom opened this issue Nov 6, 2015 · 6 comments

Comments

@drom
Copy link

drom commented Nov 6, 2015

I am having errors when building the project.

drom@drom:~/work/github/WebAssembly/wasm-emscripten> ./build.sh                                                                                                       
building asm2wasm                                                                                                                                                     
building interpreter/js                                                                                                                                               
./build.sh: line 4: em++: command not found                                                                                                                           
building wasm shell
In file included from src/wasm-s-parser.h:9:0,
                 from src/wasm-shell.cpp:8:
src/wasm.h:996:22: error: ‘ReturnType wasm::WasmVisitor<ReturnType>::visitBlock(wasm::Block*) [with ReturnType = wasm::ModuleInstance::callFunction(cashew::IString, wasm::ModuleInstance::LiteralList&)::Flow]’, declared using local type ‘wasm::ModuleInstance::callFunction(cashew::IString, wasm::ModuleInstance::LiteralList&)::Flow’, is used but never defined [-fpermissive]
   virtual ReturnType visitBlock(Block *curr) = 0;
                      ^
src/wasm.h:997:22: error: ‘ReturnType wasm::WasmVisitor<ReturnType>::visitIf(wasm::If*) [with ReturnType = wasm::ModuleInstance::callFunction(cashew::IString, wasm::ModuleInstance::LiteralList&)::Flow]’, declared using local type ‘wasm::ModuleInstance::callFunction(cashew::IString, wasm::ModuleInstance::LiteralList&)::Flow’, is used but never defined [-fpermissive]
   virtual ReturnType visitIf(If *curr) = 0;
                      ^
src/wasm.h:998:22: error: ‘ReturnType wasm::WasmVisitor<ReturnType>::visitLoop(wasm::Loop*) [with ReturnType = wasm::ModuleInstance::callFunction(cashew::IString, wasm::ModuleInstance::LiteralList&)::Flow]’, declared using local type ‘wasm::ModuleInstance::callFunction(cashew::IString, wasm::ModuleInstance::LiteralList&)::Flow’, is used but never defined [-fpermissive]
   virtual ReturnType visitLoop(Loop *curr) = 0;
                      ^
src/wasm.h:999:22: error: ‘ReturnType wasm::WasmVisitor<ReturnType>::visitLabel(wasm::Label*) [with ReturnType = wasm::ModuleInstance::callFunction(cashew::IString, wasm::ModuleInstance::LiteralList&)::Flow]’, declared using local type ‘wasm::ModuleInstance::callFunction(cashew::IString, wasm::ModuleInstance::LiteralList&)::Flow’, is used but never defined [-fpermissive]
   virtual ReturnType visitLabel(Label *curr) = 0;
                      ^
src/wasm.h:1000:22: error: ‘ReturnType wasm::WasmVisitor<ReturnType>::visitBreak(wasm::Break*) [with ReturnType = wasm::ModuleInstance::callFunction(cashew::IString, wasm::ModuleInstance::LiteralList&)::Flow]’, declared using local type ‘wasm::ModuleInstance::callFunction(cashew::IString, wasm::ModuleInstance::LiteralList&)::Flow’, is used but never defined [-fpermissive]
   virtual ReturnType visitBreak(Break *curr) = 0;
                      ^
src/wasm.h:1001:22: error: ‘ReturnType wasm::WasmVisitor<ReturnType>::visitSwitch(wasm::Switch*) [with ReturnType = wasm::ModuleInstance::callFunction(cashew::IString, wasm::ModuleInstance::LiteralList&)::Flow]’, declared using local type ‘wasm::ModuleInstance::callFunction(cashew::IString, wasm::ModuleInstance::LiteralList&)::Flow’, is used but never defined [-fpermissive]
   virtual ReturnType visitSwitch(Switch *curr) = 0;
                      ^
src/wasm.h:1002:22: error: ‘ReturnType wasm::WasmVisitor<ReturnType>::visitCall(wasm::Call*) [with ReturnType = wasm::ModuleInstance::callFunction(cashew::IString, wasm::ModuleInstance::LiteralList&)::Flow]’, declared using local type ‘wasm::ModuleInstance::callFunction(cashew::IString, wasm::ModuleInstance::LiteralList&)::Flow’, is used but never defined [-fpermissive]
   virtual ReturnType visitCall(Call *curr) = 0;
                      ^
src/wasm.h:1003:22: error: ‘ReturnType wasm::WasmVisitor<ReturnType>::visitCallImport(wasm::CallImport*) [with ReturnType = wasm::ModuleInstance::callFunction(cashew::IString, wasm::ModuleInstance::LiteralList&)::Flow]’, declared using local type ‘wasm::ModuleInstance::callFunction(cashew::IString, wasm::ModuleInstance::LiteralList&)::Flow’, is used but never defined [-fpermissive]
   virtual ReturnType visitCallImport(CallImport *curr) = 0;
                      ^
src/wasm.h:1004:22: error: ‘ReturnType wasm::WasmVisitor<ReturnType>::visitCallIndirect(wasm::CallIndirect*) [with ReturnType = wasm::ModuleInstance::callFunction(cashew::IString, wasm::ModuleInstance::LiteralList&)::Flow]’, declared using local type ‘wasm::ModuleInstance::callFunction(cashew::IString, wasm::ModuleInstance::LiteralList&)::Flow’, is used but never defined [-fpermissive]
   virtual ReturnType visitCallIndirect(CallIndirect *curr) = 0;
                      ^
src/wasm.h:1005:22: error: ‘ReturnType wasm::WasmVisitor<ReturnType>::visitGetLocal(wasm::GetLocal*) [with ReturnType = wasm::ModuleInstance::callFunction(cashew::IString, wasm::ModuleInstance::LiteralList&)::Flow]’, declared using local type ‘wasm::ModuleInstance::callFunction(cashew::IString, wasm::ModuleInstance::LiteralList&)::Flow’, is used but never defined [-fpermissive]
   virtual ReturnType visitGetLocal(GetLocal *curr) = 0;
                      ^
src/wasm.h:1006:22: error: ‘ReturnType wasm::WasmVisitor<ReturnType>::visitSetLocal(wasm::SetLocal*) [with ReturnType = wasm::ModuleInstance::callFunction(cashew::IString, wasm::ModuleInstance::LiteralList&)::Flow]’, declared using local type ‘wasm::ModuleInstance::callFunction(cashew::IString, wasm::ModuleInstance::LiteralList&)::Flow’, is used but never defined [-fpermissive]
   virtual ReturnType visitSetLocal(SetLocal *curr) = 0;
                      ^
src/wasm.h:1007:22: error: ‘ReturnType wasm::WasmVisitor<ReturnType>::visitLoad(wasm::Load*) [with ReturnType = wasm::ModuleInstance::callFunction(cashew::IString, wasm::ModuleInstance::LiteralList&)::Flow]’, declared using local type ‘wasm::ModuleInstance::callFunction(cashew::IString, wasm::ModuleInstance::LiteralList&)::Flow’, is used but never defined [-fpermissive]
   virtual ReturnType visitLoad(Load *curr) = 0;
                      ^
src/wasm.h:1008:22: error: ‘ReturnType wasm::WasmVisitor<ReturnType>::visitStore(wasm::Store*) [with ReturnType = wasm::ModuleInstance::callFunction(cashew::IString, wasm::ModuleInstance::LiteralList&)::Flow]’, declared using local type ‘wasm::ModuleInstance::callFunction(cashew::IString, wasm::ModuleInstance::LiteralList&)::Flow’, is used but never defined [-fpermissive]
   virtual ReturnType visitStore(Store *curr) = 0;
                      ^
src/wasm.h:1009:22: error: ‘ReturnType wasm::WasmVisitor<ReturnType>::visitConst(wasm::Const*) [with ReturnType = wasm::ModuleInstance::callFunction(cashew::IString, wasm::ModuleInstance::LiteralList&)::Flow]’, declared using local type ‘wasm::ModuleInstance::callFunction(cashew::IString, wasm::ModuleInstance::LiteralList&)::Flow’, is used but never defined [-fpermissive]
   virtual ReturnType visitConst(Const *curr) = 0;
                      ^
src/wasm.h:1010:22: error: ‘ReturnType wasm::WasmVisitor<ReturnType>::visitUnary(wasm::Unary*) [with ReturnType = wasm::ModuleInstance::callFunction(cashew::IString, wasm::ModuleInstance::LiteralList&)::Flow]’, declared using local type ‘wasm::ModuleInstance::callFunction(cashew::IString, wasm::ModuleInstance::LiteralList&)::Flow’, is used but never defined [-fpermissive]
   virtual ReturnType visitUnary(Unary *curr) = 0;
                      ^
src/wasm.h:1011:22: error: ‘ReturnType wasm::WasmVisitor<ReturnType>::visitBinary(wasm::Binary*) [with ReturnType = wasm::ModuleInstance::callFunction(cashew::IString, wasm::ModuleInstance::LiteralList&)::Flow]’, declared using local type ‘wasm::ModuleInstance::callFunction(cashew::IString, wasm::ModuleInstance::LiteralList&)::Flow’, is used but never defined [-fpermissive]
   virtual ReturnType visitBinary(Binary *curr) = 0;
                      ^
src/wasm.h:1012:22: error: ‘ReturnType wasm::WasmVisitor<ReturnType>::visitCompare(wasm::Compare*) [with ReturnType = wasm::ModuleInstance::callFunction(cashew::IString, wasm::ModuleInstance::LiteralList&)::Flow]’, declared using local type ‘wasm::ModuleInstance::callFunction(cashew::IString, wasm::ModuleInstance::LiteralList&)::Flow’, is used but never defined [-fpermissive]
   virtual ReturnType visitCompare(Compare *curr) = 0;
                      ^
src/wasm.h:1013:22: error: ‘ReturnType wasm::WasmVisitor<ReturnType>::visitConvert(wasm::Convert*) [with ReturnType = wasm::ModuleInstance::callFunction(cashew::IString, wasm::ModuleInstance::LiteralList&)::Flow]’, declared using local type ‘wasm::ModuleInstance::callFunction(cashew::IString, wasm::ModuleInstance::LiteralList&)::Flow’, is used but never defined [-fpermissive]
   virtual ReturnType visitConvert(Convert *curr) = 0;
                      ^
src/wasm.h:1014:22: error: ‘ReturnType wasm::WasmVisitor<ReturnType>::visitSelect(wasm::Select*) [with ReturnType = wasm::ModuleInstance::callFunction(cashew::IString, wasm::ModuleInstance::LiteralList&)::Flow]’, declared using local type ‘wasm::ModuleInstance::callFunction(cashew::IString, wasm::ModuleInstance::LiteralList&)::Flow’, is used but never defined [-fpermissive]
   virtual ReturnType visitSelect(Select *curr) = 0;
                      ^
src/wasm.h:1015:22: error: ‘ReturnType wasm::WasmVisitor<ReturnType>::visitHost(wasm::Host*) [with ReturnType = wasm::ModuleInstance::callFunction(cashew::IString, wasm::ModuleInstance::LiteralList&)::Flow]’, declared using local type ‘wasm::ModuleInstance::callFunction(cashew::IString, wasm::ModuleInstance::LiteralList&)::Flow’, is used but never defined [-fpermissive]
   virtual ReturnType visitHost(Host *curr) = 0;
                      ^
src/wasm.h:1016:22: error: ‘ReturnType wasm::WasmVisitor<ReturnType>::visitNop(wasm::Nop*) [with ReturnType = wasm::ModuleInstance::callFunction(cashew::IString, wasm::ModuleInstance::LiteralList&)::Flow]’, declared using local type ‘wasm::ModuleInstance::callFunction(cashew::IString, wasm::ModuleInstance::LiteralList&)::Flow’, is used but never defined [-fpermissive]
   virtual ReturnType visitNop(Nop *curr) = 0;
                      ^
@kripken
Copy link
Member

kripken commented Nov 6, 2015

The em++: command not found is because you need emscripten in your path, if you want to build the js parts. But you don't need it for asm2wasm or wasm-shell.

The others are a gcc bug, it turns out. Building with newer gcc, or clang, should avoid those. I haven't been able to find a workaround for older gcc.

@drom
Copy link
Author

drom commented Nov 6, 2015

Thank you. Yes, it looks like I am using LLVM-3.5 and I probably need to switch to 3.7. As of GCC I am using 4.8. What is the minimum requirement here?

@kripken
Copy link
Member

kripken commented Nov 6, 2015

This is the bug, I'm not sure how to figure out which gcc release that ends up in. But based on the dates, I think at least 5.0.

@cosinusoidally
Copy link

Looking at https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51048#c3 it appears that the below patch is sufficient to get wasm-shell to compile on GCC 4.8.2 in Ubuntu 14.04. I haven't run the test suite though.

Looking at the GCC site it is difficult to tell when the fix was added. Considering the bug report makes no mention of any of the stable branches of GCC, I would assume the fix is not in any stable release of GCC (and probably not available the default system GCC in any current stable version of Ubuntu). To be sure the unit test in would need to be compiled with one of those very recent releases of GCC.

diff --git a/src/wasm.h b/src/wasm.h
index 0fd014a..8ca8e24 100644
--- a/src/wasm.h
+++ b/src/wasm.h
@@ -1065,27 +1065,27 @@ private:

 template<class ReturnType>
 struct WasmVisitor {
-  virtual ReturnType visitBlock(Block *curr) = 0;
-  virtual ReturnType visitIf(If *curr) = 0;
-  virtual ReturnType visitLoop(Loop *curr) = 0;
-  virtual ReturnType visitLabel(Label *curr) = 0;
-  virtual ReturnType visitBreak(Break *curr) = 0;
-  virtual ReturnType visitSwitch(Switch *curr) = 0;
-  virtual ReturnType visitCall(Call *curr) = 0;
-  virtual ReturnType visitCallImport(CallImport *curr) = 0;
-  virtual ReturnType visitCallIndirect(CallIndirect *curr) = 0;
-  virtual ReturnType visitGetLocal(GetLocal *curr) = 0;
-  virtual ReturnType visitSetLocal(SetLocal *curr) = 0;
-  virtual ReturnType visitLoad(Load *curr) = 0;
-  virtual ReturnType visitStore(Store *curr) = 0;
-  virtual ReturnType visitConst(Const *curr) = 0;
-  virtual ReturnType visitUnary(Unary *curr) = 0;
-  virtual ReturnType visitBinary(Binary *curr) = 0;
-  virtual ReturnType visitCompare(Compare *curr) = 0;
-  virtual ReturnType visitConvert(Convert *curr) = 0;
-  virtual ReturnType visitSelect(Select *curr) = 0;
-  virtual ReturnType visitHost(Host *curr) = 0;
-  virtual ReturnType visitNop(Nop *curr) = 0;
+  virtual ReturnType visitBlock(Block *curr) { }; 
+  virtual ReturnType visitIf(If *curr) { };
+  virtual ReturnType visitLoop(Loop *curr) { };
+  virtual ReturnType visitLabel(Label *curr) { };
+  virtual ReturnType visitBreak(Break *curr) { };
+  virtual ReturnType visitSwitch(Switch *curr) { };
+  virtual ReturnType visitCall(Call *curr) { }; 
+  virtual ReturnType visitCallImport(CallImport *curr) { };
+  virtual ReturnType visitCallIndirect(CallIndirect *curr) { };
+  virtual ReturnType visitGetLocal(GetLocal *curr) { };
+  virtual ReturnType visitSetLocal(SetLocal *curr) { };
+  virtual ReturnType visitLoad(Load *curr) { };
+  virtual ReturnType visitStore(Store *curr) { };
+  virtual ReturnType visitConst(Const *curr) { };
+  virtual ReturnType visitUnary(Unary *curr) { };
+  virtual ReturnType visitBinary(Binary *curr) { };
+  virtual ReturnType visitCompare(Compare *curr) { };
+  virtual ReturnType visitConvert(Convert *curr) { };
+  virtual ReturnType visitSelect(Select *curr) { };
+  virtual ReturnType visitHost(Host *curr) { };
+  virtual ReturnType visitNop(Nop *curr) { };

   ReturnType visit(Expression *curr) {
     assert(curr);

kripken added a commit that referenced this issue Nov 10, 2015
@kripken
Copy link
Member

kripken commented Nov 10, 2015

Thanks! I pushed a patch with aborts instead of pure virtual. It does build in gcc now. However it gives an error, which I don't have time to look into right now. (Note that the test suite is currently failing in the spec tests due to upstream spec changes, but a gcc build errors earlier.)

@kripken
Copy link
Member

kripken commented Nov 11, 2015

After recent changes, gcc seems to build and emit a working shell, so I think we can close this.

@kripken kripken closed this as completed Nov 11, 2015
@sletz sletz mentioned this issue Jan 4, 2016
aheejin added a commit to aheejin/binaryen that referenced this issue Feb 17, 2021
We decided to change `catch_all`'s opcode from 0x05, which is the same
as `else`, to 0x19, to avoid some complicated handling in the tools.

See: WebAssembly/exception-handling#147

---

dwarf_with_exceptions.wasm was added in WebAssembly#3496 but we didn't comment on
how that file was created, so I'll add some comment on that here, in
case we need to regenerate this file with some modifications. I
regenerated dwarf_with_exceptions.wasm, so some variable names and such
have changed.

cpp file:
```cpp
void foo();

void test_debuginfo() {
  try {
    foo();
  } catch (...) {
    foo();
  }
}
```

Run:
```
$ clang++ -std=c++14 -stdlib=libc++ --target=wasm32-unknown-unknown -fwasm-exceptions -Xclang -disable-O0-optnone -c -S -emit-llvm test_debuginfo.cpp -o temp.ll
$ opt -S -mem2reg -simplifycfg temp.ll -o test_debuginfo.ll
```
(`opt -mem2reg -simplifycfg` was run to make the code little tidier.
This basically promotes stack loads/saves to registers and simplifies
the CFG.)

Resulting ll file, after modifying some function names and removing
personal info in directory names:
```llvm
source_filename = "test_debuginfo.cpp"
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"

$__clang_call_terminate = comdat any

; Function Attrs: noinline mustprogress
define hidden void @test_debuginfo() #0 personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) !dbg !7 {
entry:
  invoke void @foo()
          to label %try.cont unwind label %catch.dispatch, !dbg !10

catch.dispatch:                                   ; preds = %entry
  %0 = catchswitch within none [label %catch.start] unwind to caller, !dbg !12

catch.start:                                      ; preds = %catch.dispatch
  %1 = catchpad within %0 [i8* null], !dbg !12
  %2 = call i8* @llvm.wasm.get.exception(token %1), !dbg !12
  %3 = call i32 @llvm.wasm.get.ehselector(token %1), !dbg !12
  %4 = call i8* @__cxa_begin_catch(i8* %2) WebAssembly#2 [ "funclet"(token %1) ], !dbg !12
  invoke void @foo() [ "funclet"(token %1) ]
          to label %invoke.cont1 unwind label %ehcleanup, !dbg !13

invoke.cont1:                                     ; preds = %catch.start
  call void @__cxa_end_catch() [ "funclet"(token %1) ], !dbg !15
  catchret from %1 to label %try.cont, !dbg !15

try.cont:                                         ; preds = %entry, %invoke.cont1
  ret void, !dbg !16

ehcleanup:                                        ; preds = %catch.start
  %5 = cleanuppad within %1 [], !dbg !15
  invoke void @__cxa_end_catch() [ "funclet"(token %5) ]
          to label %invoke.cont2 unwind label %terminate, !dbg !15

invoke.cont2:                                     ; preds = %ehcleanup
  cleanupret from %5 unwind to caller, !dbg !15

terminate:                                        ; preds = %ehcleanup
  %6 = cleanuppad within %5 [], !dbg !15
  %7 = call i8* @llvm.wasm.get.exception(token %6), !dbg !15
  call void @__clang_call_terminate(i8* %7) WebAssembly#5 [ "funclet"(token %6) ], !dbg !15
  unreachable, !dbg !15
}

declare void @foo() WebAssembly#1

declare i32 @__gxx_wasm_personality_v0(...)

; Function Attrs: nounwind
declare i8* @llvm.wasm.get.exception(token) WebAssembly#2

; Function Attrs: nounwind
declare i32 @llvm.wasm.get.ehselector(token) WebAssembly#2

; Function Attrs: nounwind readnone
declare i32 @llvm.eh.typeid.for(i8*) WebAssembly#3

declare i8* @__cxa_begin_catch(i8*)

declare void @__cxa_end_catch()

; Function Attrs: noinline noreturn nounwind
define linkonce_odr hidden void @__clang_call_terminate(i8* %0) WebAssembly#4 comdat {
  %2 = call i8* @__cxa_begin_catch(i8* %0) WebAssembly#2
  call void @_ZSt9terminatev() WebAssembly#5
  unreachable
}

declare void @_ZSt9terminatev()

attributes #0 = { noinline mustprogress "disable-tail-calls"="false" "frame-pointer"="none" "min-legal-vector-width"="0" "no-jump-tables"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic" "target-features"="+exception-handling" }
attributes WebAssembly#1 = { "disable-tail-calls"="false" "frame-pointer"="none" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic" "target-features"="+exception-handling" }
attributes WebAssembly#2 = { nounwind }
attributes WebAssembly#3 = { nounwind readnone }
attributes WebAssembly#4 = { noinline noreturn nounwind }
attributes WebAssembly#5 = { noreturn nounwind }

!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!3, !4, !5}
!llvm.ident = !{!6}

!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 13.0.0 (https://github.com/llvm/llvm-project.git 3c4c205060c9398da705eb71b63ddd8a04999de9)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
!1 = !DIFile(filename: "test_debuginfo.cpp", directory: "/")
!2 = !{}
!3 = !{i32 7, !"Dwarf Version", i32 4}
!4 = !{i32 2, !"Debug Info Version", i32 3}
!5 = !{i32 1, !"wchar_size", i32 4}
!6 = !{!"clang version 13.0.0 (https://github.com/llvm/llvm-project.git 3c4c205060c9398da705eb71b63ddd8a04999de9)"}
!7 = distinct !DISubprogram(name: "test_debuginfo", linkageName: "test_debuginfo", scope: !1, file: !1, line: 3, type: !8, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
!8 = !DISubroutineType(types: !9)
!9 = !{null}
!10 = !DILocation(line: 5, column: 5, scope: !11)
!11 = distinct !DILexicalBlock(scope: !7, file: !1, line: 4, column: 7)
!12 = !DILocation(line: 6, column: 3, scope: !11)
!13 = !DILocation(line: 7, column: 5, scope: !14)
!14 = distinct !DILexicalBlock(scope: !7, file: !1, line: 6, column: 17)
!15 = !DILocation(line: 8, column: 3, scope: !14)
!16 = !DILocation(line: 9, column: 1, scope: !7)
```

Run:
```
llc -exception-model=wasm -mattr=+exception-handling -filetype=obj test_debuginfo.ll -o test_debuginfo.o
wasm-ld --no-entry --no-gc-sections --allow-undefined test_debuginfo.o -o test_debuginfo.wasm
```
aheejin added a commit to aheejin/binaryen that referenced this issue Feb 17, 2021
We decided to change `catch_all`'s opcode from 0x05, which is the same
as `else`, to 0x19, to avoid some complicated handling in the tools.

See: WebAssembly/exception-handling#147

---

dwarf_with_exceptions.wasm was added in WebAssembly#3496 but we didn't comment on
how that file was created, so I'll add some comment on that here, in
case we need to regenerate this file with some modifications. I
regenerated dwarf_with_exceptions.wasm, so some variable names and such
have changed.

cpp file:
```cpp
void foo();

void test_debuginfo() {
  try {
    foo();
  } catch (...) {
    foo();
  }
}
```

Run:
```
$ clang++ -std=c++14 -stdlib=libc++ --target=wasm32-unknown-unknown -fwasm-exceptions -Xclang -disable-O0-optnone -c -S -emit-llvm test_debuginfo.cpp -o temp.ll
$ opt -S -mem2reg -simplifycfg temp.ll -o test_debuginfo.ll
```
(`opt -mem2reg -simplifycfg` was run to make the code little tidier.
This basically promotes stack loads/saves to registers and simplifies
the CFG.)

Resulting ll file, after modifying some function names and removing
personal info in directory names:
```llvm
source_filename = "test_debuginfo.cpp"
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"

$__clang_call_terminate = comdat any

; Function Attrs: noinline mustprogress
define hidden void @test_debuginfo() #0 personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) !dbg !7 {
entry:
  invoke void @foo()
          to label %try.cont unwind label %catch.dispatch, !dbg !10

catch.dispatch:                                   ; preds = %entry
  %0 = catchswitch within none [label %catch.start] unwind to caller, !dbg !12

catch.start:                                      ; preds = %catch.dispatch
  %1 = catchpad within %0 [i8* null], !dbg !12
  %2 = call i8* @llvm.wasm.get.exception(token %1), !dbg !12
  %3 = call i32 @llvm.wasm.get.ehselector(token %1), !dbg !12
  %4 = call i8* @__cxa_begin_catch(i8* %2) WebAssembly#2 [ "funclet"(token %1) ], !dbg !12
  invoke void @foo() [ "funclet"(token %1) ]
          to label %invoke.cont1 unwind label %ehcleanup, !dbg !13

invoke.cont1:                                     ; preds = %catch.start
  call void @__cxa_end_catch() [ "funclet"(token %1) ], !dbg !15
  catchret from %1 to label %try.cont, !dbg !15

try.cont:                                         ; preds = %entry, %invoke.cont1
  ret void, !dbg !16

ehcleanup:                                        ; preds = %catch.start
  %5 = cleanuppad within %1 [], !dbg !15
  invoke void @__cxa_end_catch() [ "funclet"(token %5) ]
          to label %invoke.cont2 unwind label %terminate, !dbg !15

invoke.cont2:                                     ; preds = %ehcleanup
  cleanupret from %5 unwind to caller, !dbg !15

terminate:                                        ; preds = %ehcleanup
  %6 = cleanuppad within %5 [], !dbg !15
  %7 = call i8* @llvm.wasm.get.exception(token %6), !dbg !15
  call void @__clang_call_terminate(i8* %7) WebAssembly#5 [ "funclet"(token %6) ], !dbg !15
  unreachable, !dbg !15
}

declare void @foo() WebAssembly#1

declare i32 @__gxx_wasm_personality_v0(...)

; Function Attrs: nounwind
declare i8* @llvm.wasm.get.exception(token) WebAssembly#2

; Function Attrs: nounwind
declare i32 @llvm.wasm.get.ehselector(token) WebAssembly#2

; Function Attrs: nounwind readnone
declare i32 @llvm.eh.typeid.for(i8*) WebAssembly#3

declare i8* @__cxa_begin_catch(i8*)

declare void @__cxa_end_catch()

; Function Attrs: noinline noreturn nounwind
define linkonce_odr hidden void @__clang_call_terminate(i8* %0) WebAssembly#4 comdat {
  %2 = call i8* @__cxa_begin_catch(i8* %0) WebAssembly#2
  call void @_ZSt9terminatev() WebAssembly#5
  unreachable
}

declare void @_ZSt9terminatev()

attributes #0 = { noinline mustprogress "disable-tail-calls"="false" "frame-pointer"="none" "min-legal-vector-width"="0" "no-jump-tables"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic" "target-features"="+exception-handling" }
attributes WebAssembly#1 = { "disable-tail-calls"="false" "frame-pointer"="none" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic" "target-features"="+exception-handling" }
attributes WebAssembly#2 = { nounwind }
attributes WebAssembly#3 = { nounwind readnone }
attributes WebAssembly#4 = { noinline noreturn nounwind }
attributes WebAssembly#5 = { noreturn nounwind }

!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!3, !4, !5}
!llvm.ident = !{!6}

!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 13.0.0 (https://github.com/llvm/llvm-project.git 3c4c205060c9398da705eb71b63ddd8a04999de9)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
!1 = !DIFile(filename: "test_debuginfo.cpp", directory: "/")
!2 = !{}
!3 = !{i32 7, !"Dwarf Version", i32 4}
!4 = !{i32 2, !"Debug Info Version", i32 3}
!5 = !{i32 1, !"wchar_size", i32 4}
!6 = !{!"clang version 13.0.0 (https://github.com/llvm/llvm-project.git 3c4c205060c9398da705eb71b63ddd8a04999de9)"}
!7 = distinct !DISubprogram(name: "test_debuginfo", linkageName: "test_debuginfo", scope: !1, file: !1, line: 3, type: !8, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
!8 = !DISubroutineType(types: !9)
!9 = !{null}
!10 = !DILocation(line: 5, column: 5, scope: !11)
!11 = distinct !DILexicalBlock(scope: !7, file: !1, line: 4, column: 7)
!12 = !DILocation(line: 6, column: 3, scope: !11)
!13 = !DILocation(line: 7, column: 5, scope: !14)
!14 = distinct !DILexicalBlock(scope: !7, file: !1, line: 6, column: 17)
!15 = !DILocation(line: 8, column: 3, scope: !14)
!16 = !DILocation(line: 9, column: 1, scope: !7)
```

Run:
```
$ llc -exception-model=wasm -mattr=+exception-handling -filetype=obj test_debuginfo.ll -o test_debuginfo.o
$ wasm-ld --no-entry --no-gc-sections --allow-undefined test_debuginfo.o -o test_debuginfo.wasm
```
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

No branches or pull requests

3 participants