From dcc21c1e910f8f82627afe0e4b249e29bd73413a Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Mon, 10 Apr 2023 17:04:11 +0200 Subject: [PATCH] Don't generate wrong strings. (#2487) A header with ```cpp #include const char S1[] = "Hello"; const unsigned char S2[] = u8"Hello"; const char16_t S3[] = u"Hello"; const char32_t S4[] = U"Hello"; const wchar_t S5[] = L"Hello"; ``` will wrongly generate (`-- -std=c++11`) ```rust pub const S1: &[u8; 6usize] = b"Hello\0"; pub const S2: &[u8; 6usize] = b"Hello\0"; pub const S3: &[u8; 2usize] = b"H\0"; pub const S4: &[u8; 2usize] = b"H\0"; pub const S5: &[u8; 2usize] = b"H\0"; ``` since `clang_EvalResult_getAsStr` only works for ordinary and UTF-8 strings. This seems like a `libclang` limitation since there isn't a similar function for other string literal types. This disables generating code for unsupported string types. --- CHANGELOG.md | 3 +++ bindgen/clang.rs | 15 +++++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f2c00d132c..0c84ba2d1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -186,12 +186,15 @@ * The documentation of the generated `type` aliases now matches the comments of their `typedef` counterparts instead of using the comments of the aliased types. + ## Removed * The following deprecated flags were removed: `--use-msvc-mangling`, `--rustfmt-bindings` and `--size_t-is-usize`. * The `--no-rustfmt-bindings` flag was removed in favor of `--formatter=none`. * The `Bindings::emit_warnings` and `Bindings::warnings` methods were removed in favor of `--emit-diagnostics`. + * Bindgen no longer generates C string constants that cannot be represented as + byte slices. ## Fixed diff --git a/bindgen/clang.rs b/bindgen/clang.rs index 62bf84f6d3..0060213336 100644 --- a/bindgen/clang.rs +++ b/bindgen/clang.rs @@ -2104,6 +2104,7 @@ pub(crate) fn extract_clang_version() -> String { #[derive(Debug)] pub(crate) struct EvalResult { x: CXEvalResult, + ty: Type, } impl EvalResult { @@ -2131,6 +2132,7 @@ impl EvalResult { } Some(EvalResult { x: unsafe { clang_Cursor_Evaluate(cursor.x) }, + ty: cursor.cur_type().canonical_type(), }) } @@ -2177,13 +2179,22 @@ impl EvalResult { /// Evaluates the expression as a literal string, that may or may not be /// valid utf-8. pub(crate) fn as_literal_string(&self) -> Option> { - match self.kind() { - CXEval_StrLiteral => { + if self.kind() != CXEval_StrLiteral { + return None; + } + + let char_ty = self.ty.pointee_type().or_else(|| self.ty.elem_type())?; + match char_ty.kind() { + CXType_Char_S | CXType_SChar | CXType_Char_U | CXType_UChar => { let ret = unsafe { CStr::from_ptr(clang_EvalResult_getAsStr(self.x)) }; Some(ret.to_bytes().to_vec()) } + // FIXME: Support generating these. + CXType_Char16 => None, + CXType_Char32 => None, + CXType_WChar => None, _ => None, } }