commit f513fb21947f001c52a1ff283e2e7c4038d1158f
parent 778f643dbfe9a81ee03f6dc26f8a841f5b8717af
Author: Virgil Dupras <hsoft@hardcoded.net>
Date: Sun, 2 Apr 2023 21:08:56 -0400
halcc: fix funcsig/rettype mixup
Diffstat:
5 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/fs/comp/c/egen.fs b/fs/comp/c/egen.fs
@@ -131,7 +131,7 @@ code _callA branchA,
rdrop r> ( psinitlvl ) to psoff
Result currentW ?dup if PS- Result :release then
\ TODO: arilvl of fun rettype isn't properly preserved here
- CDecl type if PS+ Result :W else Result :none then ;
+ CDecl :rettype if PS+ Result :W else Result :none then ;
: _incdec, ( res incsz -- res )
Result :?freeCurrentW over Result :*arisz *
diff --git a/fs/comp/c/ptype.fs b/fs/comp/c/ptype.fs
@@ -44,7 +44,9 @@ alias _err parseDeclarator ( type -- cdecl ) \ forward declaration
endcase again ;
: _parseDeclarator ( type -- cdecl )
- 0 begin ( type lvl )
+ 0 over cdecl? if over CDecl :funcptr? if
+ dip bi CDecl type | CDecl lvl | + then then ( type lvl )
+ begin ( type lvl )
'*' readChar? while ( type lvl tok ) 1+ repeat ( type lvl tok )
dup '(' isChar? if ( type lvl tok )
\ Complex type parsing is messed up. Example "int (*foo)[42]", a pointer to
diff --git a/fs/comp/c/type.fs b/fs/comp/c/type.fs
@@ -82,8 +82,10 @@ struct[ CDecl
dup lvl if drop 0 else _ then ;
: :structarrow? ( self -- f ) \ is an indirect Struct reference?
dup lvl 1 = if _ else drop 0 then ;
- : :funcptr? ( self -- f ) bi lvl 1 = | type :funcsig? and ;
+ : :funcptr? ( self -- f ) bi lvl 1 = | type bi cdecl? | :funcsig? and and ;
: :constfuncsig? ( self -- f ) bi :funcsig? | :isglobal? and ;
+ : :rettype
+ dup :funcptr? if type :rettype else dup :funcsig? _assert type then ;
\ Arrays, function signatures and struct ident "naturally" yield references.
: :reference? bi+ nbelem bool | :funcsig? or swap :structdot? or ;
diff --git a/fs/tests/comp/c/cc.fs b/fs/tests/comp/c/cc.fs
@@ -122,6 +122,7 @@ ptrari5 6 + @ 42 #eq
$1234 2 ptrari7 $1238 #eq
funcall1 138 #eq
42 funcall2 85 #eq
+funcall3 scnt not # \ no PS leak/underflow
41 switch1 41 #eq
42 switch1 43 #eq
switch2 42 #eq
diff --git a/fs/tests/comp/c/test.c b/fs/tests/comp/c/test.c
@@ -524,6 +524,14 @@ int funcall1() {
int funcall2(int x) {
return adder(++x, 42);
}
+
+// Function signature type is correctly recognised in typedefs
+typedef void (*Voider)();
+int funcall3() {
+ Voider x = cnoop;
+ void (*y)() = cnoop;
+ x(); y(); // no PS leak/underflow
+}
// There used to be a bug in the forth VM where an expression (something that
// isn't a simple reference, but the result of a computation) with an arg on PS
// would mess PS up.