]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Filter: Ensure that all expressions declared return type
authorOndrej Zajicek (work) <santiago@crfreenet.org>
Thu, 3 Mar 2022 19:34:44 +0000 (20:34 +0100)
committerOndrej Zajicek <santiago@crfreenet.org>
Mon, 27 Jun 2022 19:13:31 +0000 (21:13 +0200)
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.

filter/decl.m4
filter/f-inst.c

index 5242c04c67db1149576a4bb83dc415384f7c621d..4f7ca3ad4d978987811b6a2117053398bb7b8621 100644 (file)
@@ -238,9 +238,13 @@ m4_define(ERROR,
 #      This macro specifies result type and makes there are no conflicting definitions
 m4_define(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(RESULT_TYPE_CHECK,
+       `m4_ifelse(INST_OUTVAL,0,,
+                  [[m4_ifdef([[INST_RESULT_TYPE]],,[[ERROR([[Missing type definition in]] INST_NAME)]])]])')
+
 m4_define(RESULT_TYPE_, `
 FID_NEW_BODY()m4_dnl
 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.
 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 { ... }
   INST_NAME(),
 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
 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_OUTVAL]], [[$3]])m4_dnl       instruction output value count,
 m4_undefine([[INST_NEVER_CONSTANT]])m4_dnl     reset NEVER_CONSTANT trigger,
 m4_undefine([[INST_RESULT_TYPE]])m4_dnl                and reset RESULT_TYPE value.
 FID_INTERPRET_BODY()m4_dnl                     By default, every code is interpreter code.
index 2120440dde12e33c992b640469b25080787afccf..2a02c8e5a5ead2c6995883e26b9afcb8394e07db 100644 (file)
     }
   }
 
-  INST(FI_RETURN, 1, 1) {
+  INST(FI_RETURN, 1, 0) {
     NEVER_CONSTANT;
     /* Acquire the return value */
     ARG_ANY(1);
     VARARG;
     SYMBOL;
 
+    /* Fake result type declaration */
+    RESULT_TYPE(T_VOID);
+
     FID_NEW_BODY()
     ASSERT(sym->class == SYM_FUNCTION);
 
 
   }
 
-  INST(FI_FORMAT, 1, 0) {      /* Format */
+  INST(FI_FORMAT, 1, 1) {      /* Format */
     ARG_ANY(1);
     RESULT(T_STRING, s, val_format_str(fpool, &v1));
   }