Skip to content

Fix an LLVM assertion when matching against static strings #14752

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

Merged
merged 2 commits into from Jun 10, 2014
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions src/librustc/middle/trans/_match.rs
Original file line number Diff line number Diff line change
@@ -312,9 +312,12 @@ fn trans_opt<'a>(bcx: &'a Block<'a>, o: &Opt) -> opt_result<'a> {
let datum = datum::rvalue_scratch_datum(bcx, struct_ty, "");
return single_result(Result::new(bcx, datum.val));
}
lit(ConstLit(lit_id)) => {
let (llval, _) = consts::get_const_val(bcx.ccx(), lit_id);
return single_result(Result::new(bcx, llval));
lit(l @ ConstLit(ref def_id)) => {
let lit_ty = ty::node_id_to_type(bcx.tcx(), lit_to_expr(bcx.tcx(), &l).id);
let (llval, _) = consts::get_const_val(bcx.ccx(), *def_id);
let lit_datum = immediate_rvalue(llval, lit_ty);
let lit_datum = unpack_datum!(bcx, lit_datum.to_appropriate_datum(bcx));
return single_result(Result::new(bcx, lit_datum.val));
}
var(disr_val, ref repr) => {
return adt::trans_case(bcx, &**repr, disr_val);
2 changes: 1 addition & 1 deletion src/librustc/middle/trans/common.rs
Original file line number Diff line number Diff line change
@@ -599,7 +599,7 @@ pub fn C_str_slice(cx: &CrateContext, s: InternedString) -> ValueRef {
let len = s.get().len();
let cs = llvm::LLVMConstPointerCast(C_cstr(cx, s, false),
Type::i8p(cx).to_ref());
C_struct(cx, [cs, C_uint(cx, len)], false)
C_named_struct(cx.tn.find_type("str_slice").unwrap(), [cs, C_uint(cx, len)])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh interesting! With this change, could you see if the bitcast here could be removed?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was actually looking at this just now and yes, it should be doable!

}
}

4 changes: 2 additions & 2 deletions src/librustc/middle/trans/context.rs
Original file line number Diff line number Diff line change
@@ -233,12 +233,12 @@ impl CrateContext {
ccx.int_type = Type::int(&ccx);
ccx.opaque_vec_type = Type::opaque_vec(&ccx);

ccx.tn.associate_type("tydesc", &Type::tydesc(&ccx));

let mut str_slice_ty = Type::named_struct(&ccx, "str_slice");
str_slice_ty.set_struct_body([Type::i8p(&ccx), ccx.int_type], false);
ccx.tn.associate_type("str_slice", &str_slice_ty);

ccx.tn.associate_type("tydesc", &Type::tydesc(&ccx, str_slice_ty));

if ccx.sess().count_llvm_insns() {
base::init_insn_ctxt()
}
7 changes: 1 addition & 6 deletions src/librustc/middle/trans/controlflow.rs
Original file line number Diff line number Diff line change
@@ -20,7 +20,6 @@ use middle::trans::cleanup;
use middle::trans::common::*;
use middle::trans::debuginfo;
use middle::trans::expr;
use middle::trans::type_of;
use middle::ty;
use util::ppaux::Repr;

@@ -343,14 +342,10 @@ pub fn trans_ret<'a>(bcx: &'a Block<'a>,

fn str_slice_arg<'a>(bcx: &'a Block<'a>, s: InternedString) -> ValueRef {
let ccx = bcx.ccx();
let t = ty::mk_str_slice(bcx.tcx(), ty::ReStatic, ast::MutImmutable);
let s = C_str_slice(ccx, s);
let slot = alloca(bcx, val_ty(s), "__temp");
Store(bcx, s, slot);

// The type of C_str_slice is { i8*, i64 }, but the type of the &str is
// %str_slice, so we do a bitcast here to the right type.
BitCast(bcx, slot, type_of::type_of(ccx, t).ptr_to())
slot
}

pub fn trans_fail<'a>(
4 changes: 2 additions & 2 deletions src/librustc/middle/trans/type_.rs
Original file line number Diff line number Diff line change
@@ -186,7 +186,7 @@ impl Type {
Type::func([t], &Type::void(ccx))
}

pub fn tydesc(ccx: &CrateContext) -> Type {
pub fn tydesc(ccx: &CrateContext, str_slice_ty: Type) -> Type {
let mut tydesc = Type::named_struct(ccx, "tydesc");
let glue_fn_ty = Type::glue_fn(ccx, Type::i8p(ccx)).ptr_to();

@@ -200,7 +200,7 @@ impl Type {
int_ty, // align
glue_fn_ty, // drop
glue_fn_ty, // visit
Type::struct_(ccx, [Type::i8p(ccx), Type::int(ccx)], false)]; // name
str_slice_ty]; // name
tydesc.set_struct_body(elems, false);

tydesc
19 changes: 19 additions & 0 deletions src/test/run-pass/issue-11940.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

static TEST_STR: &'static str = "abcd";

fn main() {
let s = "abcd";
match s {
TEST_STR => (),
_ => unreachable!()
}
}