Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Constants like UINT_MAX not recognized #1636

Closed
chrysn opened this issue Oct 4, 2019 · 6 comments
Closed

Constants like UINT_MAX not recognized #1636

chrysn opened this issue Oct 4, 2019 · 6 comments

Comments

@chrysn
Copy link
Contributor

chrysn commented Oct 4, 2019

Input C/C++ Header

#include <limits.h>

#define A 42
#define B UINT_MAX

static const unsigned int C = UINT_MAX;

Bindgen Invocation

Both bindgen defines.h and a minimal builder().header("defines.h").generate()?.write_to_file(…) create the observed behavior.

Actual Results

pub const A: u32 = 42;
extern "C" {
    #[link_name = "\u{1}C"]
    pub static mut C: ::std::os::raw::c_uint;
}

The __bindgen.i output from bindgen --dump-preprocessed-output ./defines.h contains a line

static const unsigned int C = (2147483647 *2U +1U);

which shows that to Clang, UINT_MAX is, with limits.h in place, valid.

Expected Results

B should be recognized as a compiler constant and expanded.


I did not manage to follow Clang's reasoning to the end, but when I looked through the ( kind = macro_definition debug output, not only did the B macro show up as invalid, but there was also a

(
 kind = macro definition
 spelling = "UINT_MAX"
 location = /usr/lib/llvm-8/lib/clang/8.0.1/include/limits.h:72:9
 is-definition? false
 is-declaration? false
 is-inlined-function? false
 usr = "c:@macro@UINT_MAX"

 type.kind = Invalid
)

section, following which I found UINT_MAX defined as (__INT_MAX__ *2U +1U), where there is no macro for __INT_MAX__ visible in the debug output -- so that's probably a compiler built-in constant. One way to resolve that might be to inject the compiler constants into the constant expression evaluation process that makes values out of nested defines. (Which otherwise work: a #define TWICE_A (A * 2) expands to 84 in bindgen).

@emilio
Copy link
Contributor

emilio commented Oct 14, 2019

Sorry for the delay here. We could probably define a few standard macros in BindgenContext::parsed_macros, if we wanted to fix this.

@reitermarkus
Copy link
Contributor

I just hit the same problem on macOS with limits.h:

Minimal input:

#include <limits.h>

const unsigned long VAR = ULONG_MAX;

Command:

bindgen minimal.h --allowlist-var ULONG_MAX --allowlist-var VAR

Output:

/* automatically generated by rust-bindgen 0.60.1 */

pub const ULONG_MAX: i32 = -1;
extern "C" {
    pub static VAR: ::std::os::raw::c_ulong;
}

@thedataking
Copy link

thedataking commented Mar 14, 2024

One potential solution would be to expose getIntWidth and equivalents for other types (short, long, etc.) in the clang-sys crate, pull that into bindgen, and insert __INT_MAX__ etc. into BindgenContext::parsed_macros for a given target. Happy to give that a stab if it sounds like the right direction.

@xbjfk
Copy link

xbjfk commented Jul 30, 2024

Just ran into this issue, consider this C header:

#define TEST0 0x7fffffffffffffff
#define TEST1 0x8000000000000000
#define TEST2 0xefffffffffffffff
#define TEST3 0xfffffffffffffff0
#define TEST4 0xffffffffffffffff

leads to this seemingly random output:

pub const TEST0: u64 = 9223372036854775807;
pub const TEST1: i64 = -9223372036854775808;
pub const TEST2: i64 = -1152921504606846977;
pub const TEST3: i32 = -16;
pub const TEST4: i32 = -1;

I've tried to show the bounds of where the strangeness occurs, (becoming signed, and then 32 bit as the value gets larger)
This issue seems to be relatively prevalent, see e.g this GitHub search.

@ojeda
Copy link
Contributor

ojeda commented Jul 30, 2024

See as well #2120 and #1594.

@pvdrz
Copy link
Contributor

pvdrz commented Sep 7, 2024

This has been fixed by using the --clang-macro-fallback feature.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants