Skip to content

Relooper translation issue in binder.c #1805

@thedataking

Description

@thedataking

In binder_thread_read in the Linux kernel, C2Rust translated a C wait macro into a Rust labeled block whose value was assigned to __ret:

The generated shape was effectively:

  __ret = '_c2rust_label_1: {
      let mut __ret_0: c_long = 0;
      's_53: {
          loop {
              ...
              __ret_0 = __int;
              break 's_53;
          }
          finish_wait(...);
      }
  } as c_int;

The problem is that this block’s final expression was (), because the inner labeled block ended with finish_wait(...), and Rust treats that as unit. Then C2Rust tried to cast () to c_int, which is invalid. Also, the labeled break 's_53 had no value, so the labeled block could not produce the intended integer value on that exit path.

The fix was to make the wait block actually yield __ret_0:

  break 's_53 __ret_0;
  ...
  finish_wait(...);
  __ret_0

So now the block consistently evaluates to the wait result, usually 0, or the interrupt/error value from prepare_to_wait_event.

See transpiled binder_thread_read in binder.rs.txt

Metadata

Metadata

Assignees

Labels

control flowmistranslationTranslating a well-behaved program changes its behavior

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions