Tcc currently accepts the following erroneous code:

void v();
void f(int, ...);
int main() {
        f(0, v());
}

And a variation:

struct incomplete v();
void f(int, ...);
int main() {
        f(0, v());
}

Slightly more fun one:

struct incomplete f();
void g(struct incomplete);
int main() {
        f(g());
}

There's also this, which looks ok but will break on ABIs with callee
stack cleanup:

struct incomplete f();
int main() {
        f();
}

Attached trivial patch fixes both of these issues.

Cheers,

 -E
diff --git a/tccgen.c b/tccgen.c
index ed26711..d5deb03 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -5639,6 +5639,11 @@ static void gfunc_param_typed(Sym *func, Sym *arg)
     int func_type;
     CType type;
 
+    if ((vtop->type.t & VT_BTYPE) == VT_VOID)
+        tcc_error("argument type is void");
+    if ((vtop->type.t & VT_BTYPE) == VT_STRUCT && vtop->type.ref->c < 0)
+        tcc_error("argument has incomplete type");
+
     func_type = func->f.func_type;
     if (func_type == FUNC_OLD ||
         (func_type == FUNC_ELLIPSIS && arg == NULL)) {
@@ -6494,6 +6499,8 @@ special_math_val:
             ret.r2 = VT_CONST;
             /* compute first implicit argument if a structure is returned */
             if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
+                if (s->type.ref->c < 0)
+                    tcc_error("function has incomplete return type");
                 variadic = (s->f.func_type == FUNC_ELLIPSIS);
                 ret_nregs = gfunc_sret(&s->type, variadic, &ret.type,
                                        &ret_align, &regsize);
_______________________________________________
Tinycc-devel mailing list
Tinycc-devel@nongnu.org
https://lists.nongnu.org/mailman/listinfo/tinycc-devel

Reply via email to