Skip to content

Commit 9585c5d

Browse files
Introduce const_cstr!() macro and use it where applicable.
1 parent f6d43ed commit 9585c5d

File tree

7 files changed

+56
-17
lines changed

7 files changed

+56
-17
lines changed

src/librustc_codegen_llvm/attributes.rs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
// except according to those terms.
1010
//! Set and unset common attributes on LLVM values.
1111
12-
use std::ffi::{CStr, CString};
12+
use std::ffi::CString;
1313

1414
use rustc::hir::CodegenFnAttrFlags;
1515
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
@@ -75,7 +75,7 @@ pub fn set_frame_pointer_elimination(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value)
7575
if cx.sess().must_not_eliminate_frame_pointers() {
7676
llvm::AddFunctionAttrStringValue(
7777
llfn, llvm::AttributePlace::Function,
78-
cstr("no-frame-pointer-elim\0"), cstr("true\0"));
78+
const_cstr!("no-frame-pointer-elim"), const_cstr!("true"));
7979
}
8080
}
8181

@@ -108,7 +108,7 @@ pub fn set_probestack(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
108108
// This is defined in the `compiler-builtins` crate for each architecture.
109109
llvm::AddFunctionAttrStringValue(
110110
llfn, llvm::AttributePlace::Function,
111-
cstr("probe-stack\0"), cstr("__rust_probestack\0"));
111+
const_cstr!("probe-stack"), const_cstr!("__rust_probestack"));
112112
}
113113

114114
pub fn llvm_target_features(sess: &Session) -> impl Iterator<Item = &str> {
@@ -202,7 +202,7 @@ pub fn from_fn_attrs(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value, id: DefId) {
202202
let val = CString::new(features).unwrap();
203203
llvm::AddFunctionAttrStringValue(
204204
llfn, llvm::AttributePlace::Function,
205-
cstr("target-features\0"), &val);
205+
const_cstr!("target-features"), &val);
206206
}
207207

208208
// Note that currently the `wasm-import-module` doesn't do anything, but
@@ -213,17 +213,13 @@ pub fn from_fn_attrs(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value, id: DefId) {
213213
llvm::AddFunctionAttrStringValue(
214214
llfn,
215215
llvm::AttributePlace::Function,
216-
cstr("wasm-import-module\0"),
216+
const_cstr!("wasm-import-module"),
217217
&module,
218218
);
219219
}
220220
}
221221
}
222222

223-
fn cstr(s: &'static str) -> &CStr {
224-
CStr::from_bytes_with_nul(s.as_bytes()).expect("null-terminated string")
225-
}
226-
227223
pub fn provide(providers: &mut Providers) {
228224
providers.target_features_whitelist = |tcx, cnum| {
229225
assert_eq!(cnum, LOCAL_CRATE);

src/librustc_codegen_llvm/base.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1255,8 +1255,8 @@ fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
12551255
// Create the llvm.used variable
12561256
// This variable has type [N x i8*] and is stored in the llvm.metadata section
12571257
if !cx.used_statics.borrow().is_empty() {
1258-
let name = CString::new("llvm.used").unwrap();
1259-
let section = CString::new("llvm.metadata").unwrap();
1258+
let name = const_cstr!("llvm.used");
1259+
let section = const_cstr!("llvm.metadata");
12601260
let array = C_array(Type::i8(&cx).ptr_to(), &*cx.used_statics.borrow());
12611261

12621262
unsafe {

src/librustc_codegen_llvm/builder.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -975,7 +975,7 @@ impl Builder<'a, 'll, 'tcx> {
975975
parent: Option<&'ll Value>,
976976
args: &[&'ll Value]) -> &'ll Value {
977977
self.count_insn("cleanuppad");
978-
let name = CString::new("cleanuppad").unwrap();
978+
let name = const_cstr!("cleanuppad");
979979
let ret = unsafe {
980980
llvm::LLVMRustBuildCleanupPad(self.llbuilder,
981981
parent,
@@ -1001,7 +1001,7 @@ impl Builder<'a, 'll, 'tcx> {
10011001
parent: &'ll Value,
10021002
args: &[&'ll Value]) -> &'ll Value {
10031003
self.count_insn("catchpad");
1004-
let name = CString::new("catchpad").unwrap();
1004+
let name = const_cstr!("catchpad");
10051005
let ret = unsafe {
10061006
llvm::LLVMRustBuildCatchPad(self.llbuilder, parent,
10071007
args.len() as c_uint, args.as_ptr(),
@@ -1025,7 +1025,7 @@ impl Builder<'a, 'll, 'tcx> {
10251025
num_handlers: usize,
10261026
) -> &'ll Value {
10271027
self.count_insn("catchswitch");
1028-
let name = CString::new("catchswitch").unwrap();
1028+
let name = const_cstr!("catchswitch");
10291029
let ret = unsafe {
10301030
llvm::LLVMRustBuildCatchSwitch(self.llbuilder, parent, unwind,
10311031
num_handlers as c_uint,

src/librustc_codegen_llvm/consts.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ pub fn codegen_static<'a, 'tcx>(
328328
} else {
329329
// If we created the global with the wrong type,
330330
// correct the type.
331-
let empty_string = CString::new("").unwrap();
331+
let empty_string = const_cstr!("");
332332
let name_str_ref = CStr::from_ptr(llvm::LLVMGetValueName(g));
333333
let name_string = CString::new(name_str_ref.to_bytes()).unwrap();
334334
llvm::LLVMSetValueName(g, empty_string.as_ptr());

src/librustc_codegen_llvm/debuginfo/metadata.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -883,7 +883,7 @@ pub fn compile_unit_metadata(tcx: TyCtxt,
883883
gcov_cu_info.as_ptr(),
884884
gcov_cu_info.len() as c_uint);
885885

886-
let llvm_gcov_ident = CString::new("llvm.gcov").unwrap();
886+
let llvm_gcov_ident = const_cstr!("llvm.gcov");
887887
llvm::LLVMAddNamedMetadataOperand(debug_context.llmod,
888888
llvm_gcov_ident.as_ptr(),
889889
gcov_metadata);
@@ -1780,7 +1780,7 @@ pub fn create_vtable_metadata(
17801780
// later on in llvm/lib/IR/Value.cpp.
17811781
let empty_array = create_DIArray(DIB(cx), &[]);
17821782

1783-
let name = CString::new("vtable").unwrap();
1783+
let name = const_cstr!("vtable");
17841784

17851785
// Create a new one each time. We don't want metadata caching
17861786
// here, because each vtable will refer to a unique containing
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
/// This macro creates a zero-overhead &CStr by adding a NUL terminator to
12+
/// the string literal passed into it at compile-time. Use it like:
13+
///
14+
/// ```
15+
/// let some_const_cstr = const_cstr!("abc");
16+
/// ```
17+
///
18+
/// The above is roughly equivalent to:
19+
///
20+
/// ```
21+
/// let some_const_cstr = CStr::from_bytes_with_nul(b"abc\0").unwrap()
22+
/// ```
23+
///
24+
/// Note that macro only checks the string literal for internal NULs if
25+
/// debug-assertions are enabled in order to avoid runtime overhead in release
26+
/// builds.
27+
#[macro_export]
28+
macro_rules! const_cstr {
29+
($s:expr) => ({
30+
use std::ffi::CStr;
31+
32+
let str_plus_nul = concat!($s, "\0");
33+
34+
if cfg!(debug_assertions) {
35+
CStr::from_bytes_with_nul(str_plus_nul.as_bytes()).unwrap()
36+
} else {
37+
unsafe {
38+
CStr::from_bytes_with_nul_unchecked(str_plus_nul.as_bytes())
39+
}
40+
}
41+
})
42+
}

src/librustc_data_structures/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ pub mod array_vec;
6060
pub mod base_n;
6161
pub mod bitslice;
6262
pub mod bitvec;
63+
pub mod const_cstr;
6364
pub mod flock;
6465
pub mod fx;
6566
pub mod graph;

0 commit comments

Comments
 (0)