diff --git a/src/plugins/wp/MemTyped.ml b/src/plugins/wp/MemTyped.ml index 6de0a92ea470f46ac2559dbef0a92a60dd5edc15..63c759f0498dc1021c47c79fc16be245a1fbaad4 100644 --- a/src/plugins/wp/MemTyped.ml +++ b/src/plugins/wp/MemTyped.ml @@ -1057,12 +1057,20 @@ let block_length sigma obj l = (* --- Cast --- *) (* -------------------------------------------------------------------------- *) -module Layout = +module Layout : sig + val pretty : Format.formatter -> c_object -> unit + + val fits: dst:c_object -> src:c_object -> bool + (* returns [true] in these cases: + - [dst] fits into [src] (exists cobj; [src] = [dst] concat cobj) + - [dst] equals [src] ([dst] = [src]) *) +end = struct - type atom = P of typ | I of c_int | F of c_float + type atom = P of typ | I of c_int | F of c_float | U of Cil_types.compinfo let pp_atom fmt = function + | U ci -> Format.fprintf fmt "union %a" Printer.pp_compinfo ci | P ty -> Printer.pp_typ fmt (TPtr(ty,[])) | I i -> Ctypes.pp_int fmt i | F f -> Ctypes.pp_float fmt f @@ -1070,7 +1078,10 @@ struct let eqatom a1 a2 = match a1 , a2 with | P _ , P _ -> true - | _ -> (a1 = a2) + | U u1 , U u2 -> Compinfo.equal u1 u2 + | I i1 , I i2 -> i1 = i2 + | F f1 , F f2 -> f1 = f2 + | _ -> false type block = | Str of atom * int @@ -1117,12 +1128,13 @@ struct | C_int i -> add_atom (I i) w | C_float f -> add_atom (F f) w | C_pointer t -> add_atom (P t) w + | C_comp { cfields = [f] } -> + flayout w f (* unions containing only one field are + considered as structures *) | C_comp c -> if c.cstruct then List.fold_left flayout w c.cfields - else - (* TODO: can be the longest common prefix *) - add_block Garbled w + else add_atom (U c) w (* unions with several fields *) | C_array { arr_flat = Some a } -> let ly = rlayout [] (Ctypes.object_of a.arr_cell) in if a.arr_cell_nbr = 1 @@ -1139,21 +1151,34 @@ struct let layout (obj : c_object) : layout = List.rev (rlayout [] obj) - type comparison = Fit | Equal | Mismatch + let add_compound (c: Cil_types.compinfo) w : layout = + List.fold_left flayout w (List.rev c.cfields) + + let ulayout (c: Cil_types.compinfo) : layout = add_compound c [] + + type comparison = Srem of layout | Drem of layout | Equal | Mismatch let add_array ly n w = if n=1 then ly @ w else add_many ly n w - let rec compare l1 l2 = - match l1 , l2 with - | [] , [] -> Equal - | [] , _ -> Fit - | _ , [] -> Mismatch + let rec equal_atom a b = + (eqatom a b) || + (match a,b with + | U u1, U u2 -> (* for union, the layouts must be equal *) + (match compare ~dst:(ulayout u1) ~src:(ulayout u2) with + | Equal -> true + | _ -> false) + | _, _ -> false) + and compare ~dst ~src = + match dst , src with + | [] , [] -> Equal (* src = dst *) + | [] , obj -> Srem obj (* src = dst @ obj *) + | obj , [] -> Drem obj (* dst = src @ obj *) | p::w1 , q::w2 -> match p , q with | Garbled , _ | _ , Garbled -> Mismatch | Str(a,n) , Str(b,m) -> - if eqatom a b then + if equal_atom a b then if n < m then let w2 = Str(a,m-n)::w2 in compare w1 w2 @@ -1166,9 +1191,16 @@ struct else Mismatch | Arr(u,n) , Arr(v,m) -> begin - match compare u v with + match compare ~dst:u ~src:v with | Mismatch -> Mismatch - | Fit -> Mismatch + | Drem u' -> + let w1 = u' @ add_array u (n-1) w1 in + let w2 = add_array v (m-1) w2 in + compare w1 w2 + | Srem v' -> + let w1 = add_array u (n-1) w1 in + let w2 = v' @ add_array v (m-1) w2 in + compare w1 w2 | Equal -> if n < m then let w2 = add_array v (m-n) w2 in @@ -1181,20 +1213,55 @@ struct compare w1 w2 end | Arr(v,n) , Str _ -> - compare (v @ add_array v (n-1) w1) l2 + compare ~dst:(v @ add_array v (n-1) w1) ~src | Str _ , Arr(v,n) -> - compare l1 (v @ add_array v (n-1) w2) - - let fits obj1 obj2 = - match obj1 , obj2 with + compare ~dst ~src:(v @ add_array v (n-1) w2) + + let rec repeated ~dst ~src = + match dst , src with + | [] , [] -> true (* src = dst *) + | _ , [] -> false (* empty source layout *) + | [] , _ -> false (* empty destination layout *) + | [p] , [q] -> begin + match p , q with + | Garbled , _ | _ , Garbled -> false + | Str(a,n) , Str(b,m) -> (* dst =?= repeated(src,n/m) *) + equal_atom a b && n >= m && (n mod m = 0) + | Arr(u,n) , Arr(v,m) -> + begin + match compare ~dst:u ~src:v with + | Mismatch -> false + | Drem u' -> + let w1 = u' @ add_array u (n-1) [] in + let w2 = add_array v (m-1) [] in + let cmp = compare ~dst:w1 ~src:w2 in + repeated_result ~src cmp + | Srem _ -> + false + | Equal -> (* dst =?= repeated(src,n/m) *) + n >= m && (n mod m = 0) + end + | _ , _ -> repeated_compare ~dst ~src + end + | _ , _ -> repeated_compare ~dst ~src + and repeated_compare ~dst ~src = repeated_result ~src (compare ~dst ~src) + and repeated_result ~src = function + | Equal -> true + | Mismatch | Srem _ -> false + | Drem dst -> repeated ~dst ~src + + let fits ~dst ~src = + match dst , src with | C_int i1 , C_int i2 -> i1 = i2 | C_float f1 , C_float f2 -> f1 = f2 | C_comp c , C_comp d when Compinfo.equal c d -> true | C_pointer _ , C_pointer _ -> true | _ -> - match compare (layout obj1) (layout obj2) with - | Equal | Fit -> true + let src = layout src in + match compare ~dst:(layout dst) ~src with + | Equal | Srem _ -> true | Mismatch -> false + | Drem dst -> repeated dst src let rec pretty fmt = function | C_pointer ty -> Format.fprintf fmt "%a*" pretty (Ctypes.object_of ty) @@ -1223,10 +1290,10 @@ let cast s l = match Context.get pointer with | NoCast -> Warning.error ~source:"Typed Model" "%a" pp_mismatch s | Fits -> - if Layout.fits s.post s.pre then l else + if Layout.fits ~dst:s.post ~src:s.pre then l else Warning.error ~source:"Typed Model" "%a" pp_mismatch s | Unsafe -> - if not (Layout.fits s.post s.pre) then + if not (Layout.fits ~dst:s.post ~src:s.pre) then Warning.emit ~severe:false ~source:"Typed Model" ~effect:"Keep pointer value" "%a" pp_mismatch s ; l diff --git a/src/plugins/wp/ctypes.ml b/src/plugins/wp/ctypes.ml index 04cd9701c91426a98d40259689f9c518e9d46d0a..bde88014eff652f7934de930b483c41815ff837d 100644 --- a/src/plugins/wp/ctypes.ml +++ b/src/plugins/wp/ctypes.ml @@ -464,9 +464,12 @@ let sizeof_object = function WpLog.fatal ~current:true "Sizeof unknown-size array" let field_offset fd = - let ctype = TComp(fd.fcomp,Cil.empty_size_cache(),[]) in - let offset = Field(fd,NoOffset) in - fst (Cil.bitsOffset ctype offset) / 8 + if fd.fcomp.cstruct then (* C struct *) + let ctype = TComp(fd.fcomp,Cil.empty_size_cache(),[]) in + let offset = Field(fd,NoOffset) in + fst (Cil.bitsOffset ctype offset) / 8 + else (* CIL invariant: all C union fields start at offset 0 *) + 0 (* Conforms to C-ISO 6.3.1.8 *) (* If same sign => greater rank. *) diff --git a/src/plugins/wp/tests/wp_acsl/logic.i b/src/plugins/wp/tests/wp_acsl/logic.i index 3d6f566be3ac4dba97d7a9aa6df2e28480e6f99a..7a54adc27e1d6764c96cef25f3bdd3facdfbedbe 100644 --- a/src/plugins/wp/tests/wp_acsl/logic.i +++ b/src/plugins/wp/tests/wp_acsl/logic.i @@ -1,9 +1,9 @@ /* run.config - OPT: -wp-model Typed+cast -*//* run.config_qualif - OPT: -wp -wp-model Typed+cast -wp-steps 50 + OPT: -wp-model Typed +*/ +/* run.config_qualif + OPT: -wp -wp-model Typed -wp-steps 50 */ - // Test logic types defined from C types //-------------------------------------- typedef struct { int x ; int y ; } Point ; diff --git a/src/plugins/wp/tests/wp_acsl/oracle/logic.res.oracle b/src/plugins/wp/tests/wp_acsl/oracle/logic.res.oracle index fe7f03a505d3ef3994930b9f69594c10c4126b1a..a3547cdccf7acb41cb77c368f97cbefbca8ec98c 100644 --- a/src/plugins/wp/tests/wp_acsl/oracle/logic.res.oracle +++ b/src/plugins/wp/tests/wp_acsl/oracle/logic.res.oracle @@ -1,17 +1,11 @@ -# frama-c -wp -wp-model 'Typed (Cast)' [...] +# frama-c -wp [...] [kernel] Parsing tests/wp_acsl/logic.i (no preprocessing) [wp] Running WP plugin... [wp] Loading driver 'share/wp.driver' [wp] Warning: Missing RTE guards -[wp] tests/wp_acsl/logic.i:16: Warning: - Cast with incompatible pointers types (source: __anonstruct_Point_1*) - (target: __anonstruct_Point_1[3]*) [wp] tests/wp_acsl/logic.i:65: Warning: Cast with incompatible pointers types (source: __anonstruct_Buint_4*) (target: uint32*) -[wp] tests/wp_acsl/logic.i:48: Warning: - Cast with incompatible pointers types (source: __anonstruct_Point_1*) - (target: __anonstruct_Point_1[3]*) [wp] tests/wp_acsl/logic.i:49: Warning: Logic cast from struct (Tint2) not implemented yet [wp] tests/wp_acsl/logic.i:50: Warning: @@ -45,28 +39,16 @@ ------------------------------------------------------------ Goal Post-condition (file tests/wp_acsl/logic.i, line 21) in 'h': -tests/wp_acsl/logic.i:16: warning from Typed Model: - - Warning: Keep pointer value - Reason: Cast with incompatible pointers types (source: __anonstruct_Point_1*) - (target: __anonstruct_Point_1[3]*) Prove: true. ------------------------------------------------------------ Goal Assigns nothing in 'h': -tests/wp_acsl/logic.i:16: warning from Typed Model: - - Warning: Keep pointer value - Reason: Cast with incompatible pointers types (source: __anonstruct_Point_1*) - (target: __anonstruct_Point_1[3]*) Prove: true. ------------------------------------------------------------ Goal Assigns nothing in 'h': -tests/wp_acsl/logic.i:16: warning from Typed Model: - - Warning: Keep pointer value - Reason: Cast with incompatible pointers types (source: __anonstruct_Point_1*) - (target: __anonstruct_Point_1[3]*) Prove: true. ------------------------------------------------------------ @@ -84,19 +66,18 @@ Let a = global(G_tr_31). Let a_1 = shift___anonstruct_Point_1(a, 2). Let a_2 = shift___anonstruct_Point_1(a, 1). Let a_3 = shift___anonstruct_Point_1(a, 0). -Let a_4 = global(G_buint_37). -Let a_5 = shiftfield_F4_bytes(a_4). +Let a_4 = shiftfield_F4_bytes(global(G_buint_37)). Let m = Array1_S1(a_3, 3, Mint_0). Assume { - Type: is_uint32(Mint_0[a_4]) /\ IsArray1S1(m). + Type: IsArray1S1(m). (* Initializer *) - Init: Mint_0[shift_uint8(a_5, 0)] = 1. + Init: Mint_0[shift_uint8(a_4, 0)] = 1. (* Initializer *) - Init: Mint_0[shift_uint8(a_5, 1)] = 2. + Init: Mint_0[shift_uint8(a_4, 1)] = 2. (* Initializer *) - Init: Mint_0[shift_uint8(a_5, 2)] = 4. + Init: Mint_0[shift_uint8(a_4, 2)] = 4. (* Initializer *) - Init: Mint_0[shift_uint8(a_5, 3)] = 8. + Init: Mint_0[shift_uint8(a_4, 3)] = 8. (* Initializer *) Init: Mint_0[shiftfield_F1_x(a_3)] = 10. (* Initializer *) @@ -121,19 +102,18 @@ Let a = global(G_tr_31). Let a_1 = shift___anonstruct_Point_1(a, 2). Let a_2 = shift___anonstruct_Point_1(a, 1). Let a_3 = shift___anonstruct_Point_1(a, 0). -Let a_4 = global(G_buint_37). -Let a_5 = shiftfield_F4_bytes(a_4). +Let a_4 = shiftfield_F4_bytes(global(G_buint_37)). Let m = Array1_S1(a_3, 3, Mint_0). Assume { - Type: is_uint32(Mint_0[a_4]) /\ IsArray1S1(m). + Type: IsArray1S1(m). (* Initializer *) - Init: Mint_0[shift_uint8(a_5, 0)] = 1. + Init: Mint_0[shift_uint8(a_4, 0)] = 1. (* Initializer *) - Init: Mint_0[shift_uint8(a_5, 1)] = 2. + Init: Mint_0[shift_uint8(a_4, 1)] = 2. (* Initializer *) - Init: Mint_0[shift_uint8(a_5, 2)] = 4. + Init: Mint_0[shift_uint8(a_4, 2)] = 4. (* Initializer *) - Init: Mint_0[shift_uint8(a_5, 3)] = 8. + Init: Mint_0[shift_uint8(a_4, 3)] = 8. (* Initializer *) Init: Mint_0[shiftfield_F1_x(a_3)] = 10. (* Initializer *) @@ -154,27 +134,22 @@ Prove: P_P(m). ------------------------------------------------------------ Goal Pre-condition 'qed_ok' in 'main': -tests/wp_acsl/logic.i:48: warning from Typed Model: - - Warning: Keep pointer value - Reason: Cast with incompatible pointers types (source: __anonstruct_Point_1*) - (target: __anonstruct_Point_1[3]*) Let a = global(G_tr_31). Let a_1 = shift___anonstruct_Point_1(a, 2). Let a_2 = shift___anonstruct_Point_1(a, 1). Let a_3 = shift___anonstruct_Point_1(a, 0). -Let a_4 = global(G_buint_37). -Let a_5 = shiftfield_F4_bytes(a_4). +Let a_4 = shiftfield_F4_bytes(global(G_buint_37)). Let m = Array1_S1(a_3, 3, Mint_0). Assume { - Type: is_uint32(Mint_0[a_4]) /\ IsArray1S1(m). + Type: IsArray1S1(m). (* Initializer *) - Init: Mint_0[shift_uint8(a_5, 0)] = 1. + Init: Mint_0[shift_uint8(a_4, 0)] = 1. (* Initializer *) - Init: Mint_0[shift_uint8(a_5, 1)] = 2. + Init: Mint_0[shift_uint8(a_4, 1)] = 2. (* Initializer *) - Init: Mint_0[shift_uint8(a_5, 2)] = 4. + Init: Mint_0[shift_uint8(a_4, 2)] = 4. (* Initializer *) - Init: Mint_0[shift_uint8(a_5, 3)] = 8. + Init: Mint_0[shift_uint8(a_4, 3)] = 8. (* Initializer *) Init: Mint_0[shiftfield_F1_x(a_3)] = 10. (* Initializer *) @@ -260,7 +235,7 @@ Let a_4 = global(G_buint_37). Let a_5 = shiftfield_F4_bytes(a_4). Let a_6 = Load_S4(a_4, Mint_0). Assume { - Type: is_uint32(Mint_0[a_4]) /\ IsS4(a_6). + Type: IsS4(a_6). (* Initializer *) Init: Mint_0[shift_uint8(a_5, 0)] = 1. (* Initializer *) diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/logic.0.report.json b/src/plugins/wp/tests/wp_acsl/oracle_qualif/logic.0.report.json index badcee8deb06c806b1e1fba397198f03ad075183..ab5fc8563a85e73fde964694df6276391d9aa62d 100644 --- a/src/plugins/wp/tests/wp_acsl/oracle_qualif/logic.0.report.json +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/logic.0.report.json @@ -1,21 +1,17 @@ -{ "wp:global": { "alt-ergo": { "total": 18, "valid": 2, "unknown": 16, +{ "wp:global": { "alt-ergo": { "total": 17, "valid": 3, "unknown": 14, "rank": 16 }, - "qed": { "total": 3, "valid": 3 }, - "wp:main": { "total": 21, "valid": 5, "unknown": 16, + "qed": { "total": 4, "valid": 4 }, + "wp:main": { "total": 21, "valid": 7, "unknown": 14, "rank": 16 } }, "wp:functions": { "h": { "h_assigns": { "qed": { "total": 2, "valid": 2 }, "wp:main": { "total": 2, "valid": 2 } }, - "h_ensures": { "alt-ergo": { "total": 1, - "unknown": 1 }, + "h_ensures": { "qed": { "total": 1, "valid": 1 }, "wp:main": { "total": 1, - "unknown": 1 } }, - "wp:section": { "alt-ergo": { "total": 1, - "unknown": 1 }, - "qed": { "total": 2, "valid": 2 }, + "valid": 1 } }, + "wp:section": { "qed": { "total": 3, "valid": 3 }, "wp:main": { "total": 3, - "valid": 2, - "unknown": 1 } } }, + "valid": 3 } } }, "main": { "main_requires_qed_ok_18": { "alt-ergo": { "total": 1, "unknown": 1 }, @@ -102,10 +98,12 @@ "unknown": 1 } }, "main_requires_qed_ok_4": { "alt-ergo": { "total": 1, - "unknown": 1 }, + "valid": 1, + "rank": 16 }, "wp:main": { "total": 1, - "unknown": 1 } }, + "valid": 1, + "rank": 16 } }, "main_requires_qed_ok_3": { "alt-ergo": { "total": 1, "valid": 1, @@ -127,12 +125,12 @@ "wp:main": { "total": 1, "valid": 1 } }, "wp:section": { "alt-ergo": { "total": 17, - "valid": 2, - "unknown": 15, + "valid": 3, + "unknown": 14, "rank": 16 }, "qed": { "total": 1, "valid": 1 }, "wp:main": { "total": 18, - "valid": 3, - "unknown": 15, + "valid": 4, + "unknown": 14, "rank": 16 } } } } } diff --git a/src/plugins/wp/tests/wp_acsl/oracle_qualif/logic.res.oracle b/src/plugins/wp/tests/wp_acsl/oracle_qualif/logic.res.oracle index a5be47ac2193ae3620930ed953b31516bf056d01..225cf1c40b801ddb410faaf397268ef0e62ef1e3 100644 --- a/src/plugins/wp/tests/wp_acsl/oracle_qualif/logic.res.oracle +++ b/src/plugins/wp/tests/wp_acsl/oracle_qualif/logic.res.oracle @@ -1,17 +1,11 @@ -# frama-c -wp -wp-timeout 90 -wp-steps 1500 [...] +# frama-c -wp -wp-timeout 90 -wp-steps 50 [...] [kernel] Parsing tests/wp_acsl/logic.i (no preprocessing) [wp] Running WP plugin... [wp] Loading driver 'share/wp.driver' [wp] Warning: Missing RTE guards -[wp] tests/wp_acsl/logic.i:16: Warning: - Cast with incompatible pointers types (source: __anonstruct_Point_1*) - (target: __anonstruct_Point_1[3]*) [wp] tests/wp_acsl/logic.i:65: Warning: Cast with incompatible pointers types (source: __anonstruct_Buint_4*) (target: uint32*) -[wp] tests/wp_acsl/logic.i:48: Warning: - Cast with incompatible pointers types (source: __anonstruct_Point_1*) - (target: __anonstruct_Point_1[3]*) [wp] tests/wp_acsl/logic.i:49: Warning: Logic cast from struct (Tint2) not implemented yet [wp] tests/wp_acsl/logic.i:50: Warning: @@ -41,13 +35,13 @@ [wp] tests/wp_acsl/logic.i:62: Warning: Logic cast to struct (Tint2) from (int [6]) not implemented yet [wp] 21 goals scheduled -[wp] [Alt-Ergo] Goal typed_h_ensures : Unsuccess (Stronger) +[wp] [Qed] Goal typed_h_ensures : Valid [wp] [Qed] Goal typed_h_assigns_exit : Valid [wp] [Qed] Goal typed_h_assigns_normal : Valid [wp] [Qed] Goal typed_main_requires_qed_ok : Valid -[wp] [Alt-Ergo] Goal typed_main_requires_qed_ok_2 : Valid -[wp] [Alt-Ergo] Goal typed_main_requires_qed_ok_3 : Valid -[wp] [Alt-Ergo] Goal typed_main_requires_qed_ok_4 : Unsuccess (Stronger) +[wp] [Alt-Ergo] Goal typed_main_requires_qed_ok_2 : Unsuccess +[wp] [Alt-Ergo] Goal typed_main_requires_qed_ok_3 : Unsuccess +[wp] [Alt-Ergo] Goal typed_main_requires_qed_ok_4 : Unsuccess [wp] [Alt-Ergo] Goal typed_main_requires_qed_ok_5 : Unsuccess (Stronger) [wp] [Alt-Ergo] Goal typed_main_requires_qed_ok_6 : Unsuccess (Stronger) [wp] [Alt-Ergo] Goal typed_main_requires_qed_ok_7 : Unsuccess (Stronger) @@ -62,13 +56,13 @@ [wp] [Alt-Ergo] Goal typed_main_requires_qed_ok_16 : Unsuccess (Stronger) [wp] [Alt-Ergo] Goal typed_main_requires_qed_ok_17 : Unsuccess (Stronger) [wp] [Alt-Ergo] Goal typed_main_requires_qed_ok_18 : Unsuccess (Stronger) -[wp] Proved goals: 5 / 21 - Qed: 3 - Alt-Ergo: 2 (unsuccess: 16) +[wp] Proved goals: 4 / 21 + Qed: 4 + Alt-Ergo: 0 (unsuccess: 17) [wp] Report in: 'tests/wp_acsl/oracle_qualif/logic.0.report.json' [wp] Report out: 'tests/wp_acsl/result_qualif/logic.0.report.json' ------------------------------------------------------------- Functions WP Alt-Ergo Total Success -h 2 - 3 66.7% -main 1 2 (56..80) 18 16.7% +h 3 - 3 100% +main 1 - 18 5.6% ------------------------------------------------------------- diff --git a/src/plugins/wp/tests/wp_typed/cast_fits.i b/src/plugins/wp/tests/wp_typed/cast_fits.i new file mode 100644 index 0000000000000000000000000000000000000000..8c0fcba18e0ea93237fea667cf06a76012ee0840 --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/cast_fits.i @@ -0,0 +1,62 @@ +typedef struct { int i1; char c1; } L1 ; + +//@ ensures \result == p->i1; +int fits1(L1 * p) { + int * q = (int *) p; + return *q; +} + +typedef struct { char c2; int i2; } L2; + +//@ ensures \result == p->c2; +int mismatch1(L2 * p) { + int * q = (int *) p; + return *q; +} + +typedef struct { char c3; L1 ic3; int i3; } L3 ; + +//@ ensures \result == p->ic3.i1; +int fits2(L3 * p) { + L2 * q = (L2 *) p; + return q->i2; +} + +typedef struct { char c4; L1 ic4[2]; int i4; } L4 ; + +//@ ensures \result == p->ic4[0].i1; +int fits3(L4 * p) { + L2 * q = (L2 *) p; + return q->i2; +} + +typedef struct { L3 ci5[2]; } L5 ; + +typedef struct { L2 ci6[2]; char c6; } L6 ; + +//@ ensures \result == p->ci5[1].c3; +int fits4(L5 * p) { + L6 * q = (L6 *) p; + return q->c6; +} + +typedef union { int u7; } L7 ; + +//@ ensures \result == p->u7; +int fits5(L7 * p) { + int * q = (int *) p; + return *q; +} + +typedef union { int i8; char u8; double d8;} L8 ; +//@ ensures \result == p->i8; +int mismatch2(L8 * p) { + int * q = (int *) p; + return *q; +} + +//@ ensures \result == *p; +int mismatch3(int * p) { + L8 * q = (L8 *) p; + return q->i8; +} diff --git a/src/plugins/wp/tests/wp_typed/oracle/cast_fits.0.res.oracle b/src/plugins/wp/tests/wp_typed/oracle/cast_fits.0.res.oracle new file mode 100644 index 0000000000000000000000000000000000000000..56beccaf01fa52665901dd19e21253de0b119058 --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle/cast_fits.0.res.oracle @@ -0,0 +1,150 @@ +# frama-c -wp [...] +[kernel] Parsing tests/wp_typed/cast_fits.i (no preprocessing) +[wp] Running WP plugin... +[wp] Loading driver 'share/wp.driver' +[wp] Warning: Missing RTE guards +[wp] tests/wp_typed/cast_fits.i:13: Warning: + Cast with incompatible pointers types (source: __anonstruct_L2_2*) + (target: sint32*) +[wp] tests/wp_typed/cast_fits.i:54: Warning: + Cast with incompatible pointers types (source: __anonunion_L8_8*) + (target: sint32*) +[wp] tests/wp_typed/cast_fits.i:60: Warning: + Cast with incompatible pointers types (source: sint32*) + (target: __anonunion_L8_8*) +------------------------------------------------------------ + Function fits1 +------------------------------------------------------------ + +Goal Post-condition (file tests/wp_typed/cast_fits.i, line 3) in 'fits1': +Let x = Mint_0[p]. +Let x_1 = Mint_0[shiftfield_F1_i1(p)]. +Assume { + Type: is_sint32(x) /\ is_sint32(x_1). + (* Heap *) + Have: region(p.base) <= 0. +} +Prove: x_1 = x. + +------------------------------------------------------------ +------------------------------------------------------------ + Function fits2 +------------------------------------------------------------ + +Goal Post-condition (file tests/wp_typed/cast_fits.i, line 19) in 'fits2': +Let x = Mint_0[shiftfield_F2_i2(p)]. +Let x_1 = Mint_0[shiftfield_F1_i1(shiftfield_F3_ic3(p))]. +Assume { + Type: is_sint32(x) /\ is_sint32(x_1). + (* Heap *) + Have: region(p.base) <= 0. +} +Prove: x_1 = x. + +------------------------------------------------------------ +------------------------------------------------------------ + Function fits3 +------------------------------------------------------------ + +Goal Post-condition (file tests/wp_typed/cast_fits.i, line 27) in 'fits3': +Let x = Mint_0[shiftfield_F2_i2(p)]. +Let x_1 = Mint_0 + [shiftfield_F1_i1(shift___anonstruct_L1_1(shiftfield_F4_ic4(p), + 0))]. +Assume { + Type: is_sint32(x) /\ is_sint32(x_1). + (* Heap *) + Have: region(p.base) <= 0. +} +Prove: x_1 = x. + +------------------------------------------------------------ +------------------------------------------------------------ + Function fits4 +------------------------------------------------------------ + +Goal Post-condition (file tests/wp_typed/cast_fits.i, line 37) in 'fits4': +Let x = Mchar_0[shiftfield_F6_c6(p)]. +Let x_1 = Mchar_0 + [shiftfield_F3_c3(shift___anonstruct_L3_3(shiftfield_F5_ci5(p), + 1))]. +Assume { + Type: is_sint8(x) /\ is_sint32(x) /\ is_sint8(x_1). + (* Heap *) + Have: (region(p.base) <= 0) /\ sconst(Mchar_0). +} +Prove: x_1 = x. + +------------------------------------------------------------ +------------------------------------------------------------ + Function fits5 +------------------------------------------------------------ + +Goal Post-condition (file tests/wp_typed/cast_fits.i, line 45) in 'fits5': +Let x = Mint_0[p]. +Let x_1 = Mint_0[shiftfield_F7_u7(p)]. +Assume { + Type: is_sint32(x) /\ is_sint32(x_1). + (* Heap *) + Have: region(p.base) <= 0. +} +Prove: x_1 = x. + +------------------------------------------------------------ +------------------------------------------------------------ + Function mismatch1 +------------------------------------------------------------ + +Goal Post-condition (file tests/wp_typed/cast_fits.i, line 11) in 'mismatch1': +tests/wp_typed/cast_fits.i:13: warning from Typed Model: + - Warning: Hide sub-term definition + Reason: Cast with incompatible pointers types (source: __anonstruct_L2_2*) + (target: sint32*) +Let x = Mint_0[q]. +Let x_1 = Mchar_0[shiftfield_F2_c2(p)]. +Assume { + Type: is_sint32(x) /\ is_sint8(x_1). + (* Heap *) + Have: (region(p.base) <= 0) /\ sconst(Mchar_0). +} +Prove: x_1 = x. + +------------------------------------------------------------ +------------------------------------------------------------ + Function mismatch2 +------------------------------------------------------------ + +Goal Post-condition (file tests/wp_typed/cast_fits.i, line 52) in 'mismatch2': +tests/wp_typed/cast_fits.i:54: warning from Typed Model: + - Warning: Hide sub-term definition + Reason: Cast with incompatible pointers types (source: __anonunion_L8_8*) + (target: sint32*) +Let x = Mint_0[q]. +Let x_1 = Mint_0[shiftfield_F8_i8(p)]. +Assume { + Type: is_sint32(x) /\ is_sint32(x_1). + (* Heap *) + Have: region(p.base) <= 0. +} +Prove: x_1 = x. + +------------------------------------------------------------ +------------------------------------------------------------ + Function mismatch3 +------------------------------------------------------------ + +Goal Post-condition (file tests/wp_typed/cast_fits.i, line 58) in 'mismatch3': +tests/wp_typed/cast_fits.i:60: warning from Typed Model: + - Warning: Hide sub-term definition + Reason: Cast with incompatible pointers types (source: sint32*) + (target: __anonunion_L8_8*) +Let x = Mint_0[p]. +Let x_1 = Mint_0[shiftfield_F8_i8(q)]. +Assume { + Type: is_sint32(x) /\ is_sint32(x_1). + (* Heap *) + Have: region(p.base) <= 0. +} +Prove: x_1 = x. + +------------------------------------------------------------ diff --git a/src/plugins/wp/tests/wp_typed/oracle/cast_fits.1.res.oracle b/src/plugins/wp/tests/wp_typed/oracle/cast_fits.1.res.oracle new file mode 100644 index 0000000000000000000000000000000000000000..cc8072d61ce0f259dd2e73a19b11d96f46c2512d --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle/cast_fits.1.res.oracle @@ -0,0 +1,150 @@ +# frama-c -wp -wp-model 'Typed (Ref)' [...] +[kernel] Parsing tests/wp_typed/cast_fits.i (no preprocessing) +[wp] Running WP plugin... +[wp] Loading driver 'share/wp.driver' +[wp] Warning: Missing RTE guards +[wp] tests/wp_typed/cast_fits.i:13: Warning: + Cast with incompatible pointers types (source: __anonstruct_L2_2*) + (target: sint32*) +[wp] tests/wp_typed/cast_fits.i:54: Warning: + Cast with incompatible pointers types (source: __anonunion_L8_8*) + (target: sint32*) +[wp] tests/wp_typed/cast_fits.i:60: Warning: + Cast with incompatible pointers types (source: sint32*) + (target: __anonunion_L8_8*) +------------------------------------------------------------ + Function fits1 +------------------------------------------------------------ + +Goal Post-condition (file tests/wp_typed/cast_fits.i, line 3) in 'fits1': +Let x = Mint_0[p]. +Let x_1 = Mint_0[shiftfield_F1_i1(p)]. +Assume { + Type: is_sint32(x) /\ is_sint32(x_1). + (* Heap *) + Have: region(p.base) <= 0. +} +Prove: x_1 = x. + +------------------------------------------------------------ +------------------------------------------------------------ + Function fits2 +------------------------------------------------------------ + +Goal Post-condition (file tests/wp_typed/cast_fits.i, line 19) in 'fits2': +Let x = Mint_0[shiftfield_F2_i2(p)]. +Let x_1 = Mint_0[shiftfield_F1_i1(shiftfield_F3_ic3(p))]. +Assume { + Type: is_sint32(x) /\ is_sint32(x_1). + (* Heap *) + Have: region(p.base) <= 0. +} +Prove: x_1 = x. + +------------------------------------------------------------ +------------------------------------------------------------ + Function fits3 +------------------------------------------------------------ + +Goal Post-condition (file tests/wp_typed/cast_fits.i, line 27) in 'fits3': +Let x = Mint_0[shiftfield_F2_i2(p)]. +Let x_1 = Mint_0 + [shiftfield_F1_i1(shift___anonstruct_L1_1(shiftfield_F4_ic4(p), + 0))]. +Assume { + Type: is_sint32(x) /\ is_sint32(x_1). + (* Heap *) + Have: region(p.base) <= 0. +} +Prove: x_1 = x. + +------------------------------------------------------------ +------------------------------------------------------------ + Function fits4 +------------------------------------------------------------ + +Goal Post-condition (file tests/wp_typed/cast_fits.i, line 37) in 'fits4': +Let x = Mchar_0[shiftfield_F6_c6(p)]. +Let x_1 = Mchar_0 + [shiftfield_F3_c3(shift___anonstruct_L3_3(shiftfield_F5_ci5(p), + 1))]. +Assume { + Type: is_sint8(x) /\ is_sint32(x) /\ is_sint8(x_1). + (* Heap *) + Have: (region(p.base) <= 0) /\ sconst(Mchar_0). +} +Prove: x_1 = x. + +------------------------------------------------------------ +------------------------------------------------------------ + Function fits5 +------------------------------------------------------------ + +Goal Post-condition (file tests/wp_typed/cast_fits.i, line 45) in 'fits5': +Let x = Mint_0[p]. +Let x_1 = Mint_0[shiftfield_F7_u7(p)]. +Assume { + Type: is_sint32(x) /\ is_sint32(x_1). + (* Heap *) + Have: region(p.base) <= 0. +} +Prove: x_1 = x. + +------------------------------------------------------------ +------------------------------------------------------------ + Function mismatch1 +------------------------------------------------------------ + +Goal Post-condition (file tests/wp_typed/cast_fits.i, line 11) in 'mismatch1': +tests/wp_typed/cast_fits.i:13: warning from Typed Model: + - Warning: Hide sub-term definition + Reason: Cast with incompatible pointers types (source: __anonstruct_L2_2*) + (target: sint32*) +Let x = Mint_0[q]. +Let x_1 = Mchar_0[shiftfield_F2_c2(p)]. +Assume { + Type: is_sint32(x) /\ is_sint8(x_1). + (* Heap *) + Have: (region(p.base) <= 0) /\ sconst(Mchar_0). +} +Prove: x_1 = x. + +------------------------------------------------------------ +------------------------------------------------------------ + Function mismatch2 +------------------------------------------------------------ + +Goal Post-condition (file tests/wp_typed/cast_fits.i, line 52) in 'mismatch2': +tests/wp_typed/cast_fits.i:54: warning from Typed Model: + - Warning: Hide sub-term definition + Reason: Cast with incompatible pointers types (source: __anonunion_L8_8*) + (target: sint32*) +Let x = Mint_0[q]. +Let x_1 = Mint_0[shiftfield_F8_i8(p)]. +Assume { + Type: is_sint32(x) /\ is_sint32(x_1). + (* Heap *) + Have: region(p.base) <= 0. +} +Prove: x_1 = x. + +------------------------------------------------------------ +------------------------------------------------------------ + Function mismatch3 +------------------------------------------------------------ + +Goal Post-condition (file tests/wp_typed/cast_fits.i, line 58) in 'mismatch3': +tests/wp_typed/cast_fits.i:60: warning from Typed Model: + - Warning: Hide sub-term definition + Reason: Cast with incompatible pointers types (source: sint32*) + (target: __anonunion_L8_8*) +Let x = Mint_0[p]. +Let x_1 = Mint_0[shiftfield_F8_i8(q)]. +Assume { + Type: is_sint32(x) /\ is_sint32(x_1). + (* Heap *) + Have: region(p.base) <= 0. +} +Prove: x_1 = x. + +------------------------------------------------------------ diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/cast_fits.0.report.json b/src/plugins/wp/tests/wp_typed/oracle_qualif/cast_fits.0.report.json new file mode 100644 index 0000000000000000000000000000000000000000..193b5d5e58bebc238a27b6c45e343141affb683a --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/cast_fits.0.report.json @@ -0,0 +1,94 @@ +{ "wp:global": { "alt-ergo": { "total": 8, "valid": 5, "unknown": 3, + "rank": 8 }, + "wp:main": { "total": 8, "valid": 5, "unknown": 3, + "rank": 8 } }, + "wp:functions": { "fits1": { "fits1_ensures": { "alt-ergo": { "total": 1, + "valid": 1, + "rank": 6 }, + "wp:main": { "total": 1, + "valid": 1, + "rank": 6 } }, + "wp:section": { "alt-ergo": { "total": 1, + "valid": 1, + "rank": 6 }, + "wp:main": { "total": 1, + "valid": 1, + "rank": 6 } } }, + "mismatch1": { "mismatch1_ensures": { "alt-ergo": + { "total": 1, + "unknown": 1 }, + "wp:main": + { "total": 1, + "unknown": 1 } }, + "wp:section": { "alt-ergo": { "total": 1, + "unknown": 1 }, + "wp:main": { "total": 1, + "unknown": 1 } } }, + "fits2": { "fits2_ensures": { "alt-ergo": { "total": 1, + "valid": 1, + "rank": 6 }, + "wp:main": { "total": 1, + "valid": 1, + "rank": 6 } }, + "wp:section": { "alt-ergo": { "total": 1, + "valid": 1, + "rank": 6 }, + "wp:main": { "total": 1, + "valid": 1, + "rank": 6 } } }, + "fits3": { "fits3_ensures": { "alt-ergo": { "total": 1, + "valid": 1, + "rank": 7 }, + "wp:main": { "total": 1, + "valid": 1, + "rank": 7 } }, + "wp:section": { "alt-ergo": { "total": 1, + "valid": 1, + "rank": 7 }, + "wp:main": { "total": 1, + "valid": 1, + "rank": 7 } } }, + "fits4": { "fits4_ensures": { "alt-ergo": { "total": 1, + "valid": 1, + "rank": 8 }, + "wp:main": { "total": 1, + "valid": 1, + "rank": 8 } }, + "wp:section": { "alt-ergo": { "total": 1, + "valid": 1, + "rank": 8 }, + "wp:main": { "total": 1, + "valid": 1, + "rank": 8 } } }, + "fits5": { "fits5_ensures": { "alt-ergo": { "total": 1, + "valid": 1, + "rank": 6 }, + "wp:main": { "total": 1, + "valid": 1, + "rank": 6 } }, + "wp:section": { "alt-ergo": { "total": 1, + "valid": 1, + "rank": 6 }, + "wp:main": { "total": 1, + "valid": 1, + "rank": 6 } } }, + "mismatch2": { "mismatch2_ensures": { "alt-ergo": + { "total": 1, + "unknown": 1 }, + "wp:main": + { "total": 1, + "unknown": 1 } }, + "wp:section": { "alt-ergo": { "total": 1, + "unknown": 1 }, + "wp:main": { "total": 1, + "unknown": 1 } } }, + "mismatch3": { "mismatch3_ensures": { "alt-ergo": + { "total": 1, + "unknown": 1 }, + "wp:main": + { "total": 1, + "unknown": 1 } }, + "wp:section": { "alt-ergo": { "total": 1, + "unknown": 1 }, + "wp:main": { "total": 1, + "unknown": 1 } } } } } diff --git a/src/plugins/wp/tests/wp_typed/oracle_qualif/cast_fits.res.oracle b/src/plugins/wp/tests/wp_typed/oracle_qualif/cast_fits.res.oracle new file mode 100644 index 0000000000000000000000000000000000000000..6bc88bcb22a2bf7acb1f1acca3ffc64da2dca480 --- /dev/null +++ b/src/plugins/wp/tests/wp_typed/oracle_qualif/cast_fits.res.oracle @@ -0,0 +1,39 @@ +# frama-c -wp -wp-timeout 90 -wp-steps 1500 [...] +[kernel] Parsing tests/wp_typed/cast_fits.i (no preprocessing) +[wp] Running WP plugin... +[wp] Loading driver 'share/wp.driver' +[wp] Warning: Missing RTE guards +[wp] tests/wp_typed/cast_fits.i:13: Warning: + Cast with incompatible pointers types (source: __anonstruct_L2_2*) + (target: sint32*) +[wp] tests/wp_typed/cast_fits.i:54: Warning: + Cast with incompatible pointers types (source: __anonunion_L8_8*) + (target: sint32*) +[wp] tests/wp_typed/cast_fits.i:60: Warning: + Cast with incompatible pointers types (source: sint32*) + (target: __anonunion_L8_8*) +[wp] 8 goals scheduled +[wp] [Alt-Ergo] Goal typed_fits1_ensures : Valid +[wp] [Alt-Ergo] Goal typed_fits2_ensures : Valid +[wp] [Alt-Ergo] Goal typed_fits3_ensures : Valid +[wp] [Alt-Ergo] Goal typed_fits4_ensures : Valid +[wp] [Alt-Ergo] Goal typed_fits5_ensures : Valid +[wp] [Alt-Ergo] Goal typed_mismatch1_ensures : Unsuccess (Stronger) +[wp] [Alt-Ergo] Goal typed_mismatch2_ensures : Unsuccess (Stronger) +[wp] [Alt-Ergo] Goal typed_mismatch3_ensures : Unsuccess (Stronger) +[wp] Proved goals: 5 / 8 + Qed: 0 + Alt-Ergo: 5 (unsuccess: 3) +[wp] Report in: 'tests/wp_typed/oracle_qualif/cast_fits.0.report.json' +[wp] Report out: 'tests/wp_typed/result_qualif/cast_fits.0.report.json' +------------------------------------------------------------- +Functions WP Alt-Ergo Total Success +fits1 - 1 (20..32) 1 100% +mismatch1 - - 1 0.0% +fits2 - 1 (20..32) 1 100% +fits3 - 1 (24..36) 1 100% +fits4 - 1 (28..40) 1 100% +fits5 - 1 (20..32) 1 100% +mismatch2 - - 1 0.0% +mismatch3 - - 1 0.0% +-------------------------------------------------------------