From d6e96cc1342ab4c855b5fc1b6cd718aec8b61ca3 Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@cea.fr> Date: Wed, 12 Mar 2025 15:47:05 +0100 Subject: [PATCH] [ir2cabs] stabilize translation of function template instantiation --- reorder_defs.ml | 44 ++++++++++++++++- tests/stl/oracle/stl_algorithm.res.oracle | 4 +- tests/stl/oracle/stl_iterator.res.oracle | 8 ++-- tests/stl/oracle/stl_unique_ptr.res.oracle | 4 +- tests/stl/oracle/stl_utility.res.oracle | 48 +++++++++---------- .../oracle/simple_template.res.oracle | 8 ++-- 6 files changed, 79 insertions(+), 37 deletions(-) diff --git a/reorder_defs.ml b/reorder_defs.ml index 8e168745..34898872 100644 --- a/reorder_defs.ml +++ b/reorder_defs.ml @@ -410,6 +410,47 @@ class compute_deps = end else DoChildren end +let extract_def_name = + function + | _,FUNDEF(_,(_,(n,_,_,_)),_,_,_) -> Some n + | _,DECDEF(_,(_,[(n,_,_,_),_]),_) -> Some n + | _ -> None (* we only reorder function template definitions *) + +let reorder_insts l = + let compare d1 d2 = + match extract_def_name d1, extract_def_name d2 with + | None, _ | _, None -> 0 + | Some n1, Some n2 -> String.compare n1 n2 + in + List.stable_sort compare l + +let same_template d1 d2 = + match extract_def_name d1, extract_def_name d2 with + | None, _ | _, None -> false + | Some n1, Some n2 -> + let n1 = Mangling.unmangle n1 in + let n2 = Mangling.unmangle n2 in + let fct_template_regex=Str.regexp {|\(.*\)<.*>$|} in + Str.string_match fct_template_regex n1 0 && + let n1 = Str.matched_group 1 n1 in + Str.string_match fct_template_regex n2 0 && + let n2 = Str.matched_group 1 n2 in + n1 = n2 + +let order_template_insts l = + let rec aux res curr tl = + match curr,tl with + | _, [] -> List.rev_append res (reorder_insts curr) + | [], _ -> assert false + | cd::_, d :: tl -> + if same_template cd d then + aux res (d::curr) tl + else aux (List.rev_append (reorder_insts (List.rev curr)) res) [d] tl + in + match l with + | [] -> [] + | hd :: tl -> aux [] [hd] tl + let reorder file = ignore (Cabsvisit.visitCabsFile (new compute_deps) file); if not (Dependencies.is_complete()) then @@ -418,4 +459,5 @@ let reorder file = if Dependencies.has_cycle () then Frama_Clang_option.fatal "cannot reorder global definitions: dependencies cycle"; - (fst file, Dependencies.emit_deps (snd file)) + let l = order_template_insts (snd file) in + (fst file, Dependencies.emit_deps l) diff --git a/tests/stl/oracle/stl_algorithm.res.oracle b/tests/stl/oracle/stl_algorithm.res.oracle index cd0b3f34..5d910338 100644 --- a/tests/stl/oracle/stl_algorithm.res.oracle +++ b/tests/stl/oracle/stl_algorithm.res.oracle @@ -279,10 +279,10 @@ struct _frama_c_rtti_name_info_node _frama_c_rtti_name_info; struct _frama_c_rtti_name_info_node _frama_c_rtti_name_info; /*@ ensures \valid(\result); */ -type declval<int*&>(void); +type declval<int*&&>(void); /*@ ensures \valid(\result); */ -type declval<int*&&>(void); +type declval<int*&>(void); /*@ ensures \valid(\result); */ type declval<int*&>(void); diff --git a/tests/stl/oracle/stl_iterator.res.oracle b/tests/stl/oracle/stl_iterator.res.oracle index d5c0479f..d89e946f 100644 --- a/tests/stl/oracle/stl_iterator.res.oracle +++ b/tests/stl/oracle/stl_iterator.res.oracle @@ -715,6 +715,10 @@ struct _frama_c_rtti_name_info_node _frama_c_rtti_name_info = .base_classes = (struct _frama_c_rtti_name_info_content *)0, .number_of_base_classes = 0, .pvmt = (struct _frama_c_vmt *)0}; +/*@ requires \valid_read(a); + ensures \valid_read(\result); */ +int const *get<3,int,4>(struct array<int,4> const *a); + /*@ requires \valid(a); ensures \valid(\result); */ int *get<3,int,4>(struct array<int,4> *a) @@ -724,10 +728,6 @@ int *get<3,int,4>(struct array<int,4> *a) return tmp; } -/*@ requires \valid_read(a); - ensures \valid_read(\result); */ -int const *get<3,int,4>(struct array<int,4> const *a); - int main(void) { int __retres; diff --git a/tests/stl/oracle/stl_unique_ptr.res.oracle b/tests/stl/oracle/stl_unique_ptr.res.oracle index 84212433..a113095c 100644 --- a/tests/stl/oracle/stl_unique_ptr.res.oracle +++ b/tests/stl/oracle/stl_unique_ptr.res.oracle @@ -757,11 +757,11 @@ struct unique_ptr<PlainOldStruct,std::default_delete<PlainOldStruct>> *forward<s struct unique_ptr<ClassTemplate<int,0>,std::default_delete<ClassTemplate<int,0>>> *forward<std::unique_ptr<ClassTemplate<int,0>,std::default_delete<ClassTemplate<int,0>>>> (type *t); -struct default_delete<int[]> *forward<std::default_delete<int[]>>(type *t); - struct default_delete<PlainOldStruct> *forward<std::default_delete<PlainOldStruct>> (type *t); +struct default_delete<int[]> *forward<std::default_delete<int[]>>(type *t); + struct default_delete<ClassTemplate<int,0>> *forward<std::default_delete<ClassTemplate<int,0>>> (type *t); diff --git a/tests/stl/oracle/stl_utility.res.oracle b/tests/stl/oracle/stl_utility.res.oracle index 913743f6..84bf1cd4 100644 --- a/tests/stl/oracle/stl_utility.res.oracle +++ b/tests/stl/oracle/stl_utility.res.oracle @@ -190,28 +190,28 @@ struct _frama_c_rtti_name_info_node _frama_c_rtti_name_info; struct _frama_c_rtti_name_info_node _frama_c_rtti_name_info; /*@ ensures \valid(\result); */ -type declval<int&&>(void); +type declval<bool&&>(void); /*@ ensures \valid(\result); */ -type declval<int&>(void); +type declval<double&&>(void); /*@ ensures \valid(\result); */ -type declval<int&>(void); +type declval<int&&>(void); /*@ ensures \valid(\result); */ type declval<bool&>(void); /*@ ensures \valid(\result); */ -type declval<bool&&>(void); +type declval<double&>(void); /*@ ensures \valid(\result); */ -type declval<bool&>(void); +type declval<int&>(void); /*@ ensures \valid(\result); */ -type declval<double&>(void); +type declval<bool&>(void); /*@ ensures \valid(\result); */ -type declval<double&&>(void); +type declval<int&>(void); struct _frama_c_rtti_name_info_node _frama_c_rtti_name_info = {.name = "ok_type", @@ -626,9 +626,9 @@ _Bool operator><S>(struct S const *x, struct S const *y); /*@ requires \valid(b); requires \valid(a); */ -void swap<int>(int *a, int *b) +void swap<double>(double *a, double *b) { - int tmp = *a; + double tmp = *a; *a = *b; *b = tmp; return; @@ -636,9 +636,9 @@ void swap<int>(int *a, int *b) /*@ requires \valid(b); requires \valid(a); */ -void swap<double>(double *a, double *b) +void swap<int>(int *a, int *b) { - double tmp = *a; + int tmp = *a; *a = *b; *b = tmp; return; @@ -658,21 +658,21 @@ void swap<int,2>(int (*a)[2], int (*b)[2]) /*@ requires \valid(t); ensures \valid(\result); */ -int *forward<int>(type *t) +int *forward<int&>(type *t) { return t; } /*@ requires \valid(t); ensures \valid(\result); */ -int *forward<int&>(type *t) +_Bool *forward<bool>(type *t) { return t; } /*@ requires \valid(t); ensures \valid(\result); */ -_Bool *forward<bool>(type *t) +int *forward<int>(type *t) { return t; } @@ -686,14 +686,14 @@ int *forward<int>(type *t) /*@ requires \valid(t); ensures \valid(\result); */ -type *move<int>(int *t) +type *move<int&>(int *t) { return t; } /*@ requires \valid(t); ensures \valid(\result); */ -type *move<int&>(int *t) +type *move<int>(int *t) { return t; } @@ -931,6 +931,10 @@ struct _frama_c_rtti_name_info_node _frama_c_rtti_name_info = .base_classes = (struct _frama_c_rtti_name_info_content *)0, .number_of_base_classes = 0, .pvmt = (struct _frama_c_vmt *)0}; +/*@ requires \valid_read(p); + ensures \valid_read(\result); */ +type const *get<0,int,double>(struct pair<int,double> const *p); + /*@ requires \valid(p); ensures \valid(\result); */ type *get<0,int,double>(struct pair<int,double> *p) @@ -940,6 +944,10 @@ type *get<0,int,double>(struct pair<int,double> *p) return tmp; } +/*@ requires \valid_read(p); + ensures \valid_read(\result); */ +type const *get<1,int,double>(struct pair<int,double> const *p); + /*@ requires \valid(p); ensures \valid(\result); */ type *get<1,int,double>(struct pair<int,double> *p) @@ -949,14 +957,6 @@ type *get<1,int,double>(struct pair<int,double> *p) return tmp; } -/*@ requires \valid_read(p); - ensures \valid_read(\result); */ -type const *get<0,int,double>(struct pair<int,double> const *p); - -/*@ requires \valid_read(p); - ensures \valid_read(\result); */ -type const *get<1,int,double>(struct pair<int,double> const *p); - struct _frama_c_rtti_name_info_node _frama_c_rtti_name_info; /*@ requires \valid_read(this); */ diff --git a/tests/template/oracle/simple_template.res.oracle b/tests/template/oracle/simple_template.res.oracle index ece5e5d3..22877445 100644 --- a/tests/template/oracle/simple_template.res.oracle +++ b/tests/template/oracle/simple_template.res.oracle @@ -1,15 +1,15 @@ [kernel] Parsing simple_template.cc (external front-end) /* Generated by Frama-C */ -int f<int>(int *x) +_Bool f<bool>(_Bool *x) { - int __retres; + _Bool __retres; __retres = *x; return __retres; } -_Bool f<bool>(_Bool *x) +int f<int>(int *x) { - _Bool __retres; + int __retres; __retres = *x; return __retres; } -- GitLab