Skip to content

Commit cff08ee

Browse files
committed
Fix variadic template union layout recursion and generic field codegen
Early return None in CompInfo::layout for uninstantiated C++ template unions (self.kind == CompKind::Union && !self.template_params.is_empty()), avoiding infinite layout recursion on variadic template unions while preserving opaque type alias codegen across LLVM 18 and LLVM 19+. In CompInfo::is_rust_union, check ctx.uses_any_template_parameters during codegen, emitting struct + __BindgenUnionField<T> wrappers for unconstrained generic template union fields to prevent Rust compiler E0740 errors. This also adds LLVM-21 tests, since clang generates different code than LLVM-20. Test: cargo test -p bindgen-tests TAG=agy CONV=619bdf72-4d2d-494f-8cb0-f61a6db9674c
1 parent 2cce544 commit cff08ee

12 files changed

Lines changed: 350 additions & 68 deletions

File tree

.github/workflows/bindgen.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ jobs:
111111
libtinfo: libtinfo5_6.3+20220423-2ubuntu0.1_amd64.deb
112112
- os: ubuntu-24.04-arm
113113
libtinfo: libtinfo5_6.3+20220423-2ubuntu0.1_arm64.deb
114-
llvm_version: ["16.0", "20.1"]
114+
llvm_version: ["16.0", "20.1", "21.1"]
115115
release_build: [0, 1]
116116
no_default_features: [0, 1]
117117
# FIXME: There are no pre-built static libclang libraries, so the
@@ -125,15 +125,15 @@ jobs:
125125
- platform:
126126
os: ubuntu-latest
127127
libtinfo: libtinfo5_6.3+20220423-2ubuntu0.1_amd64.deb
128-
llvm_version: "20.1"
128+
llvm_version: "21.1"
129129
release_build: 0
130130
no_default_features: 0
131131
feature_extra_asserts: 1
132132

133133
# Ensure stuff works on macos too
134134
- platform:
135135
os: macos-latest
136-
llvm_version: "20.1"
136+
llvm_version: "21.1"
137137
release_build: 0
138138
no_default_features: 0
139139
feature_extra_asserts: 0
@@ -160,7 +160,7 @@ jobs:
160160
BINDGEN_FEATURE_RUNTIME: ${{matrix.feature_runtime}}
161161
BINDGEN_FEATURE_EXTRA_ASSERTS: ${{matrix.feature_extra_asserts}}
162162
BINDGEN_NO_DEFAULT_FEATURES: ${{matrix.no_default_features}}
163-
BINDGEN_RUST_FOR_LINUX_TEST: ${{startsWith(matrix.platform.os, 'ubuntu') && matrix.llvm_version == '20.1' && matrix.feature_extra_asserts == 0 && 1 || 0}}
163+
BINDGEN_RUST_FOR_LINUX_TEST: ${{startsWith(matrix.platform.os, 'ubuntu') && matrix.llvm_version == '21.1' && matrix.feature_extra_asserts == 0 && 1 || 0}}
164164
run: ./ci/test.sh
165165

166166
test-book:

bindgen-tests/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,4 @@ runtime = ["bindgen/runtime"]
2626
__testing_only_extra_assertions = ["bindgen/__testing_only_extra_assertions"]
2727
__testing_only_libclang_16 = ["bindgen/__testing_only_libclang_16"]
2828
__testing_only_libclang_20 = ["bindgen/__testing_only_libclang_20"]
29+
__testing_only_libclang_21 = []

bindgen-tests/tests/expectations/tests/libclang-21/issue-544-stylo-creduce-2.rs

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bindgen-tests/tests/expectations/tests/libclang-21/nsBaseHashtable.rs

Lines changed: 57 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bindgen-tests/tests/expectations/tests/transform-op.rs

Lines changed: 9 additions & 55 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bindgen-tests/tests/expectations/tests/variadic_template_union.rs

Lines changed: 59 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bindgen-tests/tests/expectations/tests/variadic_template_union_alignment.rs

Lines changed: 53 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// bindgen-flags: -- -std=c++14
2+
3+
namespace test {
4+
template <class _Arg0, class... _Args>
5+
union __union {
6+
_Arg0 __arg;
7+
__union<_Args...> __u;
8+
};
9+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// bindgen-flags: --raw-line '#[test] fn test_mixed_union_pointer_size() { assert_eq!(::std::mem::size_of::<test_MixedCharPointer>(), 8); }' --opaque-type '.*MixedUnionValue.*' -- -std=c++14
2+
3+
namespace test {
4+
5+
template <class T, class... Args>
6+
union MixedUnionPointer {
7+
T val;
8+
MixedUnionPointer<Args...>* ptr;
9+
};
10+
11+
template <class T>
12+
union MixedUnionPointer<T> {
13+
T val;
14+
};
15+
16+
template <class T, class... Args>
17+
union MixedUnionValue {
18+
T val;
19+
MixedUnionValue<Args...> next;
20+
};
21+
22+
template <class T>
23+
union MixedUnionValue<T> {
24+
T val;
25+
};
26+
27+
using MixedCharPointer = MixedUnionPointer<char, int>;
28+
using MixedCharDouble = MixedUnionValue<char, double>;
29+
30+
static_assert(sizeof(MixedCharPointer) == 8, "Expected sizeof(MixedCharPointer) == 8 in C++");
31+
static_assert(sizeof(MixedCharDouble) == 8, "Expected sizeof(MixedCharDouble) == 8 in C++");
32+
33+
}

bindgen-tests/tests/tests.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -141,16 +141,20 @@ fn compare_generated_header(
141141
{
142142
let mut expectation = expectation.clone();
143143

144-
if cfg!(feature = "__testing_only_libclang_20") {
144+
if cfg!(feature = "__testing_only_libclang_21") {
145+
expectation.push("libclang-21");
146+
} else if cfg!(feature = "__testing_only_libclang_20") {
145147
expectation.push("libclang-20");
146148
} else if cfg!(feature = "__testing_only_libclang_16") {
147149
expectation.push("libclang-16");
148150
} else {
149151
match clang_version().parsed {
150-
None => expectation.push("libclang-20"),
152+
None => expectation.push("libclang-21"),
151153
Some(version) => {
152154
let (maj, min) = version;
153-
let version_str = if maj >= 20 {
155+
let version_str = if maj >= 21 {
156+
"21".to_owned()
157+
} else if maj >= 20 {
154158
"20".to_owned()
155159
} else if maj >= 16 {
156160
"16".to_owned()

0 commit comments

Comments
 (0)