rust-lang / rust-lang/rust-bindgen

Infinite reference loops in C++ headers

Open
#1,992 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
5.3k
Forks
829
Avg merge
1d 1h
Merged PRs (30d)
15

Description

Input C/C++ Header
template<typename _Key>
struct _Hashtable_base {
  typedef _Key key_type;
};

template<typename _Key, bool _Unique_keys>
struct _Map_base { };

template<typename _Key>
struct _Map_base<_Key, true> {
private:
  using key_type = typename _Hashtable_base<_Key>::key_type;

  void at(const key_type& __k);
};

template<typename _Key>
void _Map_base<_Key, true>::at(const key_type& __k) {
}
Bindgen Invocation
$ bindgen input.h
Actual Results
Bindgen hangs indefinitely inside ItemResolver::resolve
Expected Results

Some meaningful bindings, probably:

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct _Hashtable_base {
    pub _address: u8,
}
pub type _Hashtable_base_key_type<_Key> = _Key;
Quick fix (panic instead of hanging)
diff --git a/src/ir/context.rs b/src/ir/context.rs
index 0207547a..2832a462 100644
--- a/src/ir/context.rs
+++ b/src/ir/context.rs
@@ -2659,11 +2659,11 @@ impl ItemResolver {
         loop {
             let item = ctx.resolve_item(id);
             let ty_kind = item.as_type().map(|t| t.kind());
-            match ty_kind {
+            let next_id = match ty_kind {
                 Some(&TypeKind::ResolvedTypeRef(next_id))
                     if self.through_type_refs =>
                 {
-                    id = next_id.into();
+                    next_id.into()
                 }
                 // We intentionally ignore template aliases here, as they are
                 // more complicated, and don't represent a simple renaming of
@@ -2671,10 +2671,16 @@ impl ItemResolver {
                 Some(&TypeKind::Alias(next_id))
                     if self.through_type_aliases =>
                 {
-                    id = next_id.into();
+                    next_id.into()
                 }
                 _ => return item,
+            };
+
+            if next_id == id {
+                panic!("Infinite reference loop involving {:?}", id);
             }
+
+            id = next_id;
         }
     }
 }

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

Inspect ItemResolver::resolve in src/ir/context.rs and reproduce the hang with the supplied input.h using bindgen input.h. Done means the invocation terminates without hanging and produces meaningful bindings for the supplied C++ header, while handling the infinite reference loop appropriately.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, rust
Domain
devtools
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.