authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-02-14 16:10:12-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-02-14 16:10:12-05:00
logdf87044fd6588452755014d5909e0db1b776deb2
tree2d41d109f257f1f03e26154c84528a0aa61eff20
parent6769183a9d5f5ec69747f46d4d13c0f8709b2f46
signaturelock-open Commit is signed but in an unrecognized format.

omit nonnull attribute for C pointers

See #1059

5 files changed, 26 insertions(+), 3 deletions(-)

src/analyze.cpp+4
...@@ -4100,6 +4100,10 @@ ZigType *get_codegen_ptr_type(ZigType *type) {...@@ -4100,6 +4100,10 @@ ZigType *get_codegen_ptr_type(ZigType *type) {
4100 return ty;4100 return ty;
4101}4101}
41024102
4103bool type_is_nonnull_ptr(ZigType *type) {
4104 return type_is_codegen_pointer(type) && !ptr_allows_addr_zero(type);
4105}
4106
4103bool type_is_codegen_pointer(ZigType *type) {4107bool type_is_codegen_pointer(ZigType *type) {
4104 return get_codegen_ptr_type(type) == type;4108 return get_codegen_ptr_type(type) == type;
4105}4109}
src/analyze.hpp+1
...@@ -46,6 +46,7 @@ void find_libc_lib_path(CodeGen *g);...@@ -46,6 +46,7 @@ void find_libc_lib_path(CodeGen *g);
46bool type_has_bits(ZigType *type_entry);46bool type_has_bits(ZigType *type_entry);
47bool type_allowed_in_extern(CodeGen *g, ZigType *type_entry);47bool type_allowed_in_extern(CodeGen *g, ZigType *type_entry);
48bool ptr_allows_addr_zero(ZigType *ptr_type);48bool ptr_allows_addr_zero(ZigType *ptr_type);
49bool type_is_nonnull_ptr(ZigType *type);
4950
50ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *abs_full_path, Buf *source_code);51ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *abs_full_path, Buf *source_code);
5152
src/codegen.cpp+16-3
...@@ -617,9 +617,10 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn_table_entry) {...@@ -617,9 +617,10 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn_table_entry) {
617 unsigned init_gen_i = 0;617 unsigned init_gen_i = 0;
618 if (!type_has_bits(return_type)) {618 if (!type_has_bits(return_type)) {
619 // nothing to do619 // nothing to do
620 } else if (type_is_codegen_pointer(return_type)) {620 } else if (type_is_nonnull_ptr(return_type)) {
621 addLLVMAttr(fn_table_entry->llvm_value, 0, "nonnull");621 addLLVMAttr(fn_table_entry->llvm_value, 0, "nonnull");
622 } else if (want_first_arg_sret(g, &fn_type->data.fn.fn_type_id)) {622 } else if (want_first_arg_sret(g, &fn_type->data.fn.fn_type_id)) {
623 // Sret pointers must not be address 0
623 addLLVMArgAttr(fn_table_entry->llvm_value, 0, "nonnull");624 addLLVMArgAttr(fn_table_entry->llvm_value, 0, "nonnull");
624 addLLVMArgAttr(fn_table_entry->llvm_value, 0, "sret");625 addLLVMArgAttr(fn_table_entry->llvm_value, 0, "sret");
625 if (cc_want_sret_attr(cc)) {626 if (cc_want_sret_attr(cc)) {
...@@ -637,6 +638,8 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn_table_entry) {...@@ -637,6 +638,8 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn_table_entry) {
637638
638 uint32_t err_ret_trace_arg_index = get_err_ret_trace_arg_index(g, fn_table_entry);639 uint32_t err_ret_trace_arg_index = get_err_ret_trace_arg_index(g, fn_table_entry);
639 if (err_ret_trace_arg_index != UINT32_MAX) {640 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.
640 addLLVMArgAttr(fn_table_entry->llvm_value, (unsigned)err_ret_trace_arg_index, "nonnull");643 addLLVMArgAttr(fn_table_entry->llvm_value, (unsigned)err_ret_trace_arg_index, "nonnull");
641 }644 }
642645
...@@ -1246,6 +1249,8 @@ static LLVMValueRef get_add_error_return_trace_addr_fn(CodeGen *g) {...@@ -1246,6 +1249,8 @@ static LLVMValueRef get_add_error_return_trace_addr_fn(CodeGen *g) {
1246 LLVMSetFunctionCallConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified));1249 LLVMSetFunctionCallConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified));
1247 addLLVMFnAttr(fn_val, "nounwind");1250 addLLVMFnAttr(fn_val, "nounwind");
1248 add_uwtable_attr(g, fn_val);1251 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.
1249 addLLVMArgAttr(fn_val, (unsigned)0, "nonnull");1254 addLLVMArgAttr(fn_val, (unsigned)0, "nonnull");
1250 if (g->build_mode == BuildModeDebug) {1255 if (g->build_mode == BuildModeDebug) {
1251 ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim", "true");1256 ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim", "true");
...@@ -1320,9 +1325,13 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) {...@@ -1320,9 +1325,13 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) {
1320 LLVMSetFunctionCallConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified));1325 LLVMSetFunctionCallConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified));
1321 addLLVMFnAttr(fn_val, "nounwind");1326 addLLVMFnAttr(fn_val, "nounwind");
1322 add_uwtable_attr(g, fn_val);1327 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.
1323 addLLVMArgAttr(fn_val, (unsigned)0, "nonnull");1330 addLLVMArgAttr(fn_val, (unsigned)0, "nonnull");
1324 addLLVMArgAttr(fn_val, (unsigned)0, "noalias");1331 addLLVMArgAttr(fn_val, (unsigned)0, "noalias");
1325 addLLVMArgAttr(fn_val, (unsigned)0, "writeonly");1332 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.
1326 addLLVMArgAttr(fn_val, (unsigned)1, "nonnull");1335 addLLVMArgAttr(fn_val, (unsigned)1, "nonnull");
1327 addLLVMArgAttr(fn_val, (unsigned)1, "noalias");1336 addLLVMArgAttr(fn_val, (unsigned)1, "noalias");
1328 addLLVMArgAttr(fn_val, (unsigned)1, "readonly");1337 addLLVMArgAttr(fn_val, (unsigned)1, "readonly");
...@@ -1450,6 +1459,8 @@ static LLVMValueRef get_return_err_fn(CodeGen *g) {...@@ -1450,6 +1459,8 @@ static LLVMValueRef get_return_err_fn(CodeGen *g) {
1450 LLVMSetFunctionCallConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified));1459 LLVMSetFunctionCallConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified));
1451 addLLVMFnAttr(fn_val, "nounwind");1460 addLLVMFnAttr(fn_val, "nounwind");
1452 add_uwtable_attr(g, fn_val);1461 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.
1453 addLLVMArgAttr(fn_val, (unsigned)0, "nonnull");1464 addLLVMArgAttr(fn_val, (unsigned)0, "nonnull");
1454 if (g->build_mode == BuildModeDebug) {1465 if (g->build_mode == BuildModeDebug) {
1455 ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim", "true");1466 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_...@@ -2051,7 +2062,7 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
2051 case FnWalkIdAttrs: {2062 case FnWalkIdAttrs: {
2052 ZigType *ptr_type = get_codegen_ptr_type(ty);2063 ZigType *ptr_type = get_codegen_ptr_type(ty);
2053 if (ptr_type != nullptr) {2064 if (ptr_type != nullptr) {
2054 if (ty->id != ZigTypeIdOptional) {2065 if (type_is_nonnull_ptr(ty)) {
2055 addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "nonnull");2066 addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "nonnull");
2056 }2067 }
2057 if (ptr_type->data.pointer.is_const) {2068 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_...@@ -2095,6 +2106,7 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
2095 assert(handle_is_ptr(ty));2106 assert(handle_is_ptr(ty));
2096 switch (fn_walk->id) {2107 switch (fn_walk->id) {
2097 case FnWalkIdAttrs:2108 case FnWalkIdAttrs:
2109 // arrays passed to C ABI functions may not be at address 0
2098 addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "nonnull");2110 addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "nonnull");
2099 addLLVMArgAttrInt(llvm_fn, fn_walk->data.attrs.gen_i, "align", get_abi_alignment(g, ty));2111 addLLVMArgAttrInt(llvm_fn, fn_walk->data.attrs.gen_i, "align", get_abi_alignment(g, ty));
2100 fn_walk->data.attrs.gen_i += 1;2112 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_...@@ -2134,6 +2146,7 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
2134 case FnWalkIdAttrs:2146 case FnWalkIdAttrs:
2135 addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "byval");2147 addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "byval");
2136 addLLVMArgAttrInt(llvm_fn, fn_walk->data.attrs.gen_i, "align", get_abi_alignment(g, ty));2148 addLLVMArgAttrInt(llvm_fn, fn_walk->data.attrs.gen_i, "align", get_abi_alignment(g, ty));
2149 // Byvalue parameters must not have address 0
2137 addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "nonnull");2150 addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "nonnull");
2138 fn_walk->data.attrs.gen_i += 1;2151 fn_walk->data.attrs.gen_i += 1;
2139 break;2152 break;
...@@ -2266,7 +2279,7 @@ void walk_function_params(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk) {...@@ -2266,7 +2279,7 @@ void walk_function_params(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk) {
2266 if ((param_type->id == ZigTypeIdPointer && param_type->data.pointer.is_const) || is_byval) {2279 if ((param_type->id == ZigTypeIdPointer && param_type->data.pointer.is_const) || is_byval) {
2267 addLLVMArgAttr(llvm_fn, (unsigned)gen_index, "readonly");2280 addLLVMArgAttr(llvm_fn, (unsigned)gen_index, "readonly");
2268 }2281 }
2269 if (param_type->id == ZigTypeIdPointer) {2282 if (type_is_nonnull_ptr(param_type)) {
2270 addLLVMArgAttr(llvm_fn, (unsigned)gen_index, "nonnull");2283 addLLVMArgAttr(llvm_fn, (unsigned)gen_index, "nonnull");
2271 }2284 }
2272 break;2285 break;
src/target.cpp+4
...@@ -807,6 +807,10 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) {...@@ -807,6 +807,10 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) {
807 zig_unreachable();807 zig_unreachable();
808}808}
809809
810bool target_allows_addr_zero(const ZigTarget *target) {
811 return target->os == OsFreestanding;
812}
813
810const char *target_o_file_ext(ZigTarget *target) {814const char *target_o_file_ext(ZigTarget *target) {
811 if (target->env_type == ZigLLVM_MSVC || target->os == OsWindows || target->os == OsUefi) {815 if (target->env_type == ZigLLVM_MSVC || target->os == OsWindows || target->os == OsUefi) {
812 return ".obj";816 return ".obj";
src/target.hpp+1
...@@ -135,5 +135,6 @@ bool target_can_exec(const ZigTarget *host_target, const ZigTarget *guest_target...@@ -135,5 +135,6 @@ bool target_can_exec(const ZigTarget *host_target, const ZigTarget *guest_target
135ZigLLVM_OSType get_llvm_os_type(Os os_type);135ZigLLVM_OSType get_llvm_os_type(Os os_type);
136136
137bool target_is_arm(const ZigTarget *target);137bool target_is_arm(const ZigTarget *target);
138bool target_allows_addr_zero(const ZigTarget *target);
138139
139#endif140#endif