c-parser: VER-881: process more function calls.

Two kinds of function calls were escaping the analysis. The first is simple,
the ReturnFnCall statement type, which was a silly omission from before.

Function calls inside initialiser statements are a more difficult problem.
The simplest solution was to move the VER-881 calculation into a
post-processing phase once those function calls have been moved to statement
positions.
This commit is contained in:
Thomas Sewell 2018-03-08 12:10:12 +11:00 committed by Japheth Lim
parent 44bd2788cd
commit 4b2c812323
2 changed files with 48 additions and 17 deletions

View File

@ -1430,13 +1430,11 @@ in
| SOME _ => ()
in
([w (AssignFnCall(SOME var_e, e_fn, args))],
case args of
[] => NONE
| h :: t => let
fun foldthis (e,acc) = ebogwrap(BinOp(Plus,e,acc))
in
SOME (List.foldl foldthis h t)
end,
let
fun foldthis (e,acc) = ebogwrap(BinOp(Plus,e,acc))
in
SOME (List.foldl foldthis e_fn args)
end,
e)
end
| _ => let
@ -1608,12 +1606,19 @@ in
mod3 = []}}
end
fun fcall_retty_disagrees env fn_e lvtyp = let
val (_, (retty, _)) = fndes_callinfo env fn_e
in lvtyp <> retty end
fun treat_as_emb_fcall env (NONE,fn_e,args) = false
| treat_as_emb_fcall env (SOME lv,fn_e,args) = let
val (callee, (rettyp, _)) = fndes_callinfo env fn_e
val lvtyp = cse_typing env lv
val lv_plain = case enode lv of Var _ => true | _ => false
in not lv_plain orelse lvtyp <> rettyp end
in not lv_plain orelse fcall_retty_disagrees env fn_e lvtyp end
fun treat_ret_as_emb_fcall env (NONE,fn_e,args) = false
| treat_ret_as_emb_fcall env (SOME retty,fn_e,args)
= fcall_retty_disagrees env fn_e retty
fun process_blockitem fname e bi = let
in
@ -1718,12 +1723,7 @@ in
in
(prechaos grs [stmt], e)
end
| AssignFnCall(eopt,fn_e,args) => if treat_as_emb_fcall e (eopt,fn_e,args)
then let
val lv = case eopt of SOME lv => lv
| NONE => raise Fail "Trying to embed fcall without lval."
in pst e (w (Assign(lv,ebogwrap (EFnCall(fn_e,args))))) end
else let
| AssignFnCall(eopt,fn_e,args) => let
val (callee, _) = fndes_callinfo e fn_e
(* the arguments need to be considered as being part of one big
expression (rather than independently) in order for the
@ -1803,6 +1803,35 @@ end
and process_blockitems (fname : string) (env : csenv) bis =
apfst List.concat (fold_pipe (process_blockitem fname) env bis)
fun postprocess_blockitem fname env (BI_Stmt s)
= BI_Stmt (postprocess_stmt fname env s)
| postprocess_blockitem fname env (BI_Decl d)
= BI_Decl d
and postprocess_stmt fname env stmt = let
fun w s0 = swrap(s0, sleft stmt, sright stmt)
val p = postprocess_stmt fname env
val pb = map (postprocess_blockitem fname env)
val sstmt = snode stmt
val retty = get_rettype fname env
in w (case sstmt of
While(g, i, s) => While(g, i, p s)
| Trap(traptype, s) => Trap(traptype, p s)
| IfStmt(g,s1,s2) => IfStmt(g, p s1, p s2)
| Block b => Block (pb b)
| Switch(g,cases) => Switch(g, map (apsnd pb) cases)
| AssignFnCall(eopt,fn_e,args) => if treat_as_emb_fcall env (eopt,fn_e,args)
then let
val lv = case eopt of SOME lv => lv
| NONE => raise Fail "Trying to embed fcall without lval."
in Assign(lv,ebogwrap (EFnCall(fn_e,args))) end
else sstmt
| ReturnFnCall(fn_e, args) => if treat_ret_as_emb_fcall env (retty,fn_e,args)
then Return(SOME (ebogwrap (EFnCall(fn_e,args))))
else sstmt
| _ => sstmt
)
end
fun delete_earlier_fvars fname env = let
fun vitest (VI vinfo) =
#fname vinfo <> SOME fname orelse
@ -1892,7 +1921,8 @@ fun process_one_extdecl (env0 : csenv) edec =
val env = if rettype <> Void then #2 (insert_var (retvar, env))
else env
val (body0, env) = process_blockitems (node s) env (node body)
val body' = wrap (body0, left body, right body)
val body1 = map (postprocess_blockitem (node s) env) body0
val body' = wrap (body1, left body, right body)
val env = (* add fnspecs *) let
val U = merge_specs
in

View File

@ -397,7 +397,8 @@ fun adjusted_complex_fncalls cse ast = let
open Absyn_Serial
fun is_adjusted s = case snode s of
(Assign(_,e)) => (case enode e of EFnCall _ => true | _ => false)
Assign(_,e) => (case enode e of EFnCall _ => true | _ => false)
| Return(SOME e) => (case enode e of EFnCall _ => true | _ => false)
| _ => false
fun note_adjusteds s = if is_adjusted s
then print ("adjusted fncall at: " ^