Browse Source

Avoid member access through nullptr in debug

If |result_count| is 0 then |results| will be a nullptr and hence the
access |results->Tuple| is undefined behaviour. There's already an
early return in the 0 branch so move that to be the first thing so that
we can guarantee that it's not a nullptr.

Note that technically we take the address of the result so it's not
actually dereferencing it, however UBSan doesn't care about that.
bobsayshilol 10 months ago
parent
commit
e67692b066
1 changed files with 11 additions and 8 deletions
  1. 11 8
      src/llvm_backend_stmt.cpp

+ 11 - 8
src/llvm_backend_stmt.cpp

@@ -2018,14 +2018,7 @@ gb_internal void lb_build_return_stmt_internal(lbProcedure *p, lbValue res) {
 gb_internal void lb_build_return_stmt(lbProcedure *p, Slice<Ast *> const &return_results) {
 gb_internal void lb_build_return_stmt(lbProcedure *p, Slice<Ast *> const &return_results) {
 	lb_ensure_abi_function_type(p->module, p);
 	lb_ensure_abi_function_type(p->module, p);
 
 
-	lbValue res = {};
-
-	TypeTuple *tuple  = &p->type->Proc.results->Tuple;
 	isize return_count = p->type->Proc.result_count;
 	isize return_count = p->type->Proc.result_count;
-	isize res_count = return_results.count;
-
-	lbFunctionType *ft = lb_get_function_type(p->module, p->type);
-	bool return_by_pointer = ft->ret.kind == lbArg_Indirect;
 
 
 	if (return_count == 0) {
 	if (return_count == 0) {
 		// No return values
 		// No return values
@@ -2038,7 +2031,17 @@ gb_internal void lb_build_return_stmt(lbProcedure *p, Slice<Ast *> const &return
 			LLVMBuildRetVoid(p->builder);
 			LLVMBuildRetVoid(p->builder);
 		}
 		}
 		return;
 		return;
-	} else if (return_count == 1) {
+	}
+
+	lbValue res = {};
+
+	TypeTuple *tuple = &p->type->Proc.results->Tuple;
+	isize res_count = return_results.count;
+
+	lbFunctionType *ft = lb_get_function_type(p->module, p->type);
+	bool return_by_pointer = ft->ret.kind == lbArg_Indirect;
+
+	if (return_count == 1) {
 		Entity *e = tuple->variables[0];
 		Entity *e = tuple->variables[0];
 		if (res_count == 0) {
 		if (res_count == 0) {
 			rw_mutex_shared_lock(&p->module->values_mutex);
 			rw_mutex_shared_lock(&p->module->values_mutex);