mozilla / mozilla/cbindgen

`test_body` fails with C++20 P1766R1, `non-c-typedef-for-linkage`

Open
#1,129 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
3k
Forks
386
Avg merge
1h 43m
Merged PRs (30d)
1

Description

Since Clang 11 (commit 7ae1b4a0ce9c) and soon in GCC 16 (commit 828c48f0680e), test_body fails on non-c-typedef-for-linkage.

With clang-21.1.8-6.fc44.x86_64:
Running: "/root/cbindgen/target/debug/cbindgen" "--output" "/root/cbindgen/tests/expectations/body.compat.c" "--depfile" "/tmp/.tmpJyyVas" "--lang" "c" "--cpp-compat" "--style" "type" "--config" "/root/cbindgen/tests/rust/body.toml" "/root/cbindgen/tests/rust/body.rs"
Running: "clang" "-D" "DEFINED" "-I" "/root/cbindgen/tests" "-Wall" "-Werror" "-Wno-attributes" "-Wno-unused-const-variable" "-Wno-return-type-c-linkage" "-Wno-deprecated-declarations" "-D" "CBINDGEN_STYLE_TYPE" "-D" "CBINDGEN_CPP_COMPAT" "-o" "/tmp/cbindgen-test-outputIdxH5u/body.compat.o" "-c" "/root/cbindgen/tests/expectations/body.compat.c"
Running: "clang++" "-D" "DEFINED" "-I" "/root/cbindgen/tests" "-Wall" "-Werror" "-Wno-attributes" "-Wno-unused-const-variable" "-Wno-return-type-c-linkage" "-Wno-deprecated-declarations" "-std=c++17" "-x" "c++" "-D" "CBINDGEN_STYLE_TYPE" "-D" "CBINDGEN_CPP_COMPAT" "-o" "/tmp/cbindgen-test-outputIdxH5u/body.compat.o" "-c" "/root/cbindgen/tests/expectations/body.compat.c"

thread 'test_body' (37465) panicked at tests/tests.rs:214:5:
Output failed to compile: Output { status: ExitStatus(unix_wait_status(256)), stdout: "", stderr: "/root/cbindgen/tests/expectations/body.compat.c:18:15: error: anonymous non-C-compatible type given name for linkage purposes by typedef declaration; add a tag name here [-Werror,-Wnon-c-typedef-for-linkage]\n   18 | typedef struct {\n      |               ^\n      |                MyFancyStruct\n/root/cbindgen/tests/expectations/body.compat.c:21:5: note: type is not C-compatible due to this member declaration\n   21 |     inline void foo();\n      |     ^~~~~~~~~~~~~~~~~\n/root/cbindgen/tests/expectations/body.compat.c:23:3: note: type is given name 'MyFancyStruct' for linkage purposes by this typedef declaration\n   23 | } MyFancyStruct;\n      |   ^\n/root/cbindgen/tests/expectations/body.compat.c:31:15: error: anonymous non-C-compatible type given name for linkage purposes by typedef declaration; add a tag name here [-Werror,-Wnon-c-typedef-for-linkage]\n   31 | typedef struct {\n      |               ^\n      |                MyFancyEnum\n/root/cbindgen/tests/expectations/body.compat.c:42:5: note: type is not C-compatible due to this member declaration\n   42 |     inline void wohoo();\n      |     ^~~~~~~~~~~~~~~~~~~\n/root/cbindgen/tests/expectations/body.compat.c:44:3: note: type is given name 'MyFancyEnum' for linkage purposes by this typedef declaration\n   44 | } MyFancyEnum;\n      |   ^\n/root/cbindgen/tests/expectations/body.compat.c:52:15: error: anonymous non-C-compatible type given name for linkage purposes by typedef declaration; add a tag name here [-Werror,-Wnon-c-typedef-for-linkage]\n   52 | typedef struct {\n      |               ^\n      |                MyFancyStruct_Prepended\n/root/cbindgen/tests/expectations/body.compat.c:54:5: note: type is not C-compatible due to this member declaration\n   54 |     inline void prepended_wohoo();\n      |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n/root/cbindgen/tests/expectations/body.compat.c:57:3: note: type is given name 'MyFancyStruct_Prepended' for linkage purposes by this typedef declaration\n   57 | } MyFancyStruct_Prepended;\n      |   ^\n/root/cbindgen/tests/expectations/body.compat.c:65:15: error: anonymous non-C-compatible type given name for linkage purposes by typedef declaration; add a tag name here [-Werror,-Wnon-c-typedef-for-linkage]\n   65 | typedef struct {\n      |               ^\n      |                MyFancyEnum_Prepended\n/root/cbindgen/tests/expectations/body.compat.c:67:5: note: type is not C-compatible due to this member declaration\n   67 |     inline void wohoo();\n      |     ^~~~~~~~~~~~~~~~~~~\n/root/cbindgen/tests/expectations/body.compat.c:78:3: note: type is given name 'MyFancyEnum_Prepended' for linkage purposes by this typedef declaration\n   78 | } MyFancyEnum_Prepended;\n      |   ^\n4 errors generated.\n" }
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
newline-expanded clang stderr:
/root/cbindgen/tests/expectations/body.compat.c:18:15: error: anonymous non-C-compatible type given name for linkage purposes by typedef declaration; add a tag name here [-Werror,-Wnon-c-typedef-for-linkage]
   18 | typedef struct {
      |               ^
      |                MyFancyStruct
/root/cbindgen/tests/expectations/body.compat.c:21:5: note: type is not C-compatible due to this member declaration
   21 |     inline void foo();
      |     ^~~~~~~~~~~~~~~~~
/root/cbindgen/tests/expectations/body.compat.c:23:3: note: type is given name 'MyFancyStruct' for linkage purposes by this typedef declaration
   23 | } MyFancyStruct;
      |   ^
/root/cbindgen/tests/expectations/body.compat.c:31:15: error: anonymous non-C-compatible type given name for linkage purposes by typedef declaration; add a tag name here [-Werror,-Wnon-c-typedef-for-linkage]
   31 | typedef struct {
      |               ^
      |                MyFancyEnum
/root/cbindgen/tests/expectations/body.compat.c:42:5: note: type is not C-compatible due to this member declaration
   42 |     inline void wohoo();
      |     ^~~~~~~~~~~~~~~~~~~
/root/cbindgen/tests/expectations/body.compat.c:44:3: note: type is given name 'MyFancyEnum' for linkage purposes by this typedef declaration
   44 | } MyFancyEnum;
      |   ^
/root/cbindgen/tests/expectations/body.compat.c:52:15: error: anonymous non-C-compatible type given name for linkage purposes by typedef declaration; add a tag name here [-Werror,-Wnon-c-typedef-for-linkage]
   52 | typedef struct {
      |               ^
      |                MyFancyStruct_Prepended
/root/cbindgen/tests/expectations/body.compat.c:54:5: note: type is not C-compatible due to this member declaration
   54 |     inline void prepended_wohoo();
      |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/root/cbindgen/tests/expectations/body.compat.c:57:3: note: type is given name 'MyFancyStruct_Prepended' for linkage purposes by this typedef declaration
   57 | } MyFancyStruct_Prepended;
      |   ^
/root/cbindgen/tests/expectations/body.compat.c:65:15: error: anonymous non-C-compatible type given name for linkage purposes by typedef declaration; add a tag name here [-Werror,-Wnon-c-typedef-for-linkage]
   65 | typedef struct {
      |               ^
      |                MyFancyEnum_Prepended
/root/cbindgen/tests/expectations/body.compat.c:67:5: note: type is not C-compatible due to this member declaration
   67 |     inline void wohoo();
      |     ^~~~~~~~~~~~~~~~~~~
/root/cbindgen/tests/expectations/body.compat.c:78:3: note: type is given name 'MyFancyEnum_Prepended' for linkage purposes by this typedef declaration
   78 | } MyFancyEnum_Prepended;
      |   ^
4 errors generated.
With gcc-16.0.1-0.5.fc44.x86_64:
Running: "/root/cbindgen/target/debug/cbindgen" "--output" "/root/cbindgen/tests/expectations/body.compat.c" "--depfile" "/tmp/.tmp4IgFnp" "--lang" "c" "--cpp-compat" "--style" "type" "--config" "/root/cbindgen/tests/rust/body.toml" "/root/cbindgen/tests/rust/body.rs"
Running: "gcc" "-D" "DEFINED" "-I" "/root/cbindgen/tests" "-Wall" "-Werror" "-Wno-attributes" "-Wno-unused-const-variable" "-Wno-return-type-c-linkage" "-Wno-deprecated-declarations" "-D" "CBINDGEN_STYLE_TYPE" "-D" "CBINDGEN_CPP_COMPAT" "-o" "/tmp/cbindgen-test-outputHh99aD/body.compat.o" "-c" "/root/cbindgen/tests/expectations/body.compat.c"
Running: "g++" "-D" "DEFINED" "-I" "/root/cbindgen/tests" "-Wall" "-Werror" "-Wno-attributes" "-Wno-unused-const-variable" "-Wno-return-type-c-linkage" "-Wno-deprecated-declarations" "-std=c++17" "-x" "c++" "-D" "CBINDGEN_STYLE_TYPE" "-D" "CBINDGEN_CPP_COMPAT" "-o" "/tmp/cbindgen-test-outputHh99aD/body.compat.o" "-c" "/root/cbindgen/tests/expectations/body.compat.c"

thread 'test_body' (37474) panicked at tests/tests.rs:214:5:
Output failed to compile: Output { status: ExitStatus(unix_wait_status(256)), stdout: "", stderr: "/root/cbindgen/tests/expectations/body.compat.c:18:16: error: anonymous non-C-compatible type given name for linkage purposes by ‘typedef’ declaration [-Werror=non-c-typedef-for-linkage]\n   18 | typedef struct {\n      |                ^\n      |                MyFancyStruct\n/root/cbindgen/tests/expectations/body.compat.c:21:17: note: type is not C-compatible because it contains ‘void MyFancyStruct::foo()’ declaration\n   21 |     inline void foo();\n      |                 ^~~\n/root/cbindgen/tests/expectations/body.compat.c:31:16: error: anonymous non-C-compatible type given name for linkage purposes by ‘typedef’ declaration [-Werror=non-c-typedef-for-linkage]\n   31 | typedef struct {\n      |                ^\n      |                MyFancyEnum\n/root/cbindgen/tests/expectations/body.compat.c:42:17: note: type is not C-compatible because it contains ‘void MyFancyEnum::wohoo()’ declaration\n   42 |     inline void wohoo();\n      |                 ^~~~~\n/root/cbindgen/tests/expectations/body.compat.c:52:16: error: anonymous non-C-compatible type given name for linkage purposes by ‘typedef’ declaration [-Werror=non-c-typedef-for-linkage]\n   52 | typedef struct {\n      |                ^\n      |                MyFancyStruct_Prepended\n/root/cbindgen/tests/expectations/body.compat.c:54:17: note: type is not C-compatible because it contains ‘void MyFancyStruct_Prepended::prepended_wohoo()’ declaration\n   54 |     inline void prepended_wohoo();\n      |                 ^~~~~~~~~~~~~~~\n/root/cbindgen/tests/expectations/body.compat.c:65:16: error: anonymous non-C-compatible type given name for linkage purposes by ‘typedef’ declaration [-Werror=non-c-typedef-for-linkage]\n   65 | typedef struct {\n      |                ^\n      |                MyFancyEnum_Prepended\n/root/cbindgen/tests/expectations/body.compat.c:67:17: note: type is not C-compatible because it contains ‘void MyFancyEnum_Prepended::wohoo()’ declaration\n   67 |     inline void wohoo();\n      |                 ^~~~~\ncc1plus: note: unrecognized command-line option ‘-Wno-return-type-c-linkage’ may have been intended to silence earlier diagnostics\ncc1plus: all warnings being treated as errors\n" }
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
newline-expanded gcc stderr:
/root/cbindgen/tests/expectations/body.compat.c:18:16: error: anonymous non-C-compatible type given name for linkage purposes by ‘typedef’ declaration [-Werror=non-c-typedef-for-linkage]
   18 | typedef struct {
      |                ^
      |                MyFancyStruct
/root/cbindgen/tests/expectations/body.compat.c:21:17: note: type is not C-compatible because it contains ‘void MyFancyStruct::foo()’ declaration
   21 |     inline void foo();
      |                 ^~~
/root/cbindgen/tests/expectations/body.compat.c:31:16: error: anonymous non-C-compatible type given name for linkage purposes by ‘typedef’ declaration [-Werror=non-c-typedef-for-linkage]
   31 | typedef struct {
      |                ^
      |                MyFancyEnum
/root/cbindgen/tests/expectations/body.compat.c:42:17: note: type is not C-compatible because it contains ‘void MyFancyEnum::wohoo()’ declaration
   42 |     inline void wohoo();
      |                 ^~~~~
/root/cbindgen/tests/expectations/body.compat.c:52:16: error: anonymous non-C-compatible type given name for linkage purposes by ‘typedef’ declaration [-Werror=non-c-typedef-for-linkage]
   52 | typedef struct {
      |                ^
      |                MyFancyStruct_Prepended
/root/cbindgen/tests/expectations/body.compat.c:54:17: note: type is not C-compatible because it contains ‘void MyFancyStruct_Prepended::prepended_wohoo()’ declaration
   54 |     inline void prepended_wohoo();
      |                 ^~~~~~~~~~~~~~~
/root/cbindgen/tests/expectations/body.compat.c:65:16: error: anonymous non-C-compatible type given name for linkage purposes by ‘typedef’ declaration [-Werror=non-c-typedef-for-linkage]
   65 | typedef struct {
      |                ^
      |                MyFancyEnum_Prepended
/root/cbindgen/tests/expectations/body.compat.c:67:17: note: type is not C-compatible because it contains ‘void MyFancyEnum_Prepended::wohoo()’ declaration
   67 |     inline void wohoo();
      |                 ^~~~~
cc1plus: note: unrecognized command-line option ‘-Wno-return-type-c-linkage’ may have been intended to silence earlier diagnostics
cc1plus: all warnings being treated as errors

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with tests/tests.rs and the test_body case, then inspect tests/rust/body.rs and the generated tests/expectations/body.compat.c. Reproduce the failure with the Clang and GCC commands shown in the issue, and trace how the C++-compatibility output is produced. Done means test_body compiles successfully with the newer compiler diagnostics enabled.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, cpp, rust
Domain
compilers, testing-qa
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.