| ... | @@ -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 do | 619 | // 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) { |
| 637 | | 638 | |
| 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 | } |
| 642 | | 645 | |
| ... | @@ -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; |