Filter: Ensure that all expressions declared return type

All instructions with a return value (i.e. expressions, ones with
non-zero outval, third argument in INST()) should declare their return
type. Check that automatically by M4 macros.

Set outval of FI_RETURN to 0. The instruction adds one value to stack,
but syntactically it is a statement, not an expression.

Add fake return type declaration to FI_CALL, otherwise the automatic
check would fail builds.
This commit is contained in:
Ondrej Zajicek (work) 2022-03-03 20:34:44 +01:00 committed by Ondrej Zajicek
parent cde8094c1f
commit 9b302c133f
2 changed files with 12 additions and 3 deletions

View file

@ -238,9 +238,13 @@ m4_define(ERROR,
# This macro specifies result type and makes there are no conflicting definitions # This macro specifies result type and makes there are no conflicting definitions
m4_define(RESULT_TYPE, m4_define(RESULT_TYPE,
`m4_ifdef([[INST_RESULT_TYPE]], `m4_ifdef([[INST_RESULT_TYPE]],
[[m4_ifelse(INST_RESULT_TYPE,$1,,[[ERROR([[Multiple type definitons]])]])]], [[m4_ifelse(INST_RESULT_TYPE,$1,,[[ERROR([[Multiple type definitions in]] INST_NAME)]])]],
[[m4_define(INST_RESULT_TYPE,$1) RESULT_TYPE_($1)]])') [[m4_define(INST_RESULT_TYPE,$1) RESULT_TYPE_($1)]])')
m4_define(RESULT_TYPE_CHECK,
`m4_ifelse(INST_OUTVAL,0,,
[[m4_ifdef([[INST_RESULT_TYPE]],,[[ERROR([[Missing type definition in]] INST_NAME)]])]])')
m4_define(RESULT_TYPE_, ` m4_define(RESULT_TYPE_, `
FID_NEW_BODY()m4_dnl FID_NEW_BODY()m4_dnl
what->type = $1; what->type = $1;
@ -294,6 +298,7 @@ m4_define(FID_ITERATE, `FID_ZONE(10, Iteration)')
# This macro does all the code wrapping. See inline comments. # This macro does all the code wrapping. See inline comments.
m4_define(INST_FLUSH, `m4_ifdef([[INST_NAME]], [[ m4_define(INST_FLUSH, `m4_ifdef([[INST_NAME]], [[
RESULT_TYPE_CHECK()m4_dnl Check for defined RESULT_TYPE()
FID_ENUM()m4_dnl Contents of enum fi_code { ... } FID_ENUM()m4_dnl Contents of enum fi_code { ... }
INST_NAME(), INST_NAME(),
FID_ENUM_STR()m4_dnl Contents of const char * indexed by enum fi_code FID_ENUM_STR()m4_dnl Contents of const char * indexed by enum fi_code
@ -392,6 +397,7 @@ m4_define(INST, `m4_dnl This macro is called on beginning of each instruction
INST_FLUSH()m4_dnl First, old data is flushed INST_FLUSH()m4_dnl First, old data is flushed
m4_define([[INST_NAME]], [[$1]])m4_dnl Then we store instruction name, m4_define([[INST_NAME]], [[$1]])m4_dnl Then we store instruction name,
m4_define([[INST_INVAL]], [[$2]])m4_dnl instruction input value count, m4_define([[INST_INVAL]], [[$2]])m4_dnl instruction input value count,
m4_define([[INST_OUTVAL]], [[$3]])m4_dnl instruction output value count,
m4_undefine([[INST_NEVER_CONSTANT]])m4_dnl reset NEVER_CONSTANT trigger, m4_undefine([[INST_NEVER_CONSTANT]])m4_dnl reset NEVER_CONSTANT trigger,
m4_undefine([[INST_RESULT_TYPE]])m4_dnl and reset RESULT_TYPE value. m4_undefine([[INST_RESULT_TYPE]])m4_dnl and reset RESULT_TYPE value.
FID_INTERPRET_BODY()m4_dnl By default, every code is interpreter code. FID_INTERPRET_BODY()m4_dnl By default, every code is interpreter code.

View file

@ -1103,7 +1103,7 @@
} }
} }
INST(FI_RETURN, 1, 1) { INST(FI_RETURN, 1, 0) {
NEVER_CONSTANT; NEVER_CONSTANT;
/* Acquire the return value */ /* Acquire the return value */
ARG_ANY(1); ARG_ANY(1);
@ -1134,6 +1134,9 @@
VARARG; VARARG;
SYMBOL; SYMBOL;
/* Fake result type declaration */
RESULT_TYPE(T_VOID);
FID_NEW_BODY() FID_NEW_BODY()
ASSERT(sym->class == SYM_FUNCTION); ASSERT(sym->class == SYM_FUNCTION);
@ -1443,7 +1446,7 @@
} }
INST(FI_FORMAT, 1, 0) { /* Format */ INST(FI_FORMAT, 1, 1) { /* Format */
ARG_ANY(1); ARG_ANY(1);
RESULT(T_STRING, s, val_format_str(fpool, &v1)); RESULT(T_STRING, s, val_format_str(fpool, &v1));
} }