cg_llvm: Use a type-safe helper to cast &str and &[u8] to *const c_char#132260
cg_llvm: Use a type-safe helper to cast &str and &[u8] to *const c_char#132260bors merged 1 commit intorust-lang:masterfrom
&str and &[u8] to *const c_char#132260Conversation
compiler-errors
left a comment
There was a problem hiding this comment.
Yeah, I think it's always best to constrain "dangling generics" sooner than later, so this extension function seems like a nice little improvement.
|
r? compiler-errors @bors r+ |
…r-errors cg_llvm: Use a type-safe helper to cast `&str` and `&[u8]` to `*const c_char` In `rustc_codegen_llvm` there are many uses of `.as_ptr().cast()` to convert a string or byte-slice to `*const c_char`, which then gets passed through FFI. This works, but is fragile, because there's nothing constraining the pointer cast to actually be from `u8` to `c_char`. If the original value changes to something else that has an `as_ptr` method, or the context changes to expect something other than `c_char`, the cast will silently do the wrong thing. By making the cast more explicit via a helper method, we can be sure that it will either perform the intended cast, or fail at compile time.
…r-errors cg_llvm: Use a type-safe helper to cast `&str` and `&[u8]` to `*const c_char` In `rustc_codegen_llvm` there are many uses of `.as_ptr().cast()` to convert a string or byte-slice to `*const c_char`, which then gets passed through FFI. This works, but is fragile, because there's nothing constraining the pointer cast to actually be from `u8` to `c_char`. If the original value changes to something else that has an `as_ptr` method, or the context changes to expect something other than `c_char`, the cast will silently do the wrong thing. By making the cast more explicit via a helper method, we can be sure that it will either perform the intended cast, or fail at compile time.
…kingjubilee Rollup of 9 pull requests Successful merges: - rust-lang#130259 (Lower AST node id only once) - rust-lang#131441 (Add a new trait `proc_macro::ToTokens`) - rust-lang#132247 (stable_mir: Directly use types from rustc_abi) - rust-lang#132249 (compiler: Add rustc_abi dependence to the compiler) - rust-lang#132255 (Add `LayoutS::is_uninhabited` and use it) - rust-lang#132258 ([rustdoc] Unify variant struct fields margins with struct fields) - rust-lang#132260 (cg_llvm: Use a type-safe helper to cast `&str` and `&[u8]` to `*const c_char`) - rust-lang#132261 (refactor: cleaner check to return None) - rust-lang#132271 (Updating Fuchsia platform-support documentation) r? `@ghost` `@rustbot` modify labels: rollup
…r-errors cg_llvm: Use a type-safe helper to cast `&str` and `&[u8]` to `*const c_char` In `rustc_codegen_llvm` there are many uses of `.as_ptr().cast()` to convert a string or byte-slice to `*const c_char`, which then gets passed through FFI. This works, but is fragile, because there's nothing constraining the pointer cast to actually be from `u8` to `c_char`. If the original value changes to something else that has an `as_ptr` method, or the context changes to expect something other than `c_char`, the cast will silently do the wrong thing. By making the cast more explicit via a helper method, we can be sure that it will either perform the intended cast, or fail at compile time.
…r-errors cg_llvm: Use a type-safe helper to cast `&str` and `&[u8]` to `*const c_char` In `rustc_codegen_llvm` there are many uses of `.as_ptr().cast()` to convert a string or byte-slice to `*const c_char`, which then gets passed through FFI. This works, but is fragile, because there's nothing constraining the pointer cast to actually be from `u8` to `c_char`. If the original value changes to something else that has an `as_ptr` method, or the context changes to expect something other than `c_char`, the cast will silently do the wrong thing. By making the cast more explicit via a helper method, we can be sure that it will either perform the intended cast, or fail at compile time.
…iaskrgr Rollup of 10 pull requests Successful merges: - rust-lang#130259 (Lower AST node id only once) - rust-lang#131441 (Add a new trait `proc_macro::ToTokens`) - rust-lang#132247 (stable_mir: Directly use types from rustc_abi) - rust-lang#132249 (compiler: Add rustc_abi dependence to the compiler) - rust-lang#132255 (Add `LayoutData::is_uninhabited` and use it) - rust-lang#132258 ([rustdoc] Unify variant struct fields margins with struct fields) - rust-lang#132260 (cg_llvm: Use a type-safe helper to cast `&str` and `&[u8]` to `*const c_char`) - rust-lang#132261 (refactor: cleaner check to return None) - rust-lang#132271 (Updating Fuchsia platform-support documentation) - rust-lang#132295 (fixed wast version was released, remove randomization exemption) r? `@ghost` `@rustbot` modify labels: rollup
…kingjubilee Rollup of 9 pull requests Successful merges: - rust-lang#130259 (Lower AST node id only once) - rust-lang#131441 (Add a new trait `proc_macro::ToTokens`) - rust-lang#132247 (stable_mir: Directly use types from rustc_abi) - rust-lang#132249 (compiler: Add rustc_abi dependence to the compiler) - rust-lang#132255 (Add `LayoutData::is_uninhabited` and use it) - rust-lang#132258 ([rustdoc] Unify variant struct fields margins with struct fields) - rust-lang#132260 (cg_llvm: Use a type-safe helper to cast `&str` and `&[u8]` to `*const c_char`) - rust-lang#132261 (refactor: cleaner check to return None) - rust-lang#132271 (Updating Fuchsia platform-support documentation) r? `@ghost` `@rustbot` modify labels: rollup
Rollup merge of rust-lang#132260 - Zalathar:type-safe-cast, r=compiler-errors cg_llvm: Use a type-safe helper to cast `&str` and `&[u8]` to `*const c_char` In `rustc_codegen_llvm` there are many uses of `.as_ptr().cast()` to convert a string or byte-slice to `*const c_char`, which then gets passed through FFI. This works, but is fragile, because there's nothing constraining the pointer cast to actually be from `u8` to `c_char`. If the original value changes to something else that has an `as_ptr` method, or the context changes to expect something other than `c_char`, the cast will silently do the wrong thing. By making the cast more explicit via a helper method, we can be sure that it will either perform the intended cast, or fail at compile time.
| impl AsCCharPtr for str { | ||
| fn as_c_char_ptr(&self) -> *const c_char { | ||
| self.as_ptr().cast() | ||
| } | ||
| } |
There was a problem hiding this comment.
Isn't this wrong? &str can contain null bytes and casting it to c_char will lead to funny results in that case. It works for now because all used strings are well behaved and do not contain nulls.
Same with [u8].
There was a problem hiding this comment.
in #132319 it broken further: c literals (for which it's ok to take *c_char), you changed to &str, which don't have guarantees of cstr.
There was a problem hiding this comment.
A pointer to c_char doesn't have to be nul-terminated. We have plenty of code that passes strings over FFI as pointer/length pairs.
As long as it gets reassembled with StringRef(Ptr, Len) on the C++ side, it's fine.
There was a problem hiding this comment.
And in #132319, all of the relevant FFI functions have been adjusted to take pointer/length pairs instead of nul-terminated strings, so there's no longer any need for those strings to be c"" literals.
There was a problem hiding this comment.
Yes, but fragile. Can't find if it ok for StringRef to have nulls inside, if it later pass them as c strings, things will blow.
| let section = bitcode_section_name(cgcx); | ||
| llvm::LLVMSetSection(llglobal, section.as_ptr().cast()); | ||
| llvm::LLVMSetSection(llglobal, section.as_c_char_ptr()); |
There was a problem hiding this comment.
LLVMSetSection accepts const char* without length, where section is &str.
Ahh, bitcode_section_name have fixme, so it can actually return cstr literals.
There was a problem hiding this comment.
Yeah, and all of the calls to llvm::LLVMSetSection should really be calling the safe wrapper llvm::set_section (which takes &CStr), which would enforce type-safety.
…rrors cg_llvm: Consistently use safe wrapper function `set_section` Follow-up to rust-lang#131962 and rust-lang#132260 (comment). To avoid too much scope creep, I've deliberately kept the changes to `LLVMRustGetSliceFromObjectDataByName` as minimal as possible.
…rrors cg_llvm: Consistently use safe wrapper function `set_section` Follow-up to rust-lang#131962 and rust-lang#132260 (comment). To avoid too much scope creep, I've deliberately kept the changes to `LLVMRustGetSliceFromObjectDataByName` as minimal as possible.
Rollup merge of rust-lang#132340 - Zalathar:set-section, r=compiler-errors cg_llvm: Consistently use safe wrapper function `set_section` Follow-up to rust-lang#131962 and rust-lang#132260 (comment). To avoid too much scope creep, I've deliberately kept the changes to `LLVMRustGetSliceFromObjectDataByName` as minimal as possible.
In
rustc_codegen_llvmthere are many uses of.as_ptr().cast()to convert a string or byte-slice to*const c_char, which then gets passed through FFI.This works, but is fragile, because there's nothing constraining the pointer cast to actually be from
u8toc_char. If the original value changes to something else that has anas_ptrmethod, or the context changes to expect something other thanc_char, the cast will silently do the wrong thing.By making the cast more explicit via a helper method, we can be sure that it will either perform the intended cast, or fail at compile time.