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:
parent
44bd2788cd
commit
4b2c812323
|
@ -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
|
||||
|
|
|
@ -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: " ^
|
||||
|
|
Loading…
Reference in New Issue