Rust-bindgen: Infinite recursion on small input with alignof

Created on 4 Jul 2019  路  12Comments  路  Source: rust-lang/rust-bindgen

Input C/C++ Header

Reduced from 10M input - thanks creduce!

template <typename d> class e {
  using f = d;
  static const auto g = alignof(f);
};

Bindgen Invocation

Current git / bindgen-0.5.0.

cargo run -- alignof-crash.i -- -x c++ -std=c++11

Actual Results

    Finished dev [unoptimized + debuginfo] target(s) in 0.23s
     Running `target/debug/bindgen alignof-crash.i -- -x c++ -std=c++11`
Segmentation fault: 11

Backtrace shows:

...
    frame #114754: 0x000000010388eb20 libclang.dylib`clang::ASTContext::getTypeInfoImpl(clang::Type const*) const + 528
    frame #114755: 0x000000010388fef8 libclang.dylib`clang::ASTContext::getTypeInfo(clang::Type const*) const + 168
    frame #114756: 0x000000010388eb20 libclang.dylib`clang::ASTContext::getTypeInfoImpl(clang::Type const*) const + 528
    frame #114757: 0x000000010388fef8 libclang.dylib`clang::ASTContext::getTypeInfo(clang::Type const*) const + 168
    frame #114758: 0x000000010388eb20 libclang.dylib`clang::ASTContext::getTypeInfoImpl(clang::Type const*) const + 528
    frame #114759: 0x000000010388fef8 libclang.dylib`clang::ASTContext::getTypeInfo(clang::Type const*) const + 168
    frame #114760: 0x000000010388eb20 libclang.dylib`clang::ASTContext::getTypeInfoImpl(clang::Type const*) const + 528
    frame #114761: 0x000000010388fef8 libclang.dylib`clang::ASTContext::getTypeInfo(clang::Type const*) const + 168
    frame #114762: 0x000000010388ebe1 libclang.dylib`clang::ASTContext::getTypeInfoImpl(clang::Type const*) const + 721
    frame #114763: 0x000000010388fef8 libclang.dylib`clang::ASTContext::getTypeInfo(clang::Type const*) const + 168
    frame #114764: 0x000000010388f846 libclang.dylib`clang::ASTContext::getPreferredTypeAlign(clang::Type const*) const + 38
    frame #114765: 0x0000000103a78b63 libclang.dylib`GetAlignOfType((anonymous namespace)::EvalInfo&, clang::QualType) + 99
    frame #114766: 0x0000000103a52678 libclang.dylib`clang::StmtVisitorBase<clang::make_const_ptr, (anonymous namespace)::IntExprEvaluator, bool>::Visit(clang::Stmt const*) (.llvm.3515910695637113089) + 2744
    frame #114767: 0x0000000103a2b656 libclang.dylib`Evaluate(clang::APValue&, (anonymous namespace)::EvalInfo&, clang::Expr const*) (.llvm.3515910695637113089) + 246
    frame #114768: 0x0000000103a2a0ff libclang.dylib`EvaluateAsRValue((anonymous namespace)::EvalInfo&, clang::Expr const*, clang::APValue&) (.llvm.3515910695637113089) + 63
    frame #114769: 0x0000000103a29d7b libclang.dylib`clang::Expr::EvaluateAsRValue(clang::Expr::EvalResult&, clang::ASTContext const&) const + 427
    frame #114770: 0x000000010381925d libclang.dylib`clang_Cursor_Evaluate + 477
    frame #114771: 0x000000010061cfc0 bindgen`clang_sys::clang_Cursor_Evaluate::hc612b80efdaacd43(cursor=CXCursor @ 0x00007ffeefbe2d80) at link.rs:98:16
...

Expected Results

Not crash.

A-libclang bug

All 12 comments

If I replace alignof with sizeof, I get an output:

/* automatically generated by rust-bindgen */

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct a_b_c_e {
    pub _address: u8,
}
pub type a_b_c_e_f<d> = d;

Similarly, if I make the input alignof(d) rather than alignof(f), it also produces an output.

Still crashes when I remove the namespaces. (edited OP)

Replacing using with typedef crashes in the same way.

That is a neat test-case. This seems to be a bug in libclang.

I'm not sure how to work-around it in bindgen without regressing functionality. We can probably introduce a flag to avoid trying to evaluate undeduced types or something.

I'll try to fix it upstream, but I'm afk-ish until next week at least.

@emilio Do you have an upstream bug report?

I sent https://reviews.llvm.org/D64409.

Upon blaming a bit while trying to get a workaround, I found https://github.com/rust-lang/rust-bindgen/pull/284. This is basically an instance of the same bug, I should've asked for it to be fixed upstream before taking the workaround.

I'll try to get a workaround that doesn't regress functionality somehow.

https://github.com/rust-lang/rust-bindgen/pull/1591 has an improvement over the existing workaround that also covers this case.

Ok, fixed upstream, workaround will merge as soon as it's green on Travis. Thanks for the report @jsgf :)

Just to clarify, is #1591 a workaround if https://reviews.llvm.org/D64409 isn't applied, or are they both needed?

That's right, https://github.com/rust-lang/rust-bindgen/pull/1591 works around unpatched versions of LLVM / libclang.

Was this page helpful?
0 / 5 - 0 ratings