M fs/comp/c/egen.fs => fs/comp/c/egen.fs +1 -1
@@ 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 *
M fs/comp/c/ptype.fs => fs/comp/c/ptype.fs +3 -1
@@ 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
M fs/comp/c/type.fs => fs/comp/c/type.fs +3 -1
@@ 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 ;
M fs/tests/comp/c/cc.fs => fs/tests/comp/c/cc.fs +1 -0
@@ 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
M fs/tests/comp/c/test.c => fs/tests/comp/c/test.c +8 -0
@@ 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.