Skip to content

Commit

Permalink
Fixes #2715.
Browse files Browse the repository at this point in the history
  • Loading branch information
remexre authored and emilio committed Jan 12, 2024
1 parent 11aeae4 commit 8fffbf8
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 4 deletions.
8 changes: 8 additions & 0 deletions bindgen-tests/tests/expectations/tests/noreturn.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions bindgen-tests/tests/headers/noreturn.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@
_Noreturn void f(void);
__attribute__((noreturn)) void g(void);
[[noreturn]] void h(void);
void i(__attribute__((noreturn)) void (*arg)(void));
__attribute__((noreturn)) void j(__attribute__((noreturn)) void (*arg)(void));
22 changes: 18 additions & 4 deletions bindgen/ir/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -505,10 +505,24 @@ impl FunctionSig {
Default::default()
};

// This looks easy to break but the clang parser keeps the type spelling clean even if
// other attributes are added.
is_divergent =
is_divergent || ty.spelling().contains("__attribute__((noreturn))");
// Check if the type contains __attribute__((noreturn)) outside of parentheses. This is
// somewhat fragile, but it seems to be the only way to get at this information as of
// libclang 9.
let ty_spelling = ty.spelling();
let has_attribute_noreturn = ty_spelling
.match_indices("__attribute__((noreturn))")
.any(|(i, _)| {
let depth = ty_spelling[..i]
.bytes()
.filter_map(|ch| match ch {
b'(' => Some(1),
b')' => Some(-1),
_ => None,
})
.sum::<isize>();
depth == 0
});
is_divergent = is_divergent || has_attribute_noreturn;

let is_method = kind == CXCursor_CXXMethod;
let is_constructor = kind == CXCursor_Constructor;
Expand Down

0 comments on commit 8fffbf8

Please sign in to comment.