llvm: fix crashes when loading a struct field

The result of buildStructGEP is not always a GEP (sorry), so we can't
use getGEPResultElementType on it.

Closes #14641
This commit is contained in:
Jacob Young 2023-03-29 21:22:14 -04:00 committed by Veikka Tuominen
parent ff97bd21c3
commit 0543def52f
5 changed files with 14 additions and 12 deletions

View file

@ -5558,7 +5558,7 @@ pub const FuncGen = struct {
return fg.loadByRef(payload_ptr, payload_ty, payload_ty.abiAlignment(target), false); return fg.loadByRef(payload_ptr, payload_ty, payload_ty.abiAlignment(target), false);
} }
const load_inst = fg.builder.buildLoad(payload_ptr.getGEPResultElementType(), payload_ptr, ""); const load_inst = fg.builder.buildLoad(err_union_llvm_ty.structGetTypeAtIndex(offset), payload_ptr, "");
load_inst.setAlignment(payload_ty.abiAlignment(target)); load_inst.setAlignment(payload_ty.abiAlignment(target));
return load_inst; return load_inst;
} }
@ -6792,7 +6792,7 @@ pub const FuncGen = struct {
return self.loadByRef(payload_ptr, payload_ty, payload_ty.abiAlignment(target), false); return self.loadByRef(payload_ptr, payload_ty, payload_ty.abiAlignment(target), false);
} }
const load_inst = self.builder.buildLoad(payload_ptr.getGEPResultElementType(), payload_ptr, ""); const load_inst = self.builder.buildLoad(err_union_llvm_ty.structGetTypeAtIndex(offset), payload_ptr, "");
load_inst.setAlignment(payload_ty.abiAlignment(target)); load_inst.setAlignment(payload_ty.abiAlignment(target));
return load_inst; return load_inst;
} }
@ -8580,7 +8580,7 @@ pub const FuncGen = struct {
} }
const tag_index = @boolToInt(layout.tag_align < layout.payload_align); const tag_index = @boolToInt(layout.tag_align < layout.payload_align);
const tag_field_ptr = self.builder.buildStructGEP(llvm_un_ty, union_handle, tag_index, ""); const tag_field_ptr = self.builder.buildStructGEP(llvm_un_ty, union_handle, tag_index, "");
return self.builder.buildLoad(tag_field_ptr.getGEPResultElementType(), tag_field_ptr, ""); return self.builder.buildLoad(llvm_un_ty.structGetTypeAtIndex(tag_index), tag_field_ptr, "");
} else { } else {
if (layout.payload_size == 0) { if (layout.payload_size == 0) {
return union_handle; return union_handle;

View file

@ -254,9 +254,6 @@ pub const Value = opaque {
pub const addFunctionAttr = ZigLLVMAddFunctionAttr; pub const addFunctionAttr = ZigLLVMAddFunctionAttr;
extern fn ZigLLVMAddFunctionAttr(Fn: *Value, attr_name: [*:0]const u8, attr_value: [*:0]const u8) void; extern fn ZigLLVMAddFunctionAttr(Fn: *Value, attr_name: [*:0]const u8, attr_value: [*:0]const u8) void;
pub const getGEPResultElementType = ZigLLVMGetGEPResultElementType;
extern fn ZigLLVMGetGEPResultElementType(GEP: *Value) *Type;
pub const addByValAttr = ZigLLVMAddByValAttr; pub const addByValAttr = ZigLLVMAddByValAttr;
extern fn ZigLLVMAddByValAttr(Fn: *Value, ArgNo: c_uint, type: *Type) void; extern fn ZigLLVMAddByValAttr(Fn: *Value, ArgNo: c_uint, type: *Type) void;
}; };

View file

@ -1239,10 +1239,6 @@ void ZigLLVMSetCallElemTypeAttr(LLVMValueRef Call, size_t arg_index, LLVMTypeRef
Attribute::get(call_inst->getContext(), Attribute::ElementType, llvm_type)); Attribute::get(call_inst->getContext(), Attribute::ElementType, llvm_type));
} }
LLVMTypeRef ZigLLVMGetGEPResultElementType(LLVMValueRef GEP) {
return wrap(unwrap<GEPOperator>(GEP)->getResultElementType());
}
void ZigLLVMFunctionSetPrefixData(LLVMValueRef function, LLVMValueRef data) { void ZigLLVMFunctionSetPrefixData(LLVMValueRef function, LLVMValueRef data) {
unwrap<Function>(function)->setPrefixData(unwrap<Constant>(data)); unwrap<Function>(function)->setPrefixData(unwrap<Constant>(data));
} }

View file

@ -332,8 +332,6 @@ ZIG_EXTERN_C void ZigLLVMAddSretAttr(LLVMValueRef fn_ref, LLVMTypeRef type_val);
ZIG_EXTERN_C void ZigLLVMAddFunctionElemTypeAttr(LLVMValueRef fn_ref, size_t arg_index, LLVMTypeRef elem_ty); ZIG_EXTERN_C void ZigLLVMAddFunctionElemTypeAttr(LLVMValueRef fn_ref, size_t arg_index, LLVMTypeRef elem_ty);
ZIG_EXTERN_C void ZigLLVMAddFunctionAttrCold(LLVMValueRef fn); ZIG_EXTERN_C void ZigLLVMAddFunctionAttrCold(LLVMValueRef fn);
ZIG_EXTERN_C LLVMTypeRef ZigLLVMGetGEPResultElementType(LLVMValueRef GEP);
ZIG_EXTERN_C void ZigLLVMParseCommandLineOptions(size_t argc, const char *const *argv); ZIG_EXTERN_C void ZigLLVMParseCommandLineOptions(size_t argc, const char *const *argv);

View file

@ -1529,3 +1529,14 @@ test "reinterpreting enum value inside packed union" {
try U.doTest(); try U.doTest();
comptime try U.doTest(); comptime try U.doTest();
} }
test "access the tag of a global tagged union" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
const U = union(enum) {
a,
b: u8,
var u: @This() = .a;
};
try expect(U.u == .a);
}