qute

A software analysis framework built around the QBE intermediate language

git clone https://git.8pit.net/qute.git

 1From 575a2d87cac49174b7f53aa6ac5f9186c2165697 Mon Sep 17 00:00:00 2001
 2From: =?UTF-8?q?S=C3=B6ren=20Tempel?= <soeren+git@soeren-tempel.net>
 3Date: Wed, 19 Aug 2026 20:32:01 +0200
 4Subject: [PATCH] Don't specify a QBE return type for C functions with void
 5 return type
 6MIME-Version: 1.0
 7Content-Type: text/plain; charset=UTF-8
 8Content-Transfer-Encoding: 8bit
 9
10Without this patch, SCC currently emits QBE functions that have a "w"
11return type for C functions that have a void return type. However, in
12the return statement of these functions, it doesn't return a value.
13Depending on the reader's interpretation, one could argue that this is
14in violation of the QBE specification, which states: “All return values
15of this function must have [the specified] return type” [1]. Arguably, a
16ret instruction without an argument does not have a "w" return type.
17qbe(1) itself accepts this, but other tooling built around QBE may not.
18
19With this patch, functions with zero-sized types are now represented as
20not having a return type in the QBE representation. Further, the emitted
21QBE call instruction no longer assigns the return value of functions
22with a void return type to a temporary.
23
24This was discovered while executing SCC's emitted QBE representation
25using quebex, a software analysis framework that comes with its own
26standalone implementation of the QBE specification [2].
27
28[1]: https://c9x.me/compile/doc/il.html#Functions
29[2]: https://git.8pit.net/quebex
30---
31 src/cmd/scc-cc/cc2/qbe/code.c | 10 +++++++---
32 1 file changed, 7 insertions(+), 3 deletions(-)
33
34diff --git a/src/cmd/scc-cc/cc2/qbe/code.c b/src/cmd/scc-cc/cc2/qbe/code.c
35index 908be4de..f0813f9a 100644
36--- a/src/cmd/scc-cc/cc2/qbe/code.c
37+++ b/src/cmd/scc-cc/cc2/qbe/code.c
38@@ -411,7 +411,10 @@ writeout(void)
39 
40 	if (curfun->kind == SGLOB)
41 		fputs("export ", stdout);
42-	printf("function %s %s(", size2stack(&curfun->rtype), symname(curfun));
43+	printf("function ");
44+	if (curfun->rtype.size > 0)
45+		printf("%s ", size2stack(&curfun->rtype));
46+	printf("%s(", symname(curfun));
47 
48 	/* declare formal parameters */
49 	sep = "";
50@@ -519,8 +522,9 @@ call(void)
51 
52 	strcpy(to, addr2txt(&pc->to));
53 	strcpy(from, addr2txt(&pc->from1));
54-	printf("\t%s =%s\tcall\t%s(",
55-	       to, size2stack(&sym->type), from);
56+	if (sym->type.size > 0)
57+		printf("\t%s =%s", to, size2stack(&sym->type));
58+	printf("\tcall\t%s(", from);
59 }
60 
61 static void