<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/81486>81486</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            wasm import attributes don't work together with constructor/destructor attributes
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          TerrorJack
      </td>
    </tr>
</table>

<pre>
    Minimum repro:

```c
__attribute__((import_module("foo"), import_name("bar"), constructor)) void foobar(void);

extern void __wasm_call_ctors(void);

__attribute__((export_name("_start")))
void _start(void) {
  __wasm_call_ctors();
}
```

When compiled with `clang --target=wasm32 -nostdlib asdf.c -o asdf.wasm`, it produces the following wasm module:

```wat
(module
  (type (;0;) (func))
 (func $__wasm_call_ctors (type 0))
  (func $_start (type 0)
    call $__wasm_call_ctors
    return)
  (table (;0;) 1 1 funcref)
  (memory (;0;) 2)
  (global $__stack_pointer (mut i32) (i32.const 66560))
 (export "memory" (memory 0))
  (export "_start" (func $_start)))
```

So `__wasm_call_ctors` does nothing, but this isn't expected behavior, it's supposed to call into the `foobar` import! If I call the `foobar` import in a separate ctor like this:

```c
__attribute__((import_module("foo"), import_name("bar"))) void foobar(void);

__attribute__((constructor)) void call_foobar(void) { foobar(); }
```

Then I get the wasm module with desired behavior:

```wat
(module
  (type (;0;) (func))
 (import "foo" "bar" (func $foobar (type 0)))
  (func $__wasm_call_ctors (type 0)
    call $call_foobar)
  (func $call_foobar (type 0)
    call $foobar
    return)
  (func $_start (type 0)
 call $__wasm_call_ctors
    return)
  (table (;0;) 1 1 funcref)
 (memory (;0;) 2)
  (global $__stack_pointer (mut i32) (i32.const 66560))
  (export "memory" (memory 0))
  (export "_start" (func $_start)))
```

The same issue exists for dtors as well, and the issue reproduces on both clang trunk and latest release 17.0.6.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzEVk1vqzgU_TXO5ioRGAJkwWI6VaSONKupNEtk4AY8NTayL03770c2tPls32zeGwmFYB8fHx9fHxDOyU4jlmz7wLaPKzFRb2z5jNYa-4doXla1ad_LP6WWwzSAxdEalvzGokcWffxm0Xw183NVCSIr64mwqhgvGC_kMBpL1WDaSWFo4gdjGOeM7xj_HZZ-LYaltxb21NsY7chODRkbWnbwamQLB2MCrPBPviN5OJeFb4RWz9CqOgo3VI1QqvI07stRd8Tj25W4ypGw9KEvXGHsPNXS-cEPLF8mgLsyLiTkj1eWnkv7u0cNjRlGqbCFo6QevOlK6A7WaxK2Q2LJo58i4bDWxlGrZA3CtYdNA2sz__P9ntnbTjBa004NOqAe4WCUMkepO_AgWLbri90-ClpaeLEgl2UyXtD7iP7OkofIL8_7wIvDpJtzwz7agPH0xptPmuhiyMWY4PUlcEEBeKa7xCeIRZqsvuQmUatr6THE4Oe0eLgEDzgY-36F5peYTplaLEociealGo3UhDYQTAQy4Ys_MuGbUOyQZdssurZqLkRgnM_zMs7PRNzadMJ_Vuyte1c1fLfy_jK-0m6NzCJoDTrQhnqpO19S9URAvXQgnWY8J8C3ERvCFmrsxav0R9gXHuO5AzeNo3HYApl5u6QmEyqRZdFyvLNoSQfGY3g6wNOM_AIEUoMAh6OwghC8TFDyBYOmX5tb_zmo7sz7ReIF66_ZfMCcppjp4fskefZJ8gQdUvDx7LDPsdKik_Z8y35uBCxb92kufBp5Xq7zEm9S4X4wfB8mNxlxYew9wjPAD6gWlm8z5sf59bPD69dm1_8aXs89ghMDgnRuQsA36cjBwVhoQ2UIB0dUyh9nodtwIGZk-NaZX45GQ22oh_llS3bSLwGsBKEjsKhQOIQ430SbbLNqy6TdJTuxwjLOozxPd1ESrfqyzuuWZ4e24FEe5bvtLuZZUyR1nRQN36ZiJUse8TTiMY_TNNlGG5HzgsdJkbZ5Kup6x9IIByHVRqnXYWNstwpayyJOi2ylRI3KhU85zjUe54X4QNo-rmzpx6zrqXMsjZR34cRCkhSWIQiW0_iZSQ5aM0f50dgXINMh9WjnpLgIqn2LHw9nw1eTVWVPNIb85XvG952kfqo3jRkY33sNy209WvMPNsT4Pih3jO_Dyv4NAAD__1VDJTw">