diff --git a/releasenotes.md b/releasenotes.md index 083358b96..8444f198f 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -53,6 +53,7 @@ - Crash when doing a type property lookup for const inline enums in some cases #2717. - Incorrect alignment on typedef and local variable debug info. - Assert on optional-returning-function in a comma expression. #2722 +- Creating recursive debug info for functions could cause assertions. ### Stdlib changes - Add `ThreadPool` join function to wait for all threads to finish in the pool without destroying the threads. diff --git a/src/compiler/llvm_codegen_debug_info.c b/src/compiler/llvm_codegen_debug_info.c index 76e78a3b4..67450803e 100644 --- a/src/compiler/llvm_codegen_debug_info.c +++ b/src/compiler/llvm_codegen_debug_info.c @@ -587,21 +587,25 @@ static LLVMMetadataRef llvm_debug_func_type(GenContext *c, Type *type) if (type->backend_debug_type) return type->backend_debug_type; // 3. Otherwise generate: - static LLVMMetadataRef *buffer = NULL; - vec_resize(buffer, 0); - vec_add(buffer, llvm_get_debug_type(c, typeget(sig->rtype))); + LLVMMetadataRef params[MAX_PARAMS + 1]; + int index = 0; + params[index++] = llvm_get_debug_type(c, typeget(sig->rtype)); FOREACH(Decl *, param, sig->params) { - vec_add(buffer, llvm_get_debug_type(c, param->type)); + params[index++] = llvm_get_debug_type(c, param->type); } if (prototype->raw_variadic) { - vec_add(buffer, LLVMDIBuilderCreateUnspecifiedType(c->debug.builder, "", 0)); + params[index++] = LLVMDIBuilderCreateUnspecifiedType(c->debug.builder, "", 0); } + + // 4. We might be done again! + if (type->backend_debug_type) return type->backend_debug_type; + return LLVMDIBuilderCreateSubroutineType(c->debug.builder, c->debug.file.debug_file, - buffer, - vec_size(buffer), 0); + params, + index, 0); }