FAILED: patch "[PATCH] rust: rust_is_available: warn for `bindgen` < 0.72.1 &&" failed to apply to 6.18-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 6.18-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.18.y
git checkout FETCH_HEAD
git cherry-pick -x dc01dfb37b34beeefcfe1c3055364d41a4070c7e
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026090302-mumbo-scorebook-4564@gregkh' --subject-prefix 'PATCH 6.18.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From dc01dfb37b34beeefcfe1c3055364d41a4070c7e Mon Sep 17 00:00:00 2001
From: Miguel Ojeda <[email protected]>
Date: Sun, 19 Jul 2026 14:05:14 +0200
Subject: [PATCH] rust: rust_is_available: warn for bindgen < 0.72.1 &&
libclang >= 22
Starting with LLVM 22, clang_getTypeDeclaration() may return a forward declaration instead of the type definition. This made bindgen generate opaque types [1][2], which in turn made us fail with e.g.
error[E0609]: no field `__bindgen_anon_1` on type `bindings::kernel_param`
--> rust/kernel/module_param.rs:78:46
|
78 | let container = unsafe { &*((*param).__bindgen_anon_1.arg.cast::<SetOnce<T>>()) };
| ^^^^^^^^^^^^^^^^ unknown field
|
= note: available field is: `_address`This was fixed in bindgen 0.72.1 [3].
In order to clarify what is going on and avoid confusion [4][5], add a warning to rust_is_available.sh about it when the versions match, similar to past warnings like the one removed in:
commit ae64324ad5c1 ("rust: rust_is_available: remove warning for `bindgen` < 0.69.5 && libclang >= 19.1")In addition, even if the versions match, check if the issue appears to not reproduce with the given binaries, to avoid a warning in such a case.
Finally, include tests.
[ Nathan, in parallel, updated the instructions of the LLVM+Rust
kernel.org toolchains [6] so that --version is not passed to cargo for bindgen, and thus the latest bindgen is installed by default, which should help to avoid some of these situations.
Thanks!
- Miguel ]
scripts/rust_is_available.sh +14 -0
@@ -208,6 +208,20 @@ if [ "$bindgen_libclang_cversion" -lt "$bindgen_libclang_min_cversion" ]; then exit 1 fi +if [ "$bindgen_libclang_cversion" -ge 2200000 ] && + [ "$rust_bindings_generator_cversion" -lt 7201 ]; then + # Distributions may have patched the issue. + if ! "$BINDGEN" $(dirname $0)/rust_is_available_bindgen_libclang_22.h | grep -q 'pub foo'; then + echo >&2 "***" + echo >&2 "*** Rust bindings generator '$BINDGEN' < 0.72.1 together with libclang >= 22" + echo >&2 "*** may not work due to a bug (https://github.com/rust-lang/rust-bindgen/pull/3278)." + echo >&2 "*** Your bindgen version: $rust_bindings_generator_version" + echo >&2 "*** Your libclang version: $bindgen_libclang_version" + echo >&2 "***" + warning=1 + fi +fi + # If the C compiler is Clang, then we can also check whether its version # matches the `libclang` version used by the Rust bindings generator. #
scripts/rust_is_available_bindgen_libclang_22.h new file +5 -0
@@ -0,0 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +struct S ; +struct S { +int foo; +};
scripts/rust_is_available_test.py +29 -1
@@ -54,16 +54,23 @@ else: """) @classmethod - def generate_bindgen(cls, version_stdout, libclang_stderr): + def generate_bindgen(cls, version_stdout, libclang_stderr, libclang_22_patched=False): if libclang_stderr is None: libclang_case = f"raise SystemExit({cls.bindgen_default_bindgen_libclang_failure_exit_code})" else: libclang_case = f"print({repr(libclang_stderr)}, file=sys.stderr)" + if libclang_22_patched: + libclang_22_case = "print('pub foo: ::std::os::raw::c_int,')" + else: + libclang_22_case = "pass" + return cls.generate_executable(f"""#!/usr/bin/env python3 import sys if "rust_is_available_bindgen_libclang.h" in " ".join(sys.argv): {libclang_case} +elif "rust_is_available_bindgen_libclang_22.h" in " ".join(sys.argv): + {libclang_22_case} else: print({repr(version_stdout)}) """)
@@ -260,6 +267,27 @@ else: result = self.run_script(self.Expected.FAILURE, { "BINDGEN": bindgen }) self.assertIn(f"libclang (used by the Rust bindings generator '{bindgen}') is too old.", result.stderr) + def test_bindgen_bad_libclang_22(self): + for (bindgen_version, libclang_version, expected_not_patched) in ( + ("0.71.1", "21.1.0", self.Expected.SUCCESS), + ("0.71.1", "22.0.0", self.Expected.SUCCESS_WITH_WARNINGS), + ("0.71.1", "22.1.0", self.Expected.SUCCESS_WITH_WARNINGS), + + ("0.72.0", "22.0.0", self.Expected.SUCCESS_WITH_WARNINGS), + + ("0.72.1", "22.0.0", self.Expected.SUCCESS), + ): + with self.subTest(bindgen_version=bindgen_version, libclang_version=libclang_version): + cc = self.generate_clang(f"clang version {libclang_version}") + libclang_stderr = f"scripts/rust_is_available_bindgen_libclang.h:2:9: warning: clang version {libclang_version} [-W#pragma-messages], err: false" + bindgen = self.generate_bindgen(f"bindgen {bindgen_version}", libclang_stderr) + result = self.run_script(expected_not_patched, { "BINDGEN": bindgen, "CC": cc }) + if expected_not_patched == self.Expected.SUCCESS_WITH_WARNINGS: + self.assertIn(f"Rust bindings generator '{bindgen}' < 0.72.1 together with libclang >= 22", result.stderr) + + bindgen = self.generate_bindgen(f"bindgen {bindgen_version}", libclang_stderr, libclang_22_patched=True) + result = self.run_script(self.Expected.SUCCESS, { "BINDGEN": bindgen, "CC": cc }) + def test_clang_matches_bindgen_libclang_different_bindgen(self): bindgen = self.generate_bindgen_libclang("scripts/rust_is_available_bindgen_libclang.h:2:9: warning: clang version 999.0.0 [-W#pragma-messages], err: false") result = self.run_script(self.Expected.SUCCESS_WITH_WARNINGS, { "BINDGEN": bindgen })
Sasha Levin
maintainerPATCH 1/3 rust: rust_is_available: remove warning for `bindgen` 0.66.[01]
From: Miguel Ojeda <[email protected]>
[ Upstream commit 41cfbb4295cf9fcdffa6c89ddc84dca2fa392c98 ]
It is not possible anymore to fall into the issue that this warning was alerting about given the bindgen version bump.
Thus simplify by removing the machinery behind it, including tests.
Stable-dep-of: dc01dfb37b34 ("rust: rust_is_available: warn for bindgen < 0.72.1 && libclang >= 22")
--- scripts/rust_is_available.sh | 13 ------------ scripts/rust_is_available_bindgen_0_66.h | 2 -- scripts/rust_is_available_test.py | 26 +++--------------------- 3 files changed, 3 insertions(+), 38 deletions(-) delete mode 100644 scripts/rust_is_available_bindgen_0_66.h
scripts/rust_is_available.sh +0 -13
@@ -163,19 +163,6 @@ if [ "$rust_bindings_generator_cversion" -lt "$rust_bindings_generator_min_cvers echo >&2 "***" exit 1 fi -if [ "$rust_bindings_generator_cversion" -eq 6600 ] || - [ "$rust_bindings_generator_cversion" -eq 6601 ]; then - # Distributions may have patched the issue (e.g. Debian did). - if ! "$BINDGEN" $(dirname $0)/rust_is_available_bindgen_0_66.h >/dev/null; then - echo >&2 "***" - echo >&2 "*** Rust bindings generator '$BINDGEN' versions 0.66.0 and 0.66.1 may not" - echo >&2 "*** work due to a bug (https://github.com/rust-lang/rust-bindgen/pull/2567)," - echo >&2 "*** unless patched (like Debian's)." - echo >&2 "*** Your version: $rust_bindings_generator_version" - echo >&2 "***" - warning=1 - fi -fi # Check that the `libclang` used by the Rust bindings generator is suitable. #
scripts/rust_is_available_bindgen_0_66.h deleted +0 -2
@@ -1,2 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#define A "\0"
scripts/rust_is_available_test.py +3 -23
@@ -54,17 +54,12 @@ else: """) @classmethod - def generate_bindgen(cls, version_stdout, libclang_stderr, version_0_66_patched=False, libclang_concat_patched=False): + def generate_bindgen(cls, version_stdout, libclang_stderr, libclang_concat_patched=False): if libclang_stderr is None: libclang_case = f"raise SystemExit({cls.bindgen_default_bindgen_libclang_failure_exit_code})" else: libclang_case = f"print({repr(libclang_stderr)}, file=sys.stderr)" - if version_0_66_patched: - version_0_66_case = "pass" - else: - version_0_66_case = "raise SystemExit(1)" - if libclang_concat_patched: libclang_concat_case = "print('pub static mut foofoo: ::std::os::raw::c_int;')" else:
@@ -74,8 +69,6 @@ else: import sys if "rust_is_available_bindgen_libclang.h" in " ".join(sys.argv): {libclang_case} -elif "rust_is_available_bindgen_0_66.h" in " ".join(sys.argv): - {version_0_66_case} elif "rust_is_available_bindgen_libclang_concat.h" in " ".join(sys.argv): {libclang_concat_case} else:
@@ -83,8 +76,8 @@ else: """) @classmethod - def generate_bindgen_version(cls, stdout, version_0_66_patched=False): - return cls.generate_bindgen(stdout, cls.bindgen_default_bindgen_libclang_stderr, version_0_66_patched) + def generate_bindgen_version(cls, stdout): + return cls.generate_bindgen(stdout, cls.bindgen_default_bindgen_libclang_stderr) @classmethod def generate_bindgen_libclang_failure(cls):
@@ -245,19 +238,6 @@ else: result = self.run_script(self.Expected.FAILURE, { "BINDGEN": bindgen }) self.assertIn(f"Rust bindings generator '{bindgen}' is too old.", result.stderr) - def test_bindgen_bad_version_0_66_0_and_0_66_1(self): - for version in ("0.66.0", "0.66.1"): - with self.subTest(version=version): - bindgen = self.generate_bindgen_version(f"bindgen {version}") - result = self.run_script(self.Expected.SUCCESS_WITH_WARNINGS, { "BINDGEN": bindgen }) - self.assertIn(f"Rust bindings generator '{bindgen}' versions 0.66.0 and 0.66.1 may not", result.stderr) - - def test_bindgen_bad_version_0_66_0_and_0_66_1_patched(self): - for version in ("0.66.0", "0.66.1"): - with self.subTest(version=version): - bindgen = self.generate_bindgen_version(f"bindgen {version}", True) - result = self.run_script(self.Expected.SUCCESS, { "BINDGEN": bindgen }) - def test_bindgen_libclang_failure(self): bindgen = self.generate_bindgen_libclang_failure() result = self.run_script(self.Expected.FAILURE, { "BINDGEN": bindgen })
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/3 rust: rust_is_available: remove warning for `bindgen` < 0.69.5 && libclang >= 19.1
From: Miguel Ojeda <[email protected]>
[ Upstream commit ae64324ad5c1fdefe479d77ecee975bc6b37467b ]
It is not possible anymore to fall into the issue that this warning was alerting about given the bindgen version bump.
Thus simplify by removing the machinery behind it, including tests.
Stable-dep-of: dc01dfb37b34 ("rust: rust_is_available: warn for bindgen < 0.72.1 && libclang >= 22")
--- scripts/rust_is_available.sh | 15 -------- ...ust_is_available_bindgen_libclang_concat.h | 3 -- scripts/rust_is_available_test.py | 34 +------------------ 3 files changed, 1 insertion(+), 51 deletions(-) delete mode 100644 scripts/rust_is_available_bindgen_libclang_concat.h
scripts/rust_is_available.sh +0 -15
@@ -214,21 +214,6 @@ if [ "$bindgen_libclang_cversion" -lt "$bindgen_libclang_min_cversion" ]; then exit 1 fi -if [ "$bindgen_libclang_cversion" -ge 1900100 ] && - [ "$rust_bindings_generator_cversion" -lt 6905 ]; then - # Distributions may have patched the issue (e.g. Debian did). - if ! "$BINDGEN" $(dirname $0)/rust_is_available_bindgen_libclang_concat.h | grep -q foofoo; then - echo >&2 "***" - echo >&2 "*** Rust bindings generator '$BINDGEN' < 0.69.5 together with libclang >= 19.1" - echo >&2 "*** may not work due to a bug (https://github.com/rust-lang/rust-bindgen/pull/2824)," - echo >&2 "*** unless patched (like Debian's)." - echo >&2 "*** Your bindgen version: $rust_bindings_generator_version" - echo >&2 "*** Your libclang version: $bindgen_libclang_version" - echo >&2 "***" - warning=1 - fi -fi - # If the C compiler is Clang, then we can also check whether its version # matches the `libclang` version used by the Rust bindings generator. #
scripts/rust_is_available_bindgen_libclang_concat.h deleted +0 -3
@@ -1,3 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#define F (x) int x##x -F (foo);
scripts/rust_is_available_test.py +1 -33
@@ -54,23 +54,16 @@ else: """) @classmethod - def generate_bindgen(cls, version_stdout, libclang_stderr, libclang_concat_patched=False): + def generate_bindgen(cls, version_stdout, libclang_stderr): if libclang_stderr is None: libclang_case = f"raise SystemExit({cls.bindgen_default_bindgen_libclang_failure_exit_code})" else: libclang_case = f"print({repr(libclang_stderr)}, file=sys.stderr)" - if libclang_concat_patched: - libclang_concat_case = "print('pub static mut foofoo: ::std::os::raw::c_int;')" - else: - libclang_concat_case = "pass" - return cls.generate_executable(f"""#!/usr/bin/env python3 import sys if "rust_is_available_bindgen_libclang.h" in " ".join(sys.argv): {libclang_case} -elif "rust_is_available_bindgen_libclang_concat.h" in " ".join(sys.argv): - {libclang_concat_case} else: print({repr(version_stdout)}) """)
@@ -255,31 +248,6 @@ else: result = self.run_script(self.Expected.FAILURE, { "BINDGEN": bindgen }) self.assertIn(f"libclang (used by the Rust bindings generator '{bindgen}') is too old.", result.stderr) - def test_bindgen_bad_libclang_concat(self): - for (bindgen_version, libclang_version, expected_not_patched) in ( - ("0.69.4", "18.0.0", self.Expected.SUCCESS), - ("0.69.4", "19.1.0", self.Expected.SUCCESS_WITH_WARNINGS), - ("0.69.4", "19.2.0", self.Expected.SUCCESS_WITH_WARNINGS), - - ("0.69.5", "18.0.0", self.Expected.SUCCESS), - ("0.69.5", "19.1.0", self.Expected.SUCCESS), - ("0.69.5", "19.2.0", self.Expected.SUCCESS), - - ("0.70.0", "18.0.0", self.Expected.SUCCESS), - ("0.70.0", "19.1.0", self.Expected.SUCCESS), - ("0.70.0", "19.2.0", self.Expected.SUCCESS), - ): - with self.subTest(bindgen_version=bindgen_version, libclang_version=libclang_version): - cc = self.generate_clang(f"clang version {libclang_version}") - libclang_stderr = f"scripts/rust_is_available_bindgen_libclang.h:2:9: warning: clang version {libclang_version} [-W#pragma-messages], err: false" - bindgen = self.generate_bindgen(f"bindgen {bindgen_version}", libclang_stderr) - result = self.run_script(expected_not_patched, { "BINDGEN": bindgen, "CC": cc }) - if expected_not_patched == self.Expected.SUCCESS_WITH_WARNINGS: - self.assertIn(f"Rust bindings generator '{bindgen}' < 0.69.5 together with libclang >= 19.1", result.stderr) - - bindgen = self.generate_bindgen(f"bindgen {bindgen_version}", libclang_stderr, libclang_concat_patched=True) - result = self.run_script(self.Expected.SUCCESS, { "BINDGEN": bindgen, "CC": cc }) - def test_clang_matches_bindgen_libclang_different_bindgen(self): bindgen = self.generate_bindgen_libclang("scripts/rust_is_available_bindgen_libclang.h:2:9: warning: clang version 999.0.0 [-W#pragma-messages], err: false") result = self.run_script(self.Expected.SUCCESS_WITH_WARNINGS, { "BINDGEN": bindgen })
Signature · 1 line
2.53.0
Re: [PATCH 6.18.y 2/3] rust: rust_is_available: remove warning for `bindgen` < 0.69.5 && libclang >= 19.1
Quoted 8 lines · Sasha Levin
From: Miguel Ojeda <[email protected]>
[ Upstream commit
ae64324ad5c1fdefe479d77ecee975bc6b37467b]It is not possible anymore to fall into the issue that this warning was alerting about given the
bindgenversion bump.
Quoted 7 lines
Thus simplify by removing the machinery behind it, including tests.
Reviewed-by Tamir Duberstein <[email protected]>Signed-off-by Miguel Ojeda <[email protected]>Stable-dep-of:
dc01dfb37b34("rust:rust_is_available: warn forbindgen< 0.72.1 && libclang >= 22")Signed-off-by Sasha Levin <[email protected]>
No, this should not be backported -- bindgen 0.69 is supported in 6.18.y.
Cheers,
Miguel
Sasha Levin
maintainerPATCH 3/3 rust: rust_is_available: warn for `bindgen` < 0.72.1 && libclang >= 22
In reply to Sasha LevinFrom: Miguel Ojeda <[email protected]>
[ Upstream commit dc01dfb37b34beeefcfe1c3055364d41a4070c7e ]
Starting with LLVM 22, clang_getTypeDeclaration() may return a forward declaration instead of the type definition. This made bindgen generate opaque types [1][2], which in turn made us fail with e.g.
error[E0609]: no field `__bindgen_anon_1` on type `bindings::kernel_param`
--> rust/kernel/module_param.rs:78:46
|
78 | let container = unsafe { &*((*param).__bindgen_anon_1.arg.cast::<SetOnce<T>>()) };
| ^^^^^^^^^^^^^^^^ unknown field
|
= note: available field is: `_address`This was fixed in bindgen 0.72.1 [3].
In order to clarify what is going on and avoid confusion [4][5], add a warning to rust_is_available.sh about it when the versions match, similar to past warnings like the one removed in:
commit ae64324ad5c1 ("rust: rust_is_available: remove warning for `bindgen` < 0.69.5 && libclang >= 19.1")In addition, even if the versions match, check if the issue appears to not reproduce with the given binaries, to avoid a warning in such a case.
Finally, include tests.
[ Nathan, in parallel, updated the instructions of the LLVM+Rust
kernel.org toolchains [6] so that --version is not passed to cargo for bindgen, and thus the latest bindgen is installed by default, which should help to avoid some of these situations.
Thanks!
- Miguel ]
--- scripts/rust_is_available.sh | 14 +++++++++ .../rust_is_available_bindgen_libclang_22.h | 5 ++++ scripts/rust_is_available_test.py | 30 ++++++++++++++++++- 3 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 scripts/rust_is_available_bindgen_libclang_22.h
scripts/rust_is_available.sh +14 -0
@@ -214,6 +214,20 @@ if [ "$bindgen_libclang_cversion" -lt "$bindgen_libclang_min_cversion" ]; then exit 1 fi +if [ "$bindgen_libclang_cversion" -ge 2200000 ] && + [ "$rust_bindings_generator_cversion" -lt 7201 ]; then + # Distributions may have patched the issue. + if ! "$BINDGEN" $(dirname $0)/rust_is_available_bindgen_libclang_22.h | grep -q 'pub foo'; then + echo >&2 "***" + echo >&2 "*** Rust bindings generator '$BINDGEN' < 0.72.1 together with libclang >= 22" + echo >&2 "*** may not work due to a bug (https://github.com/rust-lang/rust-bindgen/pull/3278)." + echo >&2 "*** Your bindgen version: $rust_bindings_generator_version" + echo >&2 "*** Your libclang version: $bindgen_libclang_version" + echo >&2 "***" + warning=1 + fi +fi + # If the C compiler is Clang, then we can also check whether its version # matches the `libclang` version used by the Rust bindings generator. #
scripts/rust_is_available_bindgen_libclang_22.h new file +5 -0
@@ -0,0 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +struct S ; +struct S { +int foo; +};
scripts/rust_is_available_test.py +29 -1
@@ -54,16 +54,23 @@ else: """) @classmethod - def generate_bindgen(cls, version_stdout, libclang_stderr): + def generate_bindgen(cls, version_stdout, libclang_stderr, libclang_22_patched=False): if libclang_stderr is None: libclang_case = f"raise SystemExit({cls.bindgen_default_bindgen_libclang_failure_exit_code})" else: libclang_case = f"print({repr(libclang_stderr)}, file=sys.stderr)" + if libclang_22_patched: + libclang_22_case = "print('pub foo: ::std::os::raw::c_int,')" + else: + libclang_22_case = "pass" + return cls.generate_executable(f"""#!/usr/bin/env python3 import sys if "rust_is_available_bindgen_libclang.h" in " ".join(sys.argv): {libclang_case} +elif "rust_is_available_bindgen_libclang_22.h" in " ".join(sys.argv): + {libclang_22_case} else: print({repr(version_stdout)}) """)
@@ -248,6 +255,27 @@ else: result = self.run_script(self.Expected.FAILURE, { "BINDGEN": bindgen }) self.assertIn(f"libclang (used by the Rust bindings generator '{bindgen}') is too old.", result.stderr) + def test_bindgen_bad_libclang_22(self): + for (bindgen_version, libclang_version, expected_not_patched) in ( + ("0.71.1", "21.1.0", self.Expected.SUCCESS), + ("0.71.1", "22.0.0", self.Expected.SUCCESS_WITH_WARNINGS), + ("0.71.1", "22.1.0", self.Expected.SUCCESS_WITH_WARNINGS), + + ("0.72.0", "22.0.0", self.Expected.SUCCESS_WITH_WARNINGS), + + ("0.72.1", "22.0.0", self.Expected.SUCCESS), + ): + with self.subTest(bindgen_version=bindgen_version, libclang_version=libclang_version): + cc = self.generate_clang(f"clang version {libclang_version}") + libclang_stderr = f"scripts/rust_is_available_bindgen_libclang.h:2:9: warning: clang version {libclang_version} [-W#pragma-messages], err: false" + bindgen = self.generate_bindgen(f"bindgen {bindgen_version}", libclang_stderr) + result = self.run_script(expected_not_patched, { "BINDGEN": bindgen, "CC": cc }) + if expected_not_patched == self.Expected.SUCCESS_WITH_WARNINGS: + self.assertIn(f"Rust bindings generator '{bindgen}' < 0.72.1 together with libclang >= 22", result.stderr) + + bindgen = self.generate_bindgen(f"bindgen {bindgen_version}", libclang_stderr, libclang_22_patched=True) + result = self.run_script(self.Expected.SUCCESS, { "BINDGEN": bindgen, "CC": cc }) + def test_clang_matches_bindgen_libclang_different_bindgen(self): bindgen = self.generate_bindgen_libclang("scripts/rust_is_available_bindgen_libclang.h:2:9: warning: clang version 999.0.0 [-W#pragma-messages], err: false") result = self.run_script(self.Expected.SUCCESS_WITH_WARNINGS, { "BINDGEN": bindgen })
Signature · 1 line
2.53.0
Re: [PATCH 6.18.y 3/3] rust: rust_is_available: warn for `bindgen` < 0.72.1 && libclang >= 22
Quoted 39 lines · Sasha Levin
From: Miguel Ojeda <[email protected]>
[ Upstream commit
dc01dfb37b34beeefcfe1c3055364d41a4070c7e]Starting with LLVM 22,
clang_getTypeDeclaration()may return a forward declaration instead of the type definition. This madebindgengenerate opaque types [1][2], which in turn made us fail with e.g.error[E0609]: no field `__bindgen_anon_1` on type `bindings::kernel_param` --> rust/kernel/module_param.rs:78:46 | 78 | let container = unsafe { &*((*param).__bindgen_anon_1.arg.cast::<SetOnce<T>>()) }; | ^^^^^^^^^^^^^^^^ unknown field | = note: available field is: `_address`This was fixed in
bindgen0.72.1 [3].In order to clarify what is going on and avoid confusion [4][5], add a warning to
rust_is_available.shabout it when the versions match, similar to past warnings like the one removed in:commit ae64324ad5c1 ("rust: rust_is_available: remove warning for `bindgen` < 0.69.5 && libclang >= 19.1")In addition, even if the versions match, check if the issue appears to not reproduce with the given binaries, to avoid a warning in such a case.
Finally, include tests.
[ Nathan, in parallel, updated the instructions of the LLVM+Rust
kernel.org toolchains [6] so that--versionis not passed tocargoforbindgen, and thus the latestbindgenis installed by default, which should help to avoid some of these situations.Thanks!
- Miguel ]
Quoted 12 lines
Cc [email protected] # Needed in 6.12.y and later (Rust is pinned in older LTSs).Link https://github.com/Rust-for-Linux/linux/issues/353 [2] # "Missing fields in nested class with LLVM 22."Reported-by Burak Emir <[email protected]>Link https://lore.kernel.org/rust-for-linux/CABwQupNfMAJOGqRM9ke6tj4f53dCCsBDKU7Vp+zf8mwk7bqt8Q@mail.gmail.com/ [5] open hereTested-by Burak Emir <[email protected]>Signed-off-by Miguel Ojeda <[email protected]>Signed-off-by Sasha Levin <[email protected]>
Thanks Sasha for the backport -- I was going to provide a custom backport for Greg for this (and other "FAILED" notifications I got for a bunch of things), because we shouldn't backport the dependencies.
Cheers,
Miguel
Re: [PATCH 6.18.y 1/3] rust: rust_is_available: remove warning for `bindgen` 0.66.[01]
In reply to Sasha LevinQuoted 8 lines · Sasha Levin
From: Miguel Ojeda <[email protected]>
[ Upstream commit
41cfbb4295cf9fcdffa6c89ddc84dca2fa392c98]It is not possible anymore to fall into the issue that this warning was alerting about given the
bindgenversion bump.
Quoted 7 lines
Thus simplify by removing the machinery behind it, including tests.
Reviewed-by Tamir Duberstein <[email protected]>Signed-off-by Miguel Ojeda <[email protected]>Stable-dep-of:
dc01dfb37b34("rust:rust_is_available: warn forbindgen< 0.72.1 && libclang >= 22")Signed-off-by Sasha Levin <[email protected]>
No, this should not be backported -- bindgen 0.66 is supported in 6.18.y.
Cheers,
Miguel
Miguel Ojeda
maintainerPATCH 1/1 rust: rust_is_available: warn for `bindgen` < 0.72.1 && libclang >= 22
In reply to [email protected]Starting with LLVM 22, clang_getTypeDeclaration() may return a forward declaration instead of the type definition. This made bindgen generate opaque types [1][2], which in turn made us fail with e.g.
error[E0609]: no field `__bindgen_anon_1` on type `bindings::kernel_param`
--> rust/kernel/module_param.rs:78:46
|
78 | let container = unsafe { &*((*param).__bindgen_anon_1.arg.cast::<SetOnce<T>>()) };
| ^^^^^^^^^^^^^^^^ unknown field
|
= note: available field is: `_address`This was fixed in bindgen 0.72.1 [3].
In order to clarify what is going on and avoid confusion [4][5], add a warning to rust_is_available.sh about it when the versions match, similar to past warnings like the one removed in:
commit ae64324ad5c1 ("rust: rust_is_available: remove warning for `bindgen` < 0.69.5 && libclang >= 19.1")In addition, even if the versions match, check if the issue appears to not reproduce with the given binaries, to avoid a warning in such a case.
Finally, include tests.
[ Nathan, in parallel, updated the instructions of the LLVM+Rust
kernel.org toolchains [6] so that --version is not passed to cargo for bindgen, and thus the latest bindgen is installed by default, which should help to avoid some of these situations.
Thanks!
- Miguel ]
--- scripts/rust_is_available.sh | 14 +++++++++ .../rust_is_available_bindgen_libclang_22.h | 5 ++++ scripts/rust_is_available_test.py | 30 ++++++++++++++++++- 3 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 scripts/rust_is_available_bindgen_libclang_22.h
scripts/rust_is_available.sh +14 -0
@@ -242,6 +242,20 @@ if [ "$bindgen_libclang_cversion" -ge 1900100 ] && fi fi +if [ "$bindgen_libclang_cversion" -ge 2200000 ] && + [ "$rust_bindings_generator_cversion" -lt 7201 ]; then + # Distributions may have patched the issue. + if ! "$BINDGEN" $(dirname $0)/rust_is_available_bindgen_libclang_22.h | grep -q 'pub foo'; then + echo >&2 "***" + echo >&2 "*** Rust bindings generator '$BINDGEN' < 0.72.1 together with libclang >= 22" + echo >&2 "*** may not work due to a bug (https://github.com/rust-lang/rust-bindgen/pull/3278)." + echo >&2 "*** Your bindgen version: $rust_bindings_generator_version" + echo >&2 "*** Your libclang version: $bindgen_libclang_version" + echo >&2 "***" + warning=1 + fi +fi + # If the C compiler is Clang, then we can also check whether its version # matches the `libclang` version used by the Rust bindings generator. #
scripts/rust_is_available_bindgen_libclang_22.h new file +5 -0
@@ -0,0 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +struct S ; +struct S { +int foo; +};
scripts/rust_is_available_test.py +29 -1
@@ -54,7 +54,7 @@ else: """) @classmethod - def generate_bindgen(cls, version_stdout, libclang_stderr, version_0_66_patched=False, libclang_concat_patched=False): + def generate_bindgen(cls, version_stdout, libclang_stderr, version_0_66_patched=False, libclang_concat_patched=False, libclang_22_patched=False): if libclang_stderr is None: libclang_case = f"raise SystemExit({cls.bindgen_default_bindgen_libclang_failure_exit_code})" else:
@@ -70,6 +70,11 @@ else: else: libclang_concat_case = "pass" + if libclang_22_patched: + libclang_22_case = "print('pub foo: ::std::os::raw::c_int,')" + else: + libclang_22_case = "pass" + return cls.generate_executable(f"""#!/usr/bin/env python3 import sys if "rust_is_available_bindgen_libclang.h" in " ".join(sys.argv):
@@ -78,6 +83,8 @@ elif "rust_is_available_bindgen_0_66.h" in " ".join(sys.argv): {version_0_66_case} elif "rust_is_available_bindgen_libclang_concat.h" in " ".join(sys.argv): {libclang_concat_case} +elif "rust_is_available_bindgen_libclang_22.h" in " ".join(sys.argv): + {libclang_22_case} else: print({repr(version_stdout)}) """)
@@ -300,6 +307,27 @@ else: bindgen = self.generate_bindgen(f"bindgen {bindgen_version}", libclang_stderr, libclang_concat_patched=True) result = self.run_script(self.Expected.SUCCESS, { "BINDGEN": bindgen, "CC": cc }) + def test_bindgen_bad_libclang_22(self): + for (bindgen_version, libclang_version, expected_not_patched) in ( + ("0.71.1", "21.1.0", self.Expected.SUCCESS), + ("0.71.1", "22.0.0", self.Expected.SUCCESS_WITH_WARNINGS), + ("0.71.1", "22.1.0", self.Expected.SUCCESS_WITH_WARNINGS), + + ("0.72.0", "22.0.0", self.Expected.SUCCESS_WITH_WARNINGS), + + ("0.72.1", "22.0.0", self.Expected.SUCCESS), + ): + with self.subTest(bindgen_version=bindgen_version, libclang_version=libclang_version): + cc = self.generate_clang(f"clang version {libclang_version}") + libclang_stderr = f"scripts/rust_is_available_bindgen_libclang.h:2:9: warning: clang version {libclang_version} [-W#pragma-messages], err: false" + bindgen = self.generate_bindgen(f"bindgen {bindgen_version}", libclang_stderr) + result = self.run_script(expected_not_patched, { "BINDGEN": bindgen, "CC": cc }) + if expected_not_patched == self.Expected.SUCCESS_WITH_WARNINGS: + self.assertIn(f"Rust bindings generator '{bindgen}' < 0.72.1 together with libclang >= 22", result.stderr) + + bindgen = self.generate_bindgen(f"bindgen {bindgen_version}", libclang_stderr, libclang_22_patched=True) + result = self.run_script(self.Expected.SUCCESS, { "BINDGEN": bindgen, "CC": cc }) + def test_clang_matches_bindgen_libclang_different_bindgen(self): bindgen = self.generate_bindgen_libclang("scripts/rust_is_available_bindgen_libclang.h:2:9: warning: clang version 999.0.0 [-W#pragma-messages], err: false") result = self.run_script(self.Expected.SUCCESS_WITH_WARNINGS, { "BINDGEN": bindgen })
Signature · 1 line
2.55.0
Re: [PATCH 6.18.y] rust: rust_is_available: warn for `bindgen` < 0.72.1 && libclang >= 22
Quoted 1 line
This was fixed in
bindgen0.72.1 [3].
Queued for 6.18, thanks.
Signature · 2 lines
Thanks, Sasha