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
Show file tree
Hide file tree
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
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/trans/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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!

}
}

Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/trans/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
Expand Down
7 changes: 1 addition & 6 deletions src/librustc/middle/trans/controlflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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>(
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/trans/type_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand All @@ -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
Expand Down
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!()
}
}