Skip to content

Commit df87044

Browse files
committed
omit nonnull attribute for C pointers
See #1059
1 parent 6769183 commit df87044

File tree

5 files changed

+26
-3
lines changed

5 files changed

+26
-3
lines changed

src/analyze.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4100,6 +4100,10 @@ ZigType *get_codegen_ptr_type(ZigType *type) {
41004100
return ty;
41014101
}
41024102

4103+
bool type_is_nonnull_ptr(ZigType *type) {
4104+
return type_is_codegen_pointer(type) && !ptr_allows_addr_zero(type);
4105+
}
4106+
41034107
bool type_is_codegen_pointer(ZigType *type) {
41044108
return get_codegen_ptr_type(type) == type;
41054109
}

src/analyze.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ void find_libc_lib_path(CodeGen *g);
4646
bool type_has_bits(ZigType *type_entry);
4747
bool type_allowed_in_extern(CodeGen *g, ZigType *type_entry);
4848
bool ptr_allows_addr_zero(ZigType *ptr_type);
49+
bool type_is_nonnull_ptr(ZigType *type);
4950

5051
ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *abs_full_path, Buf *source_code);
5152

src/codegen.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -617,9 +617,10 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn_table_entry) {
617617
unsigned init_gen_i = 0;
618618
if (!type_has_bits(return_type)) {
619619
// nothing to do
620-
} else if (type_is_codegen_pointer(return_type)) {
620+
} else if (type_is_nonnull_ptr(return_type)) {
621621
addLLVMAttr(fn_table_entry->llvm_value, 0, "nonnull");
622622
} else if (want_first_arg_sret(g, &fn_type->data.fn.fn_type_id)) {
623+
// Sret pointers must not be address 0
623624
addLLVMArgAttr(fn_table_entry->llvm_value, 0, "nonnull");
624625
addLLVMArgAttr(fn_table_entry->llvm_value, 0, "sret");
625626
if (cc_want_sret_attr(cc)) {
@@ -637,6 +638,8 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn_table_entry) {
637638

638639
uint32_t err_ret_trace_arg_index = get_err_ret_trace_arg_index(g, fn_table_entry);
639640
if (err_ret_trace_arg_index != UINT32_MAX) {
641+
// Error return trace memory is in the stack, which is impossible to be at address 0
642+
// on any architecture.
640643
addLLVMArgAttr(fn_table_entry->llvm_value, (unsigned)err_ret_trace_arg_index, "nonnull");
641644
}
642645

@@ -1246,6 +1249,8 @@ static LLVMValueRef get_add_error_return_trace_addr_fn(CodeGen *g) {
12461249
LLVMSetFunctionCallConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified));
12471250
addLLVMFnAttr(fn_val, "nounwind");
12481251
add_uwtable_attr(g, fn_val);
1252+
// Error return trace memory is in the stack, which is impossible to be at address 0
1253+
// on any architecture.
12491254
addLLVMArgAttr(fn_val, (unsigned)0, "nonnull");
12501255
if (g->build_mode == BuildModeDebug) {
12511256
ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim", "true");
@@ -1320,9 +1325,13 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) {
13201325
LLVMSetFunctionCallConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified));
13211326
addLLVMFnAttr(fn_val, "nounwind");
13221327
add_uwtable_attr(g, fn_val);
1328+
// Error return trace memory is in the stack, which is impossible to be at address 0
1329+
// on any architecture.
13231330
addLLVMArgAttr(fn_val, (unsigned)0, "nonnull");
13241331
addLLVMArgAttr(fn_val, (unsigned)0, "noalias");
13251332
addLLVMArgAttr(fn_val, (unsigned)0, "writeonly");
1333+
// Error return trace memory is in the stack, which is impossible to be at address 0
1334+
// on any architecture.
13261335
addLLVMArgAttr(fn_val, (unsigned)1, "nonnull");
13271336
addLLVMArgAttr(fn_val, (unsigned)1, "noalias");
13281337
addLLVMArgAttr(fn_val, (unsigned)1, "readonly");
@@ -1450,6 +1459,8 @@ static LLVMValueRef get_return_err_fn(CodeGen *g) {
14501459
LLVMSetFunctionCallConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified));
14511460
addLLVMFnAttr(fn_val, "nounwind");
14521461
add_uwtable_attr(g, fn_val);
1462+
// Error return trace memory is in the stack, which is impossible to be at address 0
1463+
// on any architecture.
14531464
addLLVMArgAttr(fn_val, (unsigned)0, "nonnull");
14541465
if (g->build_mode == BuildModeDebug) {
14551466
ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim", "true");
@@ -2051,7 +2062,7 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
20512062
case FnWalkIdAttrs: {
20522063
ZigType *ptr_type = get_codegen_ptr_type(ty);
20532064
if (ptr_type != nullptr) {
2054-
if (ty->id != ZigTypeIdOptional) {
2065+
if (type_is_nonnull_ptr(ty)) {
20552066
addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "nonnull");
20562067
}
20572068
if (ptr_type->data.pointer.is_const) {
@@ -2095,6 +2106,7 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
20952106
assert(handle_is_ptr(ty));
20962107
switch (fn_walk->id) {
20972108
case FnWalkIdAttrs:
2109+
// arrays passed to C ABI functions may not be at address 0
20982110
addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "nonnull");
20992111
addLLVMArgAttrInt(llvm_fn, fn_walk->data.attrs.gen_i, "align", get_abi_alignment(g, ty));
21002112
fn_walk->data.attrs.gen_i += 1;
@@ -2134,6 +2146,7 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
21342146
case FnWalkIdAttrs:
21352147
addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "byval");
21362148
addLLVMArgAttrInt(llvm_fn, fn_walk->data.attrs.gen_i, "align", get_abi_alignment(g, ty));
2149+
// Byvalue parameters must not have address 0
21372150
addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "nonnull");
21382151
fn_walk->data.attrs.gen_i += 1;
21392152
break;
@@ -2266,7 +2279,7 @@ void walk_function_params(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk) {
22662279
if ((param_type->id == ZigTypeIdPointer && param_type->data.pointer.is_const) || is_byval) {
22672280
addLLVMArgAttr(llvm_fn, (unsigned)gen_index, "readonly");
22682281
}
2269-
if (param_type->id == ZigTypeIdPointer) {
2282+
if (type_is_nonnull_ptr(param_type)) {
22702283
addLLVMArgAttr(llvm_fn, (unsigned)gen_index, "nonnull");
22712284
}
22722285
break;

src/target.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -807,6 +807,10 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) {
807807
zig_unreachable();
808808
}
809809

810+
bool target_allows_addr_zero(const ZigTarget *target) {
811+
return target->os == OsFreestanding;
812+
}
813+
810814
const char *target_o_file_ext(ZigTarget *target) {
811815
if (target->env_type == ZigLLVM_MSVC || target->os == OsWindows || target->os == OsUefi) {
812816
return ".obj";

src/target.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,5 +135,6 @@ bool target_can_exec(const ZigTarget *host_target, const ZigTarget *guest_target
135135
ZigLLVM_OSType get_llvm_os_type(Os os_type);
136136

137137
bool target_is_arm(const ZigTarget *target);
138+
bool target_allows_addr_zero(const ZigTarget *target);
138139

139140
#endif

0 commit comments

Comments
 (0)