Skip to content

Commit 9318bab

Browse files
committed
Fix const array index limit calculation.
The number of operands of the LLVM node initializing the array underlying a const vector isn't always the array length -- if the array is of a sufficiently primitive type and all the elements' values are known (or something like that), LLVM uses a specialized Constant subclass that stores the data packed, and thus has no operands. Oops. But, because llsize_of now gives us a ConstantInt, we can just fix #3169 and this all goes away.
1 parent dd7a81d commit 9318bab

File tree

1 file changed

+2
-31
lines changed

1 file changed

+2
-31
lines changed

src/librustc/middle/trans/consts.rs

+2-31
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ pub fn const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef {
254254
~"index is not an integer-constant \
255255
expression")
256256
};
257-
let (arr, _len) = match ty::get(bt).sty {
257+
let (arr, len) = match ty::get(bt).sty {
258258
ty::ty_evec(_, vstore) | ty::ty_estr(vstore) =>
259259
match vstore {
260260
ty::vstore_fixed(u) =>
@@ -278,36 +278,7 @@ pub fn const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef {
278278
a vector or string type")
279279
};
280280

281-
// FIXME #3169: This is a little odd but it arises due to a
282-
// weird wrinkle in LLVM: it doesn't appear willing to let us
283-
// call LLVMConstIntGetZExtValue on the size element of the
284-
// slice, or seemingly any integer-const involving a sizeof()
285-
// call. Despite that being "a const", it's not the kind of
286-
// const you can ask for the integer-value of, evidently. This
287-
// might be an LLVM bug, not sure. In any case, to work around
288-
// this we obtain the initializer and count how many elements it
289-
// has, ignoring the length we pulled out of the slice. (Note
290-
// that the initializer might be a struct rather than an array,
291-
// if enums are involved.) This only works because we picked out
292-
// the original globalvar via const_deref and so can recover the
293-
// array-size of the underlying array (or the element count of
294-
// the underlying struct), and all this will hold together
295-
// exactly as long as we _don't_ support const sub-slices (that
296-
// is, slices that represent something other than a whole
297-
// array). At that point we'll have more and uglier work to do
298-
// here, but for now this should work.
299-
//
300-
// In the future, what we should be doing here is the
301-
// moral equivalent of:
302-
//
303-
// let len = llvm::LLVMConstIntGetZExtValue(len) as u64;
304-
//
305-
// but we might have to do substantially more magic to
306-
// make it work. Or figure out what is causing LLVM to
307-
// not want to consider sizeof() a constant expression
308-
// we can get the value (as a number) out of.
309-
310-
let len = llvm::LLVMGetNumOperands(arr) as u64;
281+
let len = llvm::LLVMConstIntGetZExtValue(len) as u64;
311282
let len = match ty::get(bt).sty {
312283
ty::ty_estr(*) => {assert len > 0; len - 1},
313284
_ => len

0 commit comments

Comments
 (0)