diff --git a/src/kernel_internals/typing/mergecil.ml b/src/kernel_internals/typing/mergecil.ml index f1a939b213fea3855fc5daace5581dae11cbe600..805f4e06efe13270078d3163e9eca76ef90a9d8c 100644 --- a/src/kernel_internals/typing/mergecil.ml +++ b/src/kernel_internals/typing/mergecil.ml @@ -2637,6 +2637,29 @@ let equalInitOpts (x: init option) (y: init option) : bool = | _,_ -> false end +let merge_arg_names merged_args curr_args = + let do_one_arg merged_arg curr_arg = + (* if curr_arg is also anonymous, this doesn't do much, + but at least doesn't worsen things. *) + if merged_arg.vname = "" then merged_arg.vname <- curr_arg.vname + in + (* if both list have different lengths, merge should have failed earlier. *) + List.iter2 do_one_arg merged_args curr_args + +let update_formals_names merged_vi curr_vi = + (* if the reference varinfo already has formals, everything + is renamed accordingly. However, if the old prototype contains + anonymous formal declarations, while the corresponding current formal + has a name, we keep the new name. *) + match Cil.getFormalsDecl curr_vi with + | curr_args -> + (match Cil.getFormalsDecl merged_vi with + | merged_args -> merge_arg_names merged_args curr_args + | exception Not_found -> + (*existing prototype does not have formals list. Just use current one*) + Cil.unsafeSetFormalsDecl merged_vi curr_args) + | exception Not_found -> () +(* current prototype does not have formals list, nothing to merge. *) (* Now we go once more through the file and we rename the globals that we * keep. We also scan the entire body and we replace references to the @@ -2730,18 +2753,7 @@ let oneFilePass2 (f: file) = if not (is_ignored_vi vi) then begin (* Drop the decl, keep the spec *) mergeSpec vi' vi spec'; - (try - (* if the reference varinfo already has formals, everything - is renamed accordingly. *) - ignore (Cil.getFormalsDecl vi') - with Not_found -> - (* Otherwise, if we have formals here, register them with - the reference varinfo *) - try - let my_formals = Cil.getFormalsDecl vi in - Cil.unsafeSetFormalsDecl vi' my_formals - with Not_found -> () - (* Neither decl has formals. Do nothing. *)); + update_formals_names vi' vi; end; Cil.removeFormalsDecl vi end diff --git a/tests/spec/anon_arg_1.i b/tests/spec/anon_arg_1.i new file mode 100644 index 0000000000000000000000000000000000000000..386a5754268f9a275ca042e2abdc5be54111c67f --- /dev/null +++ b/tests/spec/anon_arg_1.i @@ -0,0 +1,8 @@ +/* run.config* +DONTRUN: main test in anon_arg_2.i +*/ + +int f(int*, int); + +/*@ ensures \result == x; */ +int g(int*, int x); diff --git a/tests/spec/anon_arg_2.i b/tests/spec/anon_arg_2.i new file mode 100644 index 0000000000000000000000000000000000000000..9e3ef0cb8d077d0db7b384d04bbb470a969ddda2 --- /dev/null +++ b/tests/spec/anon_arg_2.i @@ -0,0 +1,15 @@ +/* run.config* +STDOPT: #"@PTEST_DIR@/anon_arg_1.i @PTEST_FILE@" +*/ + +/*@ requires \valid(p); + assigns *p \from x; + ensures \result == x && *p == x; +*/ +int f(int* p, int x); + +/*@ requires \valid(p); + assigns *p; + ensures *p == \result; +*/ +int g(int*p, int); diff --git a/tests/spec/oracle/anon_arg_2.res.oracle b/tests/spec/oracle/anon_arg_2.res.oracle new file mode 100644 index 0000000000000000000000000000000000000000..54b9b9f1cd77985da80ab16b4ba30577a7aa6219 --- /dev/null +++ b/tests/spec/oracle/anon_arg_2.res.oracle @@ -0,0 +1,19 @@ +[kernel] Parsing tests/spec/anon_arg_1.i (no preprocessing) +[kernel] Parsing tests/spec/anon_arg_2.i (no preprocessing) +[kernel] tests/spec/anon_arg_1.i:7: Warning: found two contracts. Merging them +/* Generated by Frama-C */ +/*@ requires \valid(p); + ensures \result ≡ \old(x) ∧ *\old(p) ≡ \old(x); + assigns *p; + assigns *p \from x; + */ +int f(int *p, int x); + +/*@ requires \valid(p); + ensures \result ≡ \old(x); + ensures *\old(p) ≡ \result; + assigns *p; + */ +int g(int *p, int x); + +