From 2c623d84da92d0549d99936cafbaf04781fdcb63 Mon Sep 17 00:00:00 2001 From: Andre Maroneze <andre.oliveiramaroneze@cea.fr> Date: Thu, 10 Jan 2019 19:36:00 +0100 Subject: [PATCH] [Kernel] be more lenient with function pointer types with empty argument lists --- src/kernel_internals/typing/cabs2cil.ml | 8 ++++--- tests/syntax/fct_ptr.i | 4 ++++ tests/syntax/function-types-compatible.i | 2 +- tests/syntax/oracle/fct_ptr.res.oracle | 14 ++++++++++++ .../function-types-compatible.res.oracle | 22 +++++++++++++++---- 5 files changed, 42 insertions(+), 8 deletions(-) diff --git a/src/kernel_internals/typing/cabs2cil.ml b/src/kernel_internals/typing/cabs2cil.ml index b09617ac5eb..df716861958 100644 --- a/src/kernel_internals/typing/cabs2cil.ml +++ b/src/kernel_internals/typing/cabs2cil.ml @@ -2722,9 +2722,11 @@ let rec castTo ?(fromsource=false) | TPtr (TFun (_,args,va,_),_), TPtr(TFun (_,args',va',_),_) -> (* Checks on casting from a function type into another one. We enforce at least the same number of arguments, and emit a warning - if types do not match. - *) - if va <> va' || bigger_length_args args args' then + if types do not match. Note that empty argument lists are always + compatible. *) + if (va <> va' || bigger_length_args args args') && + (args <> None && args' <> None) + then error "conversion between function types with \ different number of arguments:@ %a@ and@ %a" diff --git a/tests/syntax/fct_ptr.i b/tests/syntax/fct_ptr.i index d6695d92417..6b64b574793 100644 --- a/tests/syntax/fct_ptr.i +++ b/tests/syntax/fct_ptr.i @@ -14,3 +14,7 @@ int main () { q = p; q(3); } + +typedef int (*Function_ptr)(); +char *f_va(int a, ...) { return a; } +Function_ptr fp_table[1] = {(Function_ptr) f_va}; // warning, but no error diff --git a/tests/syntax/function-types-compatible.i b/tests/syntax/function-types-compatible.i index 48a4e257653..770198b5691 100644 --- a/tests/syntax/function-types-compatible.i +++ b/tests/syntax/function-types-compatible.i @@ -2,5 +2,5 @@ void (*p)(int, ...); void f(); void main() { p = f; - p(1, 2); + p(1, 2); // warning, but no parsing error; will fail during execution } diff --git a/tests/syntax/oracle/fct_ptr.res.oracle b/tests/syntax/oracle/fct_ptr.res.oracle index af75749caca..5d52398cf87 100644 --- a/tests/syntax/oracle/fct_ptr.res.oracle +++ b/tests/syntax/oracle/fct_ptr.res.oracle @@ -1,5 +1,11 @@ [kernel] Parsing tests/syntax/fct_ptr.i (no preprocessing) +[kernel:typing:incompatible-types-call] tests/syntax/fct_ptr.i:20: Warning: + implicit conversion between incompatible function types: + char *(*)(int a , ...) + and + int (*)() /* Generated by Frama-C */ +typedef int (*Function_ptr)(); int f(int); void *p = (void *)(& f); @@ -22,4 +28,12 @@ int main(void) return __retres; } +char *f_va(int a, void * const *__va_params) +{ + char *__retres; + __retres = (char *)a; + return __retres; +} + +Function_ptr fp_table[1] = {(int (*)())(& f_va)}; diff --git a/tests/syntax/oracle/function-types-compatible.res.oracle b/tests/syntax/oracle/function-types-compatible.res.oracle index 1d6359c914d..121d63a24e7 100644 --- a/tests/syntax/oracle/function-types-compatible.res.oracle +++ b/tests/syntax/oracle/function-types-compatible.res.oracle @@ -1,8 +1,22 @@ [kernel] Parsing tests/syntax/function-types-compatible.i (no preprocessing) -[kernel] tests/syntax/function-types-compatible.i:4: Failure: - conversion between function types with different number of arguments: +[kernel:typing:incompatible-types-call] tests/syntax/function-types-compatible.i:4: Warning: + implicit conversion between incompatible function types: void (*)() and void (*)(int , ...) -[kernel] User Error: stopping on file "tests/syntax/function-types-compatible.i" that has errors. -[kernel] Frama-C aborted: invalid user input. +/* Generated by Frama-C */ +void (*p)(int , void * const *__va_params); +void f(); + +void main(void) +{ + p = (void (*)(int , void * const *__va_params))(& f); + { + int __va_arg0 = 2; + void *__va_args[1] = {& __va_arg0}; + (*p)(1,(void * const *)(__va_args)); + } + return; +} + + -- GitLab