Skip to content

Commit f5cea22

Browse files
committed
Miscompile when indexing an array with small unsigned types.
1 parent b7082f3 commit f5cea22

File tree

3 files changed

+13
-9
lines changed

3 files changed

+13
-9
lines changed

releasenotes.md

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
- Use `weak_odr` rather than `weak` on Windows which seems to prevent issues such as #1704.
3030
- Use `weak` on dyn-symbols on Linux.
3131
- Fix crash on project.json not having an empty set of targets.
32+
- Miscompile when indexing an array with small unsigned types for enums.
3233

3334
### Stdlib changes
3435
- Increase BitWriter.write_bits limit up to 32 bits.

src/compiler/llvm_codegen_expr.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -5292,10 +5292,9 @@ LLVMValueRef llvm_emit_array_gep_raw_index(GenContext *c, LLVMValueRef ptr, LLVM
52925292
LLVMTypeRef element_type = LLVMGetElementType(array_type);
52935293
Type *index_type = index->type;
52945294
ASSERT0(type_is_integer(index_type));
5295-
LLVMTypeRef idx_type = llvm_get_type(c, index_type);
52965295
if (type_is_unsigned(index_type) && type_size(index_type) < type_size(type_usz))
52975296
{
5298-
index_val = llvm_zext_trunc(c, index_val, idx_type);
5297+
index_val = llvm_zext_trunc(c, index_val, llvm_get_type(c, type_usz));
52995298
}
53005299
*alignment = type_min_alignment(llvm_abi_size(c, element_type), array_alignment);
53015300
return llvm_emit_pointer_inbounds_gep_raw(c, element_type, ptr, index_val);

test/test_suite/enumerations/enum_associated_value.c3t

+11-7
Original file line numberDiff line numberDiff line change
@@ -41,17 +41,21 @@ entry:
4141
store i32 1, ptr %f, align 4
4242
store i32 0, ptr %g, align 4
4343
%0 = load i32, ptr %f, align 4
44-
%ptroffset = getelementptr inbounds [4 x i8], ptr @"test.Foo$val", i32 %0
44+
%zext = zext i32 %0 to i64
45+
%ptroffset = getelementptr inbounds [4 x i8], ptr @"test.Foo$val", i64 %zext
4546
%1 = load i32, ptr %f, align 4
46-
%ptroffset1 = getelementptr inbounds [8 x i8], ptr @"test.Foo$testme", i32 %1
47+
%zext1 = zext i32 %1 to i64
48+
%ptroffset2 = getelementptr inbounds [8 x i8], ptr @"test.Foo$testme", i64 %zext1
4749
%2 = load i32, ptr %g, align 4
48-
%ptroffset2 = getelementptr inbounds [4 x i8], ptr @"test.Foo$val", i32 %2
50+
%zext3 = zext i32 %2 to i64
51+
%ptroffset4 = getelementptr inbounds [4 x i8], ptr @"test.Foo$val", i64 %zext3
4952
%3 = load i32, ptr %g, align 4
50-
%ptroffset3 = getelementptr inbounds [8 x i8], ptr @"test.Foo$testme", i32 %3
53+
%zext5 = zext i32 %3 to i64
54+
%ptroffset6 = getelementptr inbounds [8 x i8], ptr @"test.Foo$testme", i64 %zext5
5155
%4 = load i32, ptr %ptroffset, align 4
52-
%5 = load ptr, ptr %ptroffset1, align 8
53-
%6 = load i32, ptr %ptroffset2, align 4
54-
%7 = load ptr, ptr %ptroffset3, align 8
56+
%5 = load ptr, ptr %ptroffset2, align 8
57+
%6 = load i32, ptr %ptroffset4, align 4
58+
%7 = load ptr, ptr %ptroffset6, align 8
5559
%8 = call i32 (ptr, ...) @printf(ptr @.str.2, i32 %4, ptr %5, i32 %6, ptr %7)
5660
ret void
5761
}

0 commit comments

Comments
 (0)