diff --git a/convert.ml b/convert.ml index 7f39ea8f7a4287431201ce41c86b4f85841c69a8..6a3c47a58ee58fcc1bc0c4913c4a163f38afb761 100644 --- a/convert.ml +++ b/convert.ml @@ -119,31 +119,14 @@ let rec protect_ptr_type al d = let spec_type t = SpecType t -let spec_of_ikind s = - Cil_types.( - match s with - | IBool -> [ SpecType Tbool ] - | IChar -> [ SpecType Tchar ] - | ISChar -> [ SpecType Tsigned; SpecType Tchar ] - | IUChar -> [ SpecType Tunsigned; SpecType Tchar ] - | IInt -> [ SpecType Tint ] - | IUInt -> [ SpecType Tunsigned ] - | IShort -> [ SpecType Tshort ] - | IUShort -> [ SpecType Tunsigned; SpecType Tshort ] - | ILong -> [ SpecType Tlong ] - | IULong -> [ SpecType Tunsigned; SpecType Tlong ] - | ILongLong -> [ SpecType Tlong; SpecType Tlong ] - | IULongLong -> [ SpecType Tunsigned; SpecType Tlong; SpecType Tlong ] - ) - let make_integral_constant_kind k v = let v = Integer.to_string v in let s = match k with | IBool - | IChar_s | ISChar | IWChar_s | IWSChar + | IChar_s | ISChar | IWChar_s | IChar | IWChar | IShort | IInt -> "" - | IChar_u | IUChar | IChar16 | IChar32 | IWChar_u | IWUChar + | IChar_u | IUChar | IChar16 | IChar32 | IWChar_u | IUShort | IUInt -> "U" | ILong -> "L" | IULong -> "UL" @@ -154,10 +137,10 @@ let make_integral_constant_kind k v = let is_unsigned_kind = function | IBool -> true (* standard says that bool is neither signed nor unsigned, but at some point you have to take sides. *) - | IChar_s | ISChar | IWChar_s | IWSChar -> false + | IChar_s | ISChar | IWChar_s -> false | IChar | IWChar -> Cil.theMachine.theMachine.char_is_unsigned | IShort | IInt -> false - | IChar_u | IUChar | IChar16 | IChar32 | IWChar_u | IWUChar + | IChar_u | IUChar | IChar16 | IChar32 | IWChar_u | IUShort | IUInt -> true | ILong | ILongLong -> false | IULong | IULongLong -> true @@ -587,71 +570,67 @@ let preserved_returned_object aux e = List.map transf aux | _ -> aux +let convert_class_name env name tc = + if Convert_env.is_extern_c_aggregate env name tc then name.decl_name + else + let s, t = Convert_env.typedef_normalize env name tc in + Mangling.mangle s t None + +let qual_vmt_content_name = Cxx_utils.empty_qual "_frama_c_vmt_content" +let qual_vmt_name = Cxx_utils.empty_qual "_frama_c_vmt" + +let mk_vmt_content_type env = + let name, tc = + Convert_env.typedef_normalize env qual_vmt_content_name TStandard + in + Tstruct (convert_class_name env name tc, None, []) + +let mk_vmt_type env = + let name, tc = Convert_env.typedef_normalize env qual_vmt_name TStandard in + Tstruct (convert_class_name env name tc, None, []) + let rec convert_base_type env spec decl typ does_remove_virtual = match typ with - | Void -> spec_type Tvoid :: spec, decl - | Int IBool -> spec_type Tbool :: spec, decl - | Int (IChar_u | IChar_s | IChar) -> spec_type Tchar :: spec, decl - | Int IUChar -> (List.map spec_type [Tunsigned; Tchar]) @ spec, decl - | Int ISChar -> (List.map spec_type [Tsigned; Tchar ]) @ spec, decl + | Void -> env, (spec_type Tvoid :: spec, decl) + | Int IBool -> env, (spec_type Tbool :: spec, decl) + | Int (IChar_u | IChar_s | IChar) -> env, (spec_type Tchar :: spec, decl) + | Int IUChar -> env, ((List.map spec_type [Tunsigned; Tchar]) @ spec, decl) + | Int ISChar -> env, ((List.map spec_type [Tsigned; Tchar ]) @ spec, decl) (* TODO: intKindForSize returns a type of exactly 16 bits. There is no function for providing an ikind of at least 16 bits yet. This should be added to Cil. Indeed, it could theoretically be possible that intKindForSize 2 fails while there exist types of a strictly greater size. *) - | Int IChar16 -> spec_of_ikind (Cil.intKindForSize 2 true) @ spec, decl - | Int IChar32 -> spec_of_ikind (Cil.intKindForSize 4 true) @ spec, decl - | Int (IWChar_u | IWChar_s | IWUChar | IWSChar | IWChar ) -> - let wchar_name = { prequalification=[];decl_name="fc_wchar_t"} in - let base = - if Convert_env.has_typedef env wchar_name then begin - let rep = (Convert_env.get_typedef env wchar_name).plain_type in - match rep with - | Named (_,is_extern_c) -> - let name = - if is_extern_c then wchar_name.decl_name - else Mangling.mangle wchar_name TStandard None - in - [ SpecType (Tnamed name) ] - | Int _ -> - let spec,_ = - convert_base_type env [] decl rep does_remove_virtual - in - spec - | _ -> - Frama_Clang_option.fatal - "wchar_t should be linked to a named or integral type" - end else - spec_of_ikind Cil.theMachine.Cil.wcharKind - in - base @ spec, decl - | Int IInt -> spec_type Tint :: spec, decl - | Int IShort -> spec_type Tshort :: spec, decl - | Int IUShort -> (List.map spec_type [Tunsigned; Tshort ]) @ spec, decl - | Int IUInt -> (List.map spec_type [Tunsigned; Tint]) @ spec, decl - | Int ILong -> spec_type Tlong :: spec, decl - | Int IULong -> (List.map spec_type [Tunsigned; Tlong]) @ spec,decl - | Int ILongLong -> (List.map spec_type [Tlong; Tlong]) @ spec,decl + | Int IChar16 -> + env, (Cxx_utils.spec_of_ikind (Cil.intKindForSize 2 true) @ spec, decl) + | Int IChar32 -> + env, (Cxx_utils.spec_of_ikind (Cil.intKindForSize 4 true) @ spec, decl) + | Int (IWChar_u | IWChar_s | IWChar ) -> + let env = Convert_env.memo_wchar env in + env, (SpecType (Tnamed "wchar_t") :: spec, decl) + | Int IInt -> env, (spec_type Tint :: spec, decl) + | Int IShort -> env, (spec_type Tshort :: spec, decl) + | Int IUShort -> env, ((List.map spec_type [Tunsigned; Tshort ]) @ spec, decl) + | Int IUInt -> env, ((List.map spec_type [Tunsigned; Tint]) @ spec, decl) + | Int ILong -> env, (spec_type Tlong :: spec, decl) + | Int IULong -> env, ((List.map spec_type [Tunsigned; Tlong]) @ spec,decl) + | Int ILongLong -> env, ((List.map spec_type [Tlong; Tlong]) @ spec,decl) | Int IULongLong -> - (List.map spec_type [Tunsigned; Tlong; Tlong]) @ spec,decl - | Float FFloat -> spec_type Tfloat :: spec, decl - | Float FDouble -> spec_type Tdouble :: spec, decl - | Float FLongDouble -> (List.map spec_type [Tlong; Tdouble]) @ spec, decl + env, ((List.map spec_type [Tunsigned; Tlong; Tlong]) @ spec,decl) + | Float FFloat -> env, (spec_type Tfloat :: spec, decl) + | Float FDouble -> env, (spec_type Tdouble :: spec, decl) + | Float FLongDouble -> + env, ((List.map spec_type [Tlong; Tdouble]) @ spec, decl) | Enum e -> let body_name, t = Convert_env.typedef_normalize env e.body TStandard in let name = if e.ekind_is_extern_c then body_name.decl_name else Mangling.mangle body_name t None in - spec_type (Tenum(name,None,[]))::spec, decl + env, (spec_type (Tenum(name,None,[]))::spec, decl) | Struct (s,t) -> - let name = - if Convert_env.is_extern_c_aggregate env s t then s.decl_name - else - let s, t = Convert_env.typedef_normalize env s t in - Mangling.mangle s t None - in - spec_type (Tstruct (name, None, [])) :: spec, decl + let name = convert_class_name env s t in + env, (spec_type (Tstruct (name, None, [])) :: spec, decl) | Union (s,t) -> let name = if Convert_env.is_extern_c_aggregate env s t then s.decl_name @@ -659,7 +638,7 @@ let rec convert_base_type env spec decl typ does_remove_virtual = let s, t = Convert_env.typedef_normalize env s t in Mangling.mangle s t None in - spec_type (Tunion (name, None, [])) :: spec, decl + env, (spec_type (Tunion (name, None, [])) :: spec, decl) | Pointer (PDataPointer t) -> let attrs = List.map cv_to_attr spec in let decl d = decl (protect_ptr_type attrs d) in @@ -669,23 +648,25 @@ let rec convert_base_type env spec decl typ does_remove_virtual = convert_type env (fun d -> decl (protect_ptr_type attrs d)) t does_remove_virtual | Pointer (PFunctionPointer s) -> - let rt, rt_decl, args, variadic = + let env, (rt, rt_decl, args, variadic) = convert_fptr env s does_remove_virtual in let attrs = List.map cv_to_attr spec in - rt, - (fun d -> - rt_decl - (PROTO (decl (protect_ptr_type attrs d), args,[],variadic))) + env, + (rt, + (fun d -> + rt_decl + (PROTO (decl (protect_ptr_type attrs d), args,[],variadic)))) | LVReference (PFunctionPointer s) | RVReference (PFunctionPointer s) -> - let rt, rt_decl, args, variadic = + let env, (rt, rt_decl, args, variadic) = convert_fptr env s does_remove_virtual in let attrs= List.map cv_to_attr spec in - rt, - (fun d -> - rt_decl (PROTO (decl (protect_ptr_type attrs d),args,[],variadic))) + env, + (rt, + (fun d -> + rt_decl (PROTO (decl (protect_ptr_type attrs d),args,[],variadic)))) | Pointer(PStandardMethodPointer _) | LVReference (PStandardMethodPointer _) | RVReference (PStandardMethodPointer _) -> @@ -728,25 +709,26 @@ let rec convert_base_type env spec decl typ does_remove_virtual = let name, t = Convert_env.typedef_normalize env name TStandard in Mangling.mangle name t None in - spec_type (Tnamed cname)::spec, decl + env, (spec_type (Tnamed cname)::spec, decl) | Lambda _ -> let type_name = Mangling.mangle_cc_type typ in - (SpecType (Tstruct (type_name, None, []))) :: spec, decl + env, ((SpecType (Tstruct (type_name, None, []))) :: spec, decl) and convert_type env decl t does_remove_virtual = let spec = List.map convert_cv t.qualifier in convert_base_type env spec decl t.plain_type does_remove_virtual and convert_fptr env s does_remove_virtual = - let args, variadic = - if s.variadic && s.parameter = [] then [], false + let env, (args, variadic) = + if s.variadic && s.parameter = [] then env, ([], false) else - convert_signature env s.parameter does_remove_virtual, s.variadic + let env, l = convert_signature env s.parameter does_remove_virtual in + env, (l, s.variadic) in - let rt, rt_decl = + let env, (rt, rt_decl) = convert_specifiers env s.result does_remove_virtual in - rt, rt_decl, args, variadic + env, (rt, rt_decl, args, variadic) and convert_signature env l does_remove_virtual = match l with @@ -757,30 +739,37 @@ and convert_signature env l does_remove_virtual = provides one or more arguments. We thus normalize that to (void) for the C translation. *) - [ [SpecType Tvoid],("",JUSTBASE,[],Convert_env.get_loc env) ] - | _ -> List.map (convert_anonymous_decl env does_remove_virtual) l + env, [ [SpecType Tvoid],("",JUSTBASE,[],Convert_env.get_loc env) ] + | _ -> + let do_one env d = convert_anonymous_decl env does_remove_virtual d in + Convert_env.env_map do_one env l and convert_specifiers env t does_remove_virtual = let spec = List.map convert_cv t.qualifier in convert_base_type env spec (fun d -> d) t.plain_type does_remove_virtual and convert_anonymous_decl env does_remove_virtual t = - let typ, decl = convert_specifiers env t does_remove_virtual in - (typ, ("",decl JUSTBASE,[],Cil_datatype.Location.unknown)) + let env, (typ, decl) = convert_specifiers env t does_remove_virtual in + env, (typ, ("",decl JUSTBASE,[],Cil_datatype.Location.unknown)) and convert_decl env does_remove_virtual arg = - let typ,decl = convert_specifiers env arg.arg_type does_remove_virtual in + let env, (typ,decl) = + convert_specifiers env arg.arg_type does_remove_virtual + in + env, (typ, (arg.arg_name, decl JUSTBASE, [], Cil_datatype.Location.of_lexing_loc arg.arg_loc)) and make_prototype loc env name kind rt args variadic does_remove_virtual = - let rt, decl = convert_specifiers env rt does_remove_virtual in - let args = + let env, (rt, decl) = convert_specifiers env rt does_remove_virtual in + let env, args = match args with | [] -> (* empty list in C++ always mean void, not unspecified *) - [[SpecType Tvoid],("",JUSTBASE,[],loc)] - | _ -> List.map (convert_decl env does_remove_virtual) args + env, [[SpecType Tvoid],("",JUSTBASE,[],loc)] + | _ -> + let do_one env arg = convert_decl env does_remove_virtual arg in + Convert_env.env_map do_one env args in let args = match kind, args with @@ -791,8 +780,8 @@ and make_prototype loc env name kind rt args variadic does_remove_virtual = env, (rt, (name,decl (PROTO(JUSTBASE,args,[],variadic)),[],loc)) and convert_constant env c does_remove_virtual = match c with - | IntCst (kind,_,v) -> mk_int64_cst_n env ~kind v - | FloatCst(_,v) -> CONSTANT(CONST_FLOAT v) + | IntCst (kind,_,v) -> env, mk_int64_cst_n env ~kind v + | FloatCst(_,v) -> env, CONSTANT(CONST_FLOAT v) | EnumCst(n,e,_) -> let n, t = Convert_env.typedef_normalize env n TStandard in let name = @@ -807,34 +796,35 @@ and convert_constant env c does_remove_virtual = match c with This is not an issue for most purposes, except when it comes to handle exceptions: catching enum e is not the same as catching int x. *) + env, mk_cast_n ([SpecType (Tenum (enum,None,[]))], JUSTBASE) (mk_var env name) | TypeCst (TCCSizeOf, t) -> - let bt,decl = convert_base_type env [] id t does_remove_virtual in - TYPE_SIZEOF (bt,decl JUSTBASE) + let env, (bt,decl) = convert_base_type env [] id t does_remove_virtual in + env, TYPE_SIZEOF (bt,decl JUSTBASE) | TypeCst (TCCAlignOf, t) -> - let bt,decl = convert_base_type env [] id t does_remove_virtual in - TYPE_ALIGNOF (bt,decl JUSTBASE) + let env, (bt,decl) = convert_base_type env [] id t does_remove_virtual in + env, TYPE_ALIGNOF (bt,decl JUSTBASE) and convert_unary env kind arg does_remove_virtual = match kind with (* Not a real cast, merely a compilation's artifact *) - | UOCastNoEffect _ -> arg.expr_node + | UOCastNoEffect _ -> env, arg.expr_node (* Marks initialization of a ref field. treated elsewhere. *) - | UOCastDerefInit -> arg.expr_node + | UOCastDerefInit -> env, arg.expr_node (* Use the actual rvalue of a reference. *) - | UOCastDeref -> UNARY(MEMOF,arg) - | UOCastToVoid -> mk_cast_n ([SpecType Tvoid], JUSTBASE) arg + | UOCastDeref -> env, UNARY(MEMOF,arg) + | UOCastToVoid -> env, mk_cast_n ([SpecType Tvoid], JUSTBASE) arg | UOCastInteger(t,_) | UOCastEnum(t,_) | UOCastFloat(t,_) | UOCastC t -> - let rt, decl = convert_specifiers env t does_remove_virtual in - mk_cast_n (rt, decl JUSTBASE) arg - | UOPostInc -> UNARY(POSINCR,arg) - | UOPostDec -> UNARY(POSDECR,arg) - | UOPreInc -> UNARY(PREINCR,arg) - | UOPreDec -> UNARY(PREDECR,arg) - | UOOpposite -> UNARY(MINUS,arg) - | UOBitNegate -> UNARY(BNOT,arg) - | UOLogicalNegate -> UNARY(NOT,arg) + let env, (rt, decl) = convert_specifiers env t does_remove_virtual in + env, mk_cast_n (rt, decl JUSTBASE) arg + | UOPostInc -> env, UNARY(POSINCR,arg) + | UOPostDec -> env, UNARY(POSDECR,arg) + | UOPreInc -> env, UNARY(PREINCR,arg) + | UOPreDec -> env, UNARY(PREDECR,arg) + | UOOpposite -> env, UNARY(MINUS,arg) + | UOBitNegate -> env, UNARY(BNOT,arg) + | UOLogicalNegate -> env, UNARY(NOT,arg) (* drop_temp is true when the resulting value is not considered further, i.e. the expression is evaluated only for its side effect. In this setting, @@ -861,9 +851,7 @@ and convert_expr_node ?(drop_temp=false) env aux e does_remove_virtual = Cxx_utils.( plain_obj_ptr (unqual_type (Struct (derived_name,td)))) in - let derived_name, td = - Convert_env.typedef_normalize env derived_name td - in + let name = convert_class_name env derived_name td in let init = if not is_reference then e else mk_expr env (UNARY(ADDROF, e)) in @@ -871,9 +859,7 @@ and convert_expr_node ?(drop_temp=false) env aux e does_remove_virtual = add_local_aux_def aux (DECDEF( None, - ([SpecType - (Tstruct - (Mangling.mangle derived_name td None, None, []))], + ([SpecType (Tstruct (name,None,[]))], [(var_name, PTR([], JUSTBASE),[], e.expr_loc), SINGLE_INIT(init)]), e.expr_loc)) in @@ -884,19 +870,14 @@ and convert_expr_node ?(drop_temp=false) env aux e does_remove_virtual = if (noeffect) then access, aux, env else begin let table_access = virtual_var_name () in - let qual_vmt_content_name = Cxx_utils.empty_qual "_frama_c_vmt_content" in let env = Convert_env.add_local_var env table_access Cxx_utils.( plain_obj_ptr ( unqual_type (Struct (qual_vmt_content_name, TStandard)))) in - let qual_vmt_content_name, _ = - Convert_env.typedef_normalize env qual_vmt_content_name TStandard - in let tmp_decl = DECDEF( None, - ([SpecType (Tstruct (Mangling.mangle - qual_vmt_content_name TStandard None, None, []))], + ([SpecType (mk_vmt_content_type env)], [(table_access,PTR( [], JUSTBASE),[],access.expr_loc), SINGLE_INIT (access)]), access.expr_loc) @@ -924,17 +905,21 @@ and convert_expr_node ?(drop_temp=false) env aux e does_remove_virtual = let env, aux, node = match e with | Constant c -> - let e = convert_constant env c does_remove_virtual in env, aux, e + let env, e = convert_constant env c does_remove_virtual in env, aux, e | String s -> env, aux, CONSTANT (CONST_STRING s) | Variable v -> env, aux, convert_variable env v | Malloc(t) -> - let bt,decl = convert_base_type env [] id t does_remove_virtual in + let env, (bt,decl) = + convert_base_type env [] id t does_remove_virtual + in env, aux, CALL(mk_expr env (VARIABLE "malloc"), [mk_expr env (TYPE_SIZEOF (bt,decl JUSTBASE))],[]) | MallocArray(t,s) -> - let bt,decl = convert_base_type env [] id t does_remove_virtual in + let env, (bt,decl) = + convert_base_type env [] id t does_remove_virtual + in let env, aux, size = convert_expr env aux s does_remove_virtual in env, aux, @@ -970,7 +955,7 @@ and convert_expr_node ?(drop_temp=false) env aux e does_remove_virtual = env, aux, BINARY(ASSIGN,lv,rv) | Unary_operator(k,e) -> let env, aux, e = convert_expr env aux e does_remove_virtual in - let e = convert_unary env k e does_remove_virtual in + let env, e = convert_unary env k e does_remove_virtual in env, aux, e | Binary_operator(k,a,e1,e2) -> let env, aux, e1 = convert_expr env aux e1 does_remove_virtual in @@ -984,7 +969,9 @@ and convert_expr_node ?(drop_temp=false) env aux e does_remove_virtual = env, aux, (make_addrof e).expr_node | PointerCast(target,base,e) -> let env, aux, e = convert_expr env aux e does_remove_virtual in - let rt, decl = convert_specifiers env target does_remove_virtual in + let env, (rt, decl) = + convert_specifiers env target does_remove_virtual + in (match base with | RPKPointer -> env, aux, mk_cast_n (rt,decl JUSTBASE) e @@ -1024,10 +1011,11 @@ and convert_expr_node ?(drop_temp=false) env aux e does_remove_virtual = env (rt,decl JUSTBASE) (mk_addrof env (mk_expr env (MEMBEROF(e, cname))))) | RPKVirtualBasePointer(base_index, origin_type, noeffect) -> - let derived_name, td = + let derived_name,td = Convert_env.get_class_name_from_pointer env origin_type.plain_type in + let cderived_name= convert_class_name env derived_name td in let var_name = shift_ptr_var_name () in let env = Convert_env.add_local_var @@ -1038,26 +1026,16 @@ and convert_expr_node ?(drop_temp=false) env aux e does_remove_virtual = let def = DECDEF( None, - ([SpecType - (Tstruct - (Mangling.mangle derived_name td None, None, []))], + ([SpecType (Tstruct (cderived_name,None,[]))], [(var_name, PTR([], JUSTBASE),[], e.expr_loc), SINGLE_INIT(e)]), e.expr_loc) in let aux = add_local_aux_def aux def in - let qual_vmt_name = Cxx_utils.empty_qual "_frama_c_vmt" in let this_access, aux, env = create_this_access e origin_type aux env false noeffect in - let qual_vmt_name, _ = - Convert_env.typedef_normalize env qual_vmt_name TStandard - in let vmt_type = - [SpecType - (Tstruct - (Mangling.mangle qual_vmt_name - TStandard None, None, []))], - PTR ([], PTR ([], JUSTBASE)) + [SpecType (mk_vmt_type env)], PTR ([], PTR ([], JUSTBASE)) in let table_access_def = mk_expr env @@ -1093,16 +1071,8 @@ and convert_expr_node ?(drop_temp=false) env aux e does_remove_virtual = create_this_access e origin_type aux env true (* is_reference *) false (* noeffect *) in - let qual_vmt_name = Cxx_utils.empty_qual "_frama_c_vmt" in - let qual_vmt_name,_ = - Convert_env.typedef_normalize env qual_vmt_name TStandard - in let vmt_type = - [SpecType - (Tstruct - (Mangling.mangle - qual_vmt_name TStandard None, None, []))], - PTR ([], PTR ([], JUSTBASE)) + [SpecType (mk_vmt_type env)], PTR ([], PTR ([], JUSTBASE)) in let table_access_def = mk_expr env @@ -1229,7 +1199,9 @@ and convert_expr_node ?(drop_temp=false) env aux e does_remove_virtual = expr_node = UNARY(ADDROF,e)}))})) | ShiftPointerCast(target,base,kind,e) -> let env, aux, e = convert_expr env aux e does_remove_virtual in - let rt, decl = convert_specifiers env target does_remove_virtual in + let env, (rt, decl) = + convert_specifiers env target does_remove_virtual + in let derived_aux e derived_name td base_name tb = let var_name = shift_ptr_var_name () in let env = @@ -1390,7 +1362,6 @@ and convert_expr_node ?(drop_temp=false) env aux e does_remove_virtual = let qual_vmt_content_name = Cxx_utils.empty_qual "_frama_c_vmt_content" in - let qual_vmt_name = Cxx_utils.empty_qual "_frama_c_vmt" in let env = Convert_env.add_local_var env var_name @@ -1417,24 +1388,8 @@ and convert_expr_node ?(drop_temp=false) env aux e does_remove_virtual = ([SpecType Tchar], PTR ([], JUSTBASE)) (List.fold_left shift_expr this shiftPvmt)) in - let qual_vmt_content_name, _ = - Convert_env.typedef_normalize env qual_vmt_content_name TStandard - in - let qual_vmt_name, _ = - Convert_env.typedef_normalize env qual_vmt_name TStandard - in - let vmt_content_base_type = - [SpecType - (Tstruct - (Mangling.mangle qual_vmt_content_name TStandard None, - None, []))] - in - let vmt_base_type = - [SpecType - (Tstruct - (Mangling.mangle qual_vmt_name TStandard None, - None, []))] - in + let vmt_content_base_type = [SpecType (mk_vmt_content_type env)] in + let vmt_base_type = [SpecType (mk_vmt_type env)] in let vmt_access = mk_expr env (UNARY @@ -1459,13 +1414,13 @@ and convert_expr_node ?(drop_temp=false) env aux e does_remove_virtual = Convert_env.class_type_from_qualifications env name.prequalification in - let proto_args = + let env, proto_args = convert_signature env (Cxx_utils.(obj_ptr (unqual_type class_type))::signature.parameter) does_remove_virtual in - let proto_rt, proto_rt_decl = + let env, (proto_rt, proto_rt_decl) = convert_specifiers env signature.result does_remove_virtual in let proto_spec = List.map convert_cv signature.result.qualifier in @@ -1486,6 +1441,7 @@ and convert_expr_node ?(drop_temp=false) env aux e does_remove_virtual = let class_name, tc = Convert_env.typedef_normalize env class_name tc in + let cclass_name = convert_class_name env class_name tc in env, add_local_aux_def aux tmp_decl, CALL( mk_expr env @@ -1501,9 +1457,7 @@ and convert_expr_node ?(drop_temp=false) env aux e does_remove_virtual = env (MEMBEROFPTR (mk_var env var_name, "method_ptr"))))), (mk_cast env - ([SpecType - (Tstruct - (Mangling.mangle class_name tc None, None, []))], + ([SpecType (Tstruct (cclass_name, None, []))], PTR ([], JUSTBASE)) (mk_expr env (BINARY @@ -1530,7 +1484,9 @@ and convert_expr_node ?(drop_temp=false) env aux e does_remove_virtual = env, aux, CALL(f,args,[]) | Temporary(name, ctyp, init_exp, force) -> let env = Convert_env.add_local_var env name ctyp.plain_type in - let typ, decl = convert_specifiers env ctyp does_remove_virtual in + let env, (typ, decl) = + convert_specifiers env ctyp does_remove_virtual + in let attrs = add_fc_destructor_attr env ctyp [] in let res = if drop_temp then NOTHING else VARIABLE name in let is_const = Cxx_utils.is_const_type ctyp in @@ -1600,7 +1556,7 @@ and convert_expr_node ?(drop_temp=false) env aux e does_remove_virtual = env, add_local_aux_def aux tmp_decl, res) | VAArg(e,t) -> let env, aux', e = convert_expr env aux e does_remove_virtual in - let typ, decl = convert_specifiers env t does_remove_virtual in + let env, (typ, decl) = convert_specifiers env t does_remove_virtual in (* implement the ugly comment in cabs.ml *) let builtin = mk_expr env (VARIABLE "__builtin_va_arg") in let typ_expr = mk_expr env (TYPE_SIZEOF (typ, decl JUSTBASE)) in @@ -1636,7 +1592,9 @@ and convert_expr_node ?(drop_temp=false) env aux e does_remove_virtual = let subtype = Cxx_utils.const_qual_type elt_typ in let array_type = Array { subtype; dimension } in let qarray_type = Cxx_utils.unqual_type array_type in - let carr_type, carr_decl = convert_specifiers env qarray_type false in + let env, (carr_type, carr_decl) = + convert_specifiers env qarray_type false + in let array_name = Convert_env.temp_name env "init_array" in let old_env = env in let env = Convert_env.add_local_var env array_name array_type in @@ -1693,7 +1651,7 @@ and convert_expr_node ?(drop_temp=false) env aux e does_remove_virtual = (CONSTANT (CONST_INT (string_of_int il_size))) ],[])),loc)) in - let cil_type, cil_decl = + let env, (cil_type, cil_decl) = convert_specifiers env (Cxx_utils.unqual_type il_type) false in let il_dec = @@ -1743,19 +1701,22 @@ and create_lambda env aux lam_name lam_type overloads closures = (* Create the definition of the struct that represents the lambda *) let define_struct env name = let loc = Convert_env.get_loc env in - let field_of_capture cap = + let field_of_capture env cap = let s, t = capture_name_type env cap in - let rt, decl = convert_specifiers env t false in - FIELD (rt, [ (s, decl JUSTBASE, [], loc), None ]) + let env, (rt, decl) = convert_specifiers env t false in + env, FIELD (rt, [ (s, decl JUSTBASE, [], loc), None ]) in - let field_of_functions ovl = + let field_of_functions env ovl = let fptr = mk_lambda_fptr_type lam_type ovl in let name = lambda_unique_overload_name ovl.id in - let rt, decl = convert_specifiers env fptr false in - FIELD (rt, [(name, decl JUSTBASE, [], loc), None]) + let env, (rt, decl) = convert_specifiers env fptr false in + env, FIELD (rt, [(name, decl JUSTBASE, [], loc), None]) in - let cap_fields = List.map field_of_capture closures in - let fptr_fields = List.map field_of_functions overloads in + let env,cap_fields = Convert_env.env_map field_of_capture env closures in + let env,fptr_fields = + Convert_env.env_map field_of_functions env overloads + in + env, ONLYTYPEDEF ( [SpecType (Tstruct(name, Some (fptr_fields @ cap_fields),[]))],loc) in @@ -1796,7 +1757,7 @@ and create_lambda env aux lam_name lam_type overloads closures = in let struct_name = Mangling.mangle_cc_type lam_type in - let struct_def = define_struct env struct_name in + let env, struct_def = define_struct env struct_name in let env = Convert_env.add_c_global env struct_def in let struct_inst = instantiate_struct env struct_name in let aux = add_local_aux_def aux struct_inst in @@ -2116,7 +2077,7 @@ and convert_initializer env typ var init_exp does_remove_virtual = | _, None -> env, aux, (what,def)::acc | Single_init e, Some _ -> incr init_var_counter; - let spec, decl = convert_specifiers env ty does_remove_virtual in + let env, (spec, decl) = convert_specifiers env ty does_remove_virtual in let attrs = add_fc_destructor_attr env ty [] in let cloc = Cil_datatype.Location.of_lexing_loc e.eloc in let decl = @@ -2149,7 +2110,9 @@ and convert_init_statement env init does_remove_virtual = let env, aux, l, def, base = List.fold_right (fun {id_name; init_type=typ; init_val} (env,aux,l,def, base) -> - let base', decl = convert_specifiers env typ does_remove_virtual in + let env, (base', decl) = + convert_specifiers env typ does_remove_virtual + in let base = match base with | None -> Some base' @@ -2163,21 +2126,21 @@ and convert_init_statement env init does_remove_virtual = let env = Convert_env.add_local_var env id_name typ.plain_type in match init_val with | None -> - let init = (id_name, decl JUSTBASE,[],loc),NO_INIT in - (env, aux, init::l, def, base) + let init = (id_name, decl JUSTBASE,[],loc),NO_INIT in + (env, aux, init::l, def, base) | Some init -> let var = Local { prequalification = []; decl_name = id_name } in let env,aux',init, def' = convert_initializer env typ var init does_remove_virtual in - let def = match def' with - | None -> def - | Some stmt -> stmt::def - in - let init = (id_name, decl JUSTBASE,attrs,loc),init in - env, merge_aux aux' aux, init::l, def, base) - init_declarator_list - (env, empty_aux, [], [], None) + let def = match def' with + | None -> def + | Some stmt -> stmt::def + in + let init = (id_name, decl JUSTBASE,attrs,loc),init in + env, merge_aux aux' aux, init::l, def, base) + init_declarator_list + (env, empty_aux, [], [], None) in let l = List.rev l in if l = [] then @@ -2201,7 +2164,7 @@ and convert_condition env cond does_remove_virtual = | CondVarDecl(name, typ, init) -> let attrs = add_fc_destructor_attr env typ [] in let env = Convert_env.add_local_var env name typ.plain_type in - let base, decl = convert_specifiers env typ does_remove_virtual in + let env, (base, decl) = convert_specifiers env typ does_remove_virtual in let res = { expr_loc = loc; expr_node = VARIABLE name } in let var = Local { prequalification = []; decl_name = name } in let env, aux, init, e = @@ -2264,7 +2227,7 @@ and convert_statement env st does_remove_virtual = | Code_annot (l,annot) -> let env = Convert_env.set_loc env l in let cloc = Convert_env.get_loc env in - let c_annot = Convert_acsl.convert_code_annot env annot in + let env, c_annot = Convert_acsl.convert_code_annot env annot in CODE_ANNOT(c_annot,cloc), env | Return (l,Some e) -> let e = add_temporary (* env *) e in @@ -2340,7 +2303,7 @@ and convert_statement env st does_remove_virtual = | VarDecl (loc, name, typ, init) -> let env = Convert_env.set_loc env loc in let cloc = Cil_datatype.Location.of_lexing_loc loc in - let base, decl = convert_specifiers env typ does_remove_virtual in + let env, (base, decl) = convert_specifiers env typ does_remove_virtual in let qual_name = { prequalification = []; decl_name = name } in let attrs = add_fc_destructor_attr env typ [] in let env = @@ -2392,7 +2355,9 @@ and convert_statement env st does_remove_virtual = let env, aux, cond = convert_full_expr env cond does_remove_virtual in let body,env = convert_statement env body does_remove_virtual in let body = add_temps_update aux body in - let annot = List.map (Convert_acsl.convert_code_annot env) annot in + let env, annot = + Convert_env.env_map Convert_acsl.convert_code_annot env annot + in add_temps aux (WHILE(annot,cond,body,cloc)), env | DoWhile (loc, cond, body,annot) -> let env = Convert_env.set_loc env loc in @@ -2400,7 +2365,9 @@ and convert_statement env st does_remove_virtual = let env, aux, cond = convert_full_expr env cond does_remove_virtual in let body, env = convert_statement env body does_remove_virtual in let body = add_temps_update aux body in - let annot = List.map (Convert_acsl.convert_code_annot env) annot in + let env, annot = + Convert_env.env_map Convert_acsl.convert_code_annot env annot + in add_temps aux (DOWHILE(annot, cond, body, cloc)), env | For(loc, init, cond, incr, body,annot) -> let env = Convert_env.set_loc env loc in @@ -2415,7 +2382,9 @@ and convert_statement env st does_remove_virtual = let ienv, incr = convert_incr_statement ienv incr does_remove_virtual in - let annot = List.map (Convert_acsl.convert_code_annot ienv) annot in + let ienv, annot = + Convert_env.env_map Convert_acsl.convert_code_annot ienv annot + in let body, ienv = convert_statement ienv body does_remove_virtual in let body = add_temps_update aux body in let loop = FOR(annot,init,cond,incr,body,cloc) in @@ -2467,7 +2436,7 @@ and convert_catch_clause does_remove_virtual (acc,env) { typed_arg; cbody } = | None -> None, env | Some v -> let qtype = Convert_env.qual_type_normalize env v.arg_type in - let decl = convert_decl env does_remove_virtual v in + let env, decl = convert_decl env does_remove_virtual v in Some decl, Convert_env.add_local_var env v.arg_name qtype.plain_type in @@ -2482,7 +2451,7 @@ and convert_case_statement does_remove_virtual (acc, env) case = | Case(value,action) -> let loc = find_loc_list_stmt action in let cloc = Cil_datatype.Location.of_lexing_loc loc in - let value = convert_constant env value does_remove_virtual in + let env, value = convert_constant env value does_remove_virtual in let value = mk_expr_l cloc value in let action, env = convert_stmt_block env action does_remove_virtual @@ -2552,7 +2521,7 @@ let convert_static_const env loc name ikind kind value does_remove_virtual = Mangling.mangle qualified_name t None in let plain = Int ikind in - let spec, _ = + let env, (spec, _) = convert_base_type env [SpecCV CV_CONST] id plain does_remove_virtual in let spec = @@ -2598,7 +2567,7 @@ let bare_or_derived_type env most_derived n = let make_class_decl env name tkind kind inherits fields body has_virtual = let n, t = Convert_env.typedef_normalize env name tkind in - let class_name = Mangling.mangle n t None in + let class_name = convert_class_name env name tkind in let loc = Convert_env.get_loc env in let create_class_type base tb = { qualifier = []; plain_type = (Struct (base,tb)) } @@ -2637,14 +2606,11 @@ let make_class_decl env name tkind kind inherits fields body has_virtual = let n, t = Convert_env.typedef_normalize env base tb in let n' = if Class.has_virtual_base_class (base,tb) then bare_qname n else n - in (FIELD - ([SpecType - (Tstruct - (Mangling.mangle n' t None, - None, []))], - [(create_base_field_name env n t, - JUSTBASE, [], loc), - None]), + in + let cname = convert_class_name env n' t in + (FIELD + ([SpecType (Tstruct (cname, None, []))], + [(create_base_field_name env n t, JUSTBASE, [], loc), None]), (create_class_type base tb)) ::result) [] virtual_base_classes @@ -2673,14 +2639,11 @@ let make_class_decl env name tkind kind inherits fields body has_virtual = then bare_qname n else n in + let cname = convert_class_name env n' t in has_virtual, (FIELD - ([SpecType - (Tstruct - (Mangling.mangle n' t None, - None, []))], - [(create_base_field_name env n t, - JUSTBASE, [], loc), + ([SpecType (Tstruct (cname, None, []))], + [(create_base_field_name env n t, JUSTBASE, [], loc), None]), (create_class_type inherits.base inherits.templated_kind)) @@ -2714,7 +2677,7 @@ let make_class_decl env name tkind kind inherits fields body has_virtual = (List.fold_left create_field ([],[]) (List.append fields inherited_fields)) in - let bare = bare_qname name in + let bare = bare_qname n in let env = Convert_env.add_aggregate env bare CClass tkind false in Some bcfields, Convert_env.add_struct env (bare,tkind) bfields_typ @@ -2730,7 +2693,8 @@ let make_class_decl env name tkind kind inherits fields body has_virtual = match bare_fields, kind with | None, _ | Some _, CUnion -> None | Some fields, (CClass | CStruct) -> - Some (Tstruct (Mangling.mangle (bare_qname n) t None, Some fields,[])) + let bare_name = convert_class_name new_env (bare_qname n) t in + Some (Tstruct (bare_name, Some fields,[])) in let bare_class_decl = match bare_type_decl with | None -> None @@ -2844,7 +2808,7 @@ let create_stmt_set_vmt env qualification_class inherits = Cxx_utils. (obj_ptr (class_ptr (Cxx_utils.empty_qual "_frama_c_vmt", TStandard))) in - let rt, decl = convert_specifiers env vmt_type true in + let env, (rt, decl) = convert_specifiers env vmt_type true in let cvmt_type = rt, decl JUSTBASE in let create_stmt_set_shift_vmt (l, previous_index) { base = base_class_name; @@ -3080,9 +3044,13 @@ and create_generic_op op env most_derived class_name = | _ :: _ :: _ -> Frama_Clang_option.fatal "unexpected signature for implicit operator" in - let bt1,dt1 = convert_specifiers env bare_this_ptr (not most_derived) in + let env, (bt1,dt1) = + convert_specifiers env bare_this_ptr (not most_derived) + in let t1 = bt1, dt1 JUSTBASE in - let bt2,dt2 = convert_specifiers env bare_prm (not most_derived) in + let env, (bt2,dt2) = + convert_specifiers env bare_prm (not most_derived) + in let t2 = bt2, dt2 JUSTBASE in let mk_cast t e = mk_expr env (CAST (t, SINGLE_INIT e)) in let mk_mem e = mk_expr env (UNARY(MEMOF,e)) in @@ -3522,8 +3490,9 @@ let add_arg_names l = l)) let convert_contract env spec = - Convert_acsl.convert_function_contract env spec, - Convert_env.get_loc env + let loc = Convert_env.get_loc env in + let env, spec = Convert_acsl.convert_function_contract env spec in + env, (spec, loc) let constify_receiver kind args = match kind, args with @@ -3568,7 +3537,7 @@ and convert_class_component (env, implicits, types, fields, others) meth = let signature = {result= return_type; parameter= args_sig; variadic } in let signature = Convert_env.signature_normalize env signature in let name = Mangling.mangle qname tkind (Some(kind,signature)) in - let spec = Option.map (convert_contract benv) spec in + let benv, spec = Convert_env.env_opt convert_contract benv spec in let extern_c = false in let spec = if has_further_definition @@ -3625,9 +3594,10 @@ and convert_class_component (env, implicits, types, fields, others) meth = :: others)) | CCompound(loc,name,kind,inherits,body,tkind,has_virtual) -> let new_env = Convert_env.set_loc env loc in + let is_extern_c = Convert_env.is_extern_c env in let qualified_name = Convert_env.qualify new_env name in let new_env = - make_class_env new_env (Declaration name) kind tkind false + make_class_env new_env (Declaration name) kind tkind is_extern_c in let new_env,new_implicits,subtypes,subfields,subothers = match body with @@ -3666,7 +3636,7 @@ and convert_class_component (env, implicits, types, fields, others) meth = | CFieldDecl(loc, name, typ, bf_info, is_mutable) -> let env = Convert_env.set_loc env loc in let cloc = Cil_datatype.Location.of_lexing_loc loc in - let base,decl = convert_specifiers env typ false in + let env, (base,decl) = convert_specifiers env typ false in (* We remove static qualifier to avoid confusion with the C's static. *) let base = List.filter (function SpecStorage(STATIC)-> false | _ -> true) base @@ -3707,7 +3677,7 @@ and convert_class_component (env, implicits, types, fields, others) meth = let env = Convert_env.add_typedef env qual_name typ in let name,_= Convert_env.typedef_normalize env qual_name TStandard in let name = Mangling.mangle name TStandard None in - let base,decl = convert_specifiers env typ false in + let env, (base,decl) = convert_specifiers env typ false in (env,implicits, TYPEDEF((SpecTypedef::base,[(name,decl JUSTBASE,[],cloc)]),cloc) ::types, @@ -3734,12 +3704,13 @@ and convert_class_component (env, implicits, types, fields, others) meth = fields, others) | Class_annot(loc,annot) -> let env = Convert_env.set_loc env loc in - let annot = Convert_acsl.convert_annot env annot in + let env, annot = Convert_acsl.convert_annot env annot in (env,implicits,types,fields,GLOBANNOT [annot]:: others) and convert_class env name tkind kind inherits body has_virtual = let qualified_name = make_qualified_name env name in - let this_env = make_class_env env name kind tkind false in + let is_extern_c = Convert_env.is_extern_c env in + let this_env = make_class_env env name kind tkind is_extern_c in let new_env, implicits, types, fields, others = match body with | None -> this_env, [], [], [], [] @@ -3771,60 +3742,6 @@ and convert_class env name tkind kind inherits body has_virtual = List.fold_right add_glob my_implicits |> Convert_env.reset_current_class -let rec convert_pod_field (cfields, typs, env) field = - match field with - | CFieldDecl(loc, name, typ, bf_info,is_mutable) -> - let env = Convert_env.set_loc env loc in - let cloc = Cil_datatype.Location.of_lexing_loc loc in - let base,decl = convert_specifiers env typ false in - let base = - if is_mutable then - SpecAttr (add_attr env Cil.frama_c_mutable []) :: base - else base - in - let bf_length = Option.map (convert_bitfield_info env) bf_info in - FIELD(base, [(name,decl JUSTBASE,[],cloc),bf_length])::cfields, - (name, typ) :: typs, env - | CCompound(_, name, kind, _, body, tn, _) -> - let dname = Declaration name in - let env = convert_pod env dname kind tn body in - cfields, typs, env - | _ -> - Convert_env.fatal env "Unknown declaration in extern C structure definition" - -and convert_pod env name kind tn body = - let loc = Convert_env.get_loc env in - let name = - match name with - | Declaration name -> name - | Implementation name -> name.decl_name - in - let env = - Convert_env.add_aggregate env (Cxx_utils.empty_qual name) kind tn true - in - let fields, env = - match body with - | None -> None, env - | Some body -> - let fields, typs, env = - List.fold_left convert_pod_field ([], [], env) body - in - Some (List.rev fields), - Convert_env.add_struct - env (Cxx_utils.empty_qual name,tn) (List.rev typs) - in - let type_decl = - match kind with - | CClass | CStruct -> Tstruct (name, fields, []) - | CUnion -> Tunion(name, fields,[]) - in - Convert_env.add_c_global - env (ONLYTYPEDEF ([SpecType type_decl], loc)) - -let convert_class env name tkind kind inherits body has_virtual = - if Convert_env.is_extern_c env then convert_pod env name kind tkind body - else convert_class env name tkind kind inherits body has_virtual - let make_global_cons_init env name init = let loc = Convert_env.get_loc env in FUNDEF(None,([SpecType Tvoid; SpecAttr("__constructor__",[])], @@ -3902,7 +3819,7 @@ let rec convert_global env glob = match glob with | GlobalAnnotation(loc,annot) -> let env = Convert_env.set_loc env loc in - let annot = Convert_acsl.convert_annot env annot in + let env, annot = Convert_acsl.convert_annot env annot in Convert_env.add_c_global env (GLOBANNOT [annot]) | Function (name, _, _, _, _, _, _, _, _, _, _, _, _) when do_not_translate name @@ -3938,7 +3855,7 @@ let rec convert_global env glob = let signature = Convert_env.signature_normalize env signature in Mangling.mangle qualified_name tkind (Some (kind, signature)) in - let spec = Option.map (convert_contract benv) spec in + let benv, spec = Convert_env.env_opt convert_contract benv spec in let implicit = false in let spec = if has_further_definition then spec @@ -4031,7 +3948,7 @@ let rec convert_global env glob = qualified_name TStandard in Mangling.mangle n' t' None in - let rt, decl = convert_specifiers env typ false in + let env, (rt, decl) = convert_specifiers env typ false in let attrs = add_fc_destructor_attr env typ [] in let env = Convert_env.add_global_var env qualified_name typ.plain_type in let old_ghost = Convert_env.is_ghost env in @@ -4102,7 +4019,7 @@ let rec convert_global env glob = qual_name TStandard in Mangling.mangle qual_name t None in - let base,decl = convert_specifiers env typ false in + let env, (base,decl) = convert_specifiers env typ false in let env = Convert_env.set_ghost env old_ghost in Convert_env.add_c_global env (TYPEDEF((SpecTypedef::base,[(name,decl JUSTBASE,[],cloc)]), cloc)) @@ -4150,7 +4067,7 @@ let convert_ast file = pos_lnum = 0; pos_bol = 0; pos_cnum = 0; } in let basic_loc = basic_pos, basic_pos in - let sizeof_t = spec_of_ikind Cil.theMachine.kindOfSizeOf in + let sizeof_t = Cxx_utils.spec_of_ikind Cil.theMachine.kindOfSizeOf in let res = (Datatype.Filepath.of_string file.filename, (false, diff --git a/convert_acsl.ml b/convert_acsl.ml index 1a64c514a73f256068b433286ebb7826b024c529..c844ea36fced5ac4309980ab1c283a9421f277ec 100644 --- a/convert_acsl.ml +++ b/convert_acsl.ml @@ -42,41 +42,58 @@ let convert_logic_label_opt = function | Some lab -> Some (convert_logic_label lab) | None -> None -let convert_ikind = function - | IBool -> Cil_types.IBool - | IChar_u -> Cil_types.IChar - | IChar_s -> Cil_types.IChar - | IUChar -> Cil_types.IUChar - | ISChar -> Cil_types.ISChar - | IChar16 -> Cil.intKindForSize 2 true - | IChar32 -> Cil.intKindForSize 4 true - | IWChar_u - | IWChar_s - | IWUChar - | IWSChar -> Cil.theMachine.Cil.wcharKind - | IChar -> Cil_types.IChar - | IWChar -> Cil.theMachine.Cil.wcharKind - | IShort -> Cil_types.IShort - | IUShort -> Cil_types.IUShort - | IInt -> Cil_types.IInt - | IUInt -> Cil_types.IUInt - | ILong -> Cil_types.ILong - | IULong -> Cil_types.IULong - | ILongLong -> Cil_types.ILongLong - | IULongLong -> Cil_types.IULongLong +let convert_ikind env = function + | IBool -> env, LTint Cil_types.IBool + | IChar_u | IChar_s | IChar -> env, LTint Cil_types.IChar + | IUChar -> env, LTint Cil_types.IUChar + | ISChar -> env, LTint Cil_types.ISChar + | IChar16 -> env, LTint (Cil.intKindForSize 2 true) + | IChar32 -> env, LTint (Cil.intKindForSize 4 true) + | IWChar_u | IWChar_s | IWChar -> + let env = Convert_env.memo_wchar env in + env, LTnamed ("wchar_t", []) + | IShort -> env, LTint Cil_types.IShort + | IUShort -> env, LTint Cil_types.IUShort + | IInt -> env, LTint Cil_types.IInt + | IUInt -> env, LTint Cil_types.IUInt + | ILong -> env, LTint Cil_types.ILong + | IULong -> env, LTint Cil_types.IULong + | ILongLong -> env, LTint Cil_types.ILongLong + | IULongLong -> env, LTint Cil_types.IULongLong let convert_fkind = function | FFloat -> Cil_types.FFloat | FDouble -> Cil_types.FDouble | FLongDouble -> Cil_types.FLongDouble +let int_to_char c = + let open Int64 in + let char_max = of_int 256 in + let mk_char c = + Char.unsafe_chr (Option.get (unsigned_to_int (unsigned_rem c char_max))) + in + let rec aux seq c = + let seq = Seq.cons (mk_char c) seq in + let c = unsigned_div c char_max in + if equal c zero then String.of_seq seq else aux seq c + in + (* NB: intermediate_format uses int there, but, at least for wide chars, it's + better to stick with int64, that allows for unsigned operations. The whole + thing would probably need a complete overhaul, though. + *) + aux Seq.empty (Int64.of_int c) + +let convert_char c = "'" ^ int_to_char c ^ "'" + +let convert_wchar c = "L'" ^ int_to_char c ^ "'" + let convert_logic_constant = function | LCInt v -> IntConstant v | LStr s -> StringConstant s | LWStr _s -> Frama_Clang_option.not_yet_implemented "Wide string support in logic" - | LChr c -> IntConstant (string_of_int c) - | LWChr c -> IntConstant (string_of_int c) + | LChr c -> IntConstant (convert_char c) + | LWChr c -> IntConstant (convert_wchar c) | LCReal s -> FloatConstant s | LCEnum (v,_) -> IntConstant (Int64.to_string v) (* TODO: add support into ACSL for that? *) @@ -92,47 +109,47 @@ let convert_cst_array_size env = function Frama_Clang_option.fatal "Unexpected value as array dimension" let rec convert_logic_type env = function - | Lvoid -> LTvoid - | Lint ik -> LTint (convert_ikind ik) - | Lfloat fk -> LTfloat (convert_fkind fk) + | Lvoid -> env, LTvoid + | Lint ik -> convert_ikind env ik + | Lfloat fk -> env, LTfloat (convert_fkind fk) | Larray (t,dim) -> - let t = convert_logic_type env t in + let env, t = convert_logic_type env t in let dim = match dim with | Some dim -> convert_cst_array_size env dim | None -> ASnone in - LTarray(t,dim) + env, LTarray(t,dim) | Lpointer t | Lreference t -> - let t = convert_logic_type env t in - LTpointer t + let env, t = convert_logic_type env t in + env, LTpointer t | Lenum e -> let e, tk = Convert_env.typedef_normalize env e TStandard - in LTenum (Mangling.mangle e tk None) + in env, LTenum (Mangling.mangle e tk None) | Lstruct (s,t) -> let s,t = Convert_env.typedef_normalize env s t in let cname = if Convert_env.is_extern_c_aggregate env s t then s.decl_name else Mangling.mangle s t None in - LTstruct cname + env, LTstruct cname | Lunion (u,t) -> let u, t = Convert_env.typedef_normalize env u t in let cname = if Convert_env.is_extern_c_aggregate env u t then u.decl_name else Mangling.mangle u t None in - LTunion cname + env, LTunion cname | LCnamed (n,extern_c) -> let name = if extern_c then n.decl_name else (* change only the template parameters in the qualification *) let n, tk = Convert_env.typedef_normalize env n TStandard in Mangling.mangle n tk None in - LTnamed (name,[]) + env, LTnamed (name,[]) | Lnamed({ prequalification = [QNamespace "Utf8_logic"]; decl_name = "boolean"},_,[]) -> - LTnamed (Utf8_logic.boolean,[]) + env, LTnamed (Utf8_logic.boolean,[]) | Lnamed(t,extern_c,args) -> let name = if extern_c then t.decl_name @@ -140,17 +157,19 @@ let rec convert_logic_type env = function let t, tk = Convert_env.typedef_normalize env t TStandard in Mangling.mangle t tk None in - let args = List.map (convert_logic_type env) args in - LTnamed(name,args) - | Lvariable s -> LTnamed(s.decl_name,[]) - | Linteger -> LTinteger - | Lreal -> LTreal + let env, args = Convert_env.env_map convert_logic_type env args in + env, LTnamed(name,args) + | Lvariable s -> env, LTnamed(s.decl_name,[]) + | Linteger -> env, LTinteger + | Lreal -> env, LTreal | Larrow(args,rt) -> - let args = List.map (convert_logic_type env) args in - let rt = convert_logic_type env rt in - LTarrow(args, rt) + let env, args = Convert_env.env_map convert_logic_type env args in + let env, rt = convert_logic_type env rt in + env, LTarrow(args, rt) -let convert_logic_param env p = (convert_logic_type env p.la_type, p.la_name) +let convert_logic_param env p = + let env, typ = convert_logic_type env p.la_type in + env, (typ, p.la_name) type bkind = Relation | Logic | Arithmetic @@ -195,9 +214,9 @@ let convert_rel = function | Rneq -> Neq let convert_var_decl env v = - let typ = convert_logic_type env v.lv_type in + let env, typ = convert_logic_type env v.lv_type in let name = v.logic_var_def_lv_name.decl_name in - (typ, name) + env, (typ, name) let convert_reference env typ e = match typ with @@ -213,145 +232,177 @@ let convert_logic_reference env typ e = PLunop(Ustar, full_e) | _ -> e +(* ACSL parser normalizes conjunctions and disjunctions. We do the same here + in order to ensure syntactical equality of ACSL predicates + when parsed either directly or through framaCIRGen in an extern "C". *) +let rec pland ce1 ce2 = + match ce2.lexpr_node with + | PLand(ce3,ce4) -> + let lexpr_loc = fst ce1.lexpr_loc, snd ce3.lexpr_loc in + let lexpr_node = pland ce1 ce3 in + PLand ({ lexpr_loc; lexpr_node}, ce4) + | _ -> PLand (ce1, ce2) + +let rec plor ce1 ce2 = + match ce2.lexpr_node with + | PLor(ce3, ce4) -> + let lexpr_loc = fst ce1.lexpr_loc, snd ce3.lexpr_loc in + let lexpr_node = plor ce1 ce3 in + PLor ({ lexpr_loc; lexpr_node }, ce4) + | _ -> PLor (ce1, ce2) + let rec convert_logic_expr env e = let env = Convert_env.set_loc env e.loc in let lexpr_loc = Convert_env.get_loc env in - let anonymous = - { lexpr_loc; lexpr_node = convert_logic_expr_node env e.node } + let env, lexpr_node = convert_logic_expr_node env e.node in + let anonymous = { lexpr_loc; lexpr_node } in + let res = + List.fold_right + (fun s res -> { lexpr_loc; lexpr_node = PLnamed(s,res) }) + e.names anonymous in - List.fold_right - (fun s res -> { lexpr_loc; lexpr_node = PLnamed(s,res) }) - e.names anonymous + env, res and convert_logic_expr_node env = function - | TConst c -> PLconstant(convert_logic_constant c) + | TConst c -> env, PLconstant(convert_logic_constant c) | TLval lv -> convert_logic_lval env lv - | TSizeOf t -> PLsizeof(convert_logic_type env t) + | TSizeOf t -> + let env, typ = convert_logic_type env t in + env, PLsizeof typ | TSizeOfStr s -> let cs = { lexpr_loc = Convert_env.get_loc env; lexpr_node = PLconstant(StringConstant s) } in - PLsizeofE(cs) + env, PLsizeofE(cs) | TUnOp((UOPostInc|UOPostDec|UOPreInc|UOPreDec),_) -> Convert_env.fatal env "Side effect operation in ACSL++ expression" | TUnOp((UOCastNoEffect _ | UOCastDeref | UOCastToVoid | UOCastInteger _ | UOCastDerefInit | UOCastEnum _ | UOCastFloat _ | UOCastC _),_) -> Convert_env.fatal env "Logic casts are not supposed to use TUnOp but TCastE" - | TUnOp(UOOpposite,e) -> PLunop(Uminus,convert_logic_expr env e) - | TUnOp(UOBitNegate,e) -> PLunop(Ubw_not,convert_logic_expr env e) - | TUnOp(UOLogicalNegate,e) -> PLnot (convert_logic_expr env e) + | TUnOp(UOOpposite,e) -> + let env, e = convert_logic_expr env e in + env, PLunop(Uminus,e) + | TUnOp(UOBitNegate,e) -> + let env, e = convert_logic_expr env e in + env, PLunop(Ubw_not,e) + | TUnOp(UOLogicalNegate,e) -> + let env, e = convert_logic_expr env e in + env, PLnot e | TBinOp(bo,e1,e2) when bo_kind bo = Arithmetic -> let cbo = convert_bop_arith bo in - let ce1 = convert_logic_expr env e1 in - let ce2 = convert_logic_expr env e2 in - PLbinop(ce1,cbo,ce2) + let env, ce1 = convert_logic_expr env e1 in + let env, ce2 = convert_logic_expr env e2 in + env, PLbinop(ce1,cbo,ce2) | TBinOp(bo,e1,e2) when bo_kind bo = Relation -> let cbo = convert_bop_relation bo in - let ce1 = convert_logic_expr env e1 in - let ce2 = convert_logic_expr env e2 in - PLrel(ce1,cbo,ce2) + let env, ce1 = convert_logic_expr env e1 in + let env, ce2 = convert_logic_expr env e2 in + env, PLrel(ce1,cbo,ce2) | TBinOp(BOLogicalAnd,e1,e2) -> - let ce1 = convert_logic_expr env e1 in - let ce2 = convert_logic_expr env e2 in - PLand(ce1,ce2) + let env, ce1 = convert_logic_expr env e1 in + let env, ce2 = convert_logic_expr env e2 in + env, pland ce1 ce2 | TBinOp(BOLogicalOr,e1,e2) -> - let ce1 = convert_logic_expr env e1 in - let ce2 = convert_logic_expr env e2 in - PLor(ce1,ce2) + let env, ce1 = convert_logic_expr env e1 in + let env, ce2 = convert_logic_expr env e2 in + env, plor ce1 ce2 | TBinOp _ -> Convert_env.fatal env "Unknown binary operator in logic" | TCastE(typ,e) -> - let ctyp = convert_logic_type env typ in - let ce = convert_logic_expr env e in - PLcast(ctyp,ce) + let env, ctyp = convert_logic_type env typ in + let env, ce = convert_logic_expr env e in + env, PLcast(ctyp,ce) | TAddrOf lv | TStartOf lv -> - let e = convert_logic_lval env lv in + let env, e = convert_logic_lval env lv in (* simplify memory accesses introduced by handling of references *) (match e with - | PLunop(Ustar,t) -> t.lexpr_node + | PLunop(Ustar,t) -> env, t.lexpr_node | _ -> let e = { lexpr_node = e; lexpr_loc = Convert_env.get_loc env } in - PLunop(Uamp,e)) + env, PLunop(Uamp,e)) | TFieldAccess (e,(TField(f,TNoOffset)|TModel(f,TNoOffset))) -> - let ce = convert_logic_expr env e in PLdot(ce,f) + let env, ce = convert_logic_expr env e in env, PLdot(ce,f) | TFieldAccess _ -> Convert_env.fatal env "Unexpected offset in field access" - | TFalse -> PLfalse - | TTrue -> PLtrue + | TFalse -> env, PLfalse + | TTrue -> env, PLtrue | TApp(f,l,args,extern_c) -> (* TODO: if f is an extern C (or built-in), do not mangle it *) - let fname = if extern_c then f.decl_name + let fname = + if extern_c then f.decl_name else let f, t = Convert_env.typedef_normalize env f TStandard - in Mangling.mangle f t None in + in Mangling.mangle f t None + in let labels = List.map (fun l -> convert_logic_label l.snd) l in - let args = List.map (convert_logic_expr env) args in - PLapp(fname,labels,args) + let env, args = Convert_env.env_map convert_logic_expr env args in + env, PLapp(fname,labels,args) | TLambda (vars,t) -> - let quants = List.map (convert_var_decl env) vars in - let e = convert_logic_expr env t in - PLlambda(quants,e) + let env, quants = Convert_env.env_map convert_var_decl env vars in + let env, e = convert_logic_expr env t in + env, PLlambda(quants,e) | TDataCons(name,args) -> let name, t = Convert_env.typedef_normalize env name TStandard in let name = Mangling.mangle name t None in - let args = List.map (convert_logic_expr env) args in - PLapp(name,[],args) + let env, args = Convert_env.env_map convert_logic_expr env args in + env, PLapp(name,[],args) | TIf(cond,etrue,efalse) -> - let ccond = convert_logic_expr env cond in - let cetrue = convert_logic_expr env etrue in - let cefalse = convert_logic_expr env efalse in - PLif(ccond,cetrue,cefalse) + let env, ccond = convert_logic_expr env cond in + let env, cetrue = convert_logic_expr env etrue in + let env, cefalse = convert_logic_expr env efalse in + env, PLif(ccond,cetrue,cefalse) | TAt(t,l) -> - let t = convert_logic_expr env t in + let env, t = convert_logic_expr env t in let l = convert_logic_label l in - PLat(t,l) + env, PLat(t,l) | TBase_addr(l,t) -> let l = convert_logic_label_opt l in - let t = convert_logic_expr env t in - PLbase_addr(l,t) + let env, t = convert_logic_expr env t in + env, PLbase_addr(l,t) | TOffset(l,t) -> let l = convert_logic_label_opt l in - let t = convert_logic_expr env t in - PLoffset(l,t) + let env, t = convert_logic_expr env t in + env, PLoffset(l,t) | TBlock_length(l,t) -> let l = convert_logic_label_opt l in - let t = convert_logic_expr env t in - PLblock_length(l,t) - | TNull -> PLnull + let env, t = convert_logic_expr env t in + env, PLblock_length(l,t) + | TNull -> env, PLnull | TLogic_coerce(_,t) -> (* should be transparent at the parsed logic tree level. *) - (convert_logic_expr env t).lexpr_node + let env, e = convert_logic_expr env t in + env, e.lexpr_node | TUpdate(obj,off,t) -> - let obj = convert_logic_expr env obj in - let path = path_of_offset env off in - let value = convert_logic_expr env t in - PLupdate(obj,path,PLupdateTerm value) - | TEmpty_set -> PLempty + let env, obj = convert_logic_expr env obj in + let env, path = path_of_offset env off in + let env, value = convert_logic_expr env t in + env, PLupdate(obj,path,PLupdateTerm value) + | TEmpty_set -> env, PLempty | TUnion l -> - let l = List.map (convert_logic_expr env) l in - PLunion l + let env, l = Convert_env.env_map convert_logic_expr env l in + env, PLunion l | TInter l -> - let l = List.map (convert_logic_expr env) l in - PLinter l + let env, l = Convert_env.env_map convert_logic_expr env l in + env, PLinter l | TComprehension (t,quants,pred) -> - let quants = List.map (convert_var_decl env) quants in - let t = convert_logic_expr env t in - let pred = Option.map (convert_pred_named env) pred in - PLcomprehension (t,quants,pred) + let env, quants = Convert_env.env_map convert_var_decl env quants in + let env, t = convert_logic_expr env t in + let env, pred = Convert_env.env_opt convert_pred_named env pred in + env, PLcomprehension (t,quants,pred) | TRange(l,h) -> - let l = Option.map (convert_logic_expr env) l in - let h = Option.map (convert_logic_expr env) h in - PLrange(l,h) + let env, l = Convert_env.env_opt convert_logic_expr env l in + let env, h = Convert_env.env_opt convert_logic_expr env h in + env, PLrange(l,h) | TLet(info,t) -> - let body = convert_inner_body env info in + let env, body = convert_inner_body env info in let name = info.li_name.decl_name in - let rest = convert_logic_expr env t in - PLlet(name,body,rest) + let env, rest = convert_logic_expr env t in + env, PLlet(name,body,rest) | TCoerce _ | TCoerceE _ -> Frama_Clang_option.not_yet_implemented "coercions" and convert_logic_lval env lv = - let base = convert_logic_lhost env lv.base_support in + let env, base = convert_logic_lhost env lv.base_support in convert_logic_offset env base lv.offset and convert_logic_lhost env = function @@ -362,22 +413,22 @@ and convert_logic_lhost env = function Convert_env.get_global_var env v.logic_var_lv_name in let var = PLvar (convert_var env is_extern_c v) in - convert_reference env typ var + env, convert_reference env typ var | LVCLocal -> let var = PLvar v.logic_var_lv_name.decl_name in let typ = Convert_env.get_local_var env v.logic_var_lv_name.decl_name in - convert_reference env typ var + env, convert_reference env typ var | _ -> - PLvar v.logic_var_lv_name.decl_name + env, PLvar v.logic_var_lv_name.decl_name ) | TCFun(n,s) -> let n, t = Convert_env.typedef_normalize env n TStandard - in PLvar (Mangling.mangle n t (Some (FKFunction,s))) - | TResult typ -> convert_logic_reference env typ PLresult - | TMem t -> let t = convert_logic_expr env t in PLunop(Ustar,t) + in env, PLvar (Mangling.mangle n t (Some (FKFunction,s))) + | TResult typ -> env, convert_logic_reference env typ PLresult + | TMem t -> let env, t = convert_logic_expr env t in env, PLunop(Ustar,t) and convert_logic_offset env base = function - | TNoOffset -> base + | TNoOffset -> env, base | TField(s,o) | TModel(s,o) -> let e = { lexpr_loc = Convert_env.get_loc env; lexpr_node = base } in let base = PLdot(e,s) in @@ -397,144 +448,144 @@ and convert_logic_offset env base = function "casts to derived classes are not supported for the moment" | TIndex(t,o) -> let e = { lexpr_loc = Convert_env.get_loc env; lexpr_node = base } in - let i = convert_logic_expr env t in + let env, i = convert_logic_expr env t in let base = PLarrget(e,i) in convert_logic_offset env base o and path_of_offset env = function - | TNoOffset -> [] + | TNoOffset -> env, [] | TField(s,o) | TModel(s,o) -> - let path = path_of_offset env o in - PLpathField s :: path + let env, path = path_of_offset env o in + env, PLpathField s :: path | TBase(b,t,o) -> - let path = path_of_offset env o in + let env, path = path_of_offset env o in let b, t = Convert_env.typedef_normalize env b t in - PLpathField ("_frama_c_" ^ Mangling.mangle b t None) :: path + env, PLpathField ("_frama_c_" ^ Mangling.mangle b t None) :: path | TVirtualBase(b,t,o) -> - let path = path_of_offset env o in + let env, path = path_of_offset env o in let b, t = Convert_env.typedef_normalize env b t in - PLpathField ("_frama_c_" ^ Mangling.mangle b t None) :: path + env, PLpathField ("_frama_c_" ^ Mangling.mangle b t None) :: path | TDerived(_ (* d *),_ (* td *),_ (* b *),_ (* tb *),_ (* o *)) -> Convert_env.fatal env "casts to derived classes are not supported for the moment" | TIndex(t,o) -> - let i = convert_logic_expr env t in - let path = path_of_offset env o in - PLpathIndex(i) :: path + let env, i = convert_logic_expr env t in + let env, path = path_of_offset env o in + env, PLpathIndex(i) :: path and convert_pred_named env p = let env = Convert_env.set_loc env p.pred_loc in let pred_loc = Convert_env.get_loc env in - let cp = convert_pred env p.pred_content in + let env, cp = convert_pred env p.pred_content in let cp = List.fold_right (fun s acc -> PLnamed(s,{ lexpr_node = acc; lexpr_loc = pred_loc })) p.pred_name cp in - { lexpr_node = cp; lexpr_loc = pred_loc } + env, { lexpr_node = cp; lexpr_loc = pred_loc } and convert_pred env = function - | Pfalse -> PLfalse - | Ptrue -> PLtrue + | Pfalse -> env, PLfalse + | Ptrue -> env, PLtrue | PApp(p,labs,args,is_extern_c) -> let pname = if is_extern_c then p.decl_name else let p, t = Convert_env.typedef_normalize env p TStandard in Mangling.mangle p t None in let clabs = List.map (fun l -> convert_logic_label l.snd) labs in - let cargs = List.map (convert_logic_expr env) args in - PLapp(pname,clabs,cargs) + let env, cargs = Convert_env.env_map convert_logic_expr env args in + env, PLapp(pname,clabs,cargs) | Pseparated l -> - let l = List.map (convert_logic_expr env) l in - PLseparated l + let env, l = Convert_env.env_map convert_logic_expr env l in + env, PLseparated l | Prel(rel,t1,t2) -> let rel = convert_rel rel in - let t1 = convert_logic_expr env t1 in - let t2 = convert_logic_expr env t2 in - PLrel(t1,rel,t2) + let env, t1 = convert_logic_expr env t1 in + let env, t2 = convert_logic_expr env t2 in + env, PLrel(t1,rel,t2) | Pand(p1,p2) -> - let p1 = convert_pred_named env p1 in - let p2 = convert_pred_named env p2 in - PLand(p1,p2) + let env, p1 = convert_pred_named env p1 in + let env, p2 = convert_pred_named env p2 in + env, pland p1 p2 | Por(p1,p2) -> - let p1 = convert_pred_named env p1 in - let p2 = convert_pred_named env p2 in - PLor(p1,p2) + let env, p1 = convert_pred_named env p1 in + let env, p2 = convert_pred_named env p2 in + env, plor p1 p2 | Pxor(p1,p2) -> - let p1 = convert_pred_named env p1 in - let p2 = convert_pred_named env p2 in - PLxor(p1,p2) + let env, p1 = convert_pred_named env p1 in + let env, p2 = convert_pred_named env p2 in + env, PLxor(p1,p2) | Pimplies(p1,p2) -> - let p1 = convert_pred_named env p1 in - let p2 = convert_pred_named env p2 in - PLimplies(p1,p2) + let env, p1 = convert_pred_named env p1 in + let env, p2 = convert_pred_named env p2 in + env, PLimplies(p1,p2) | Piff(p1,p2) -> - let p1 = convert_pred_named env p1 in - let p2 = convert_pred_named env p2 in - PLiff(p1,p2) + let env, p1 = convert_pred_named env p1 in + let env, p2 = convert_pred_named env p2 in + env, PLiff(p1,p2) | Pnot p -> - let p = convert_pred_named env p in - PLnot p + let env, p = convert_pred_named env p in + env, PLnot p | Pif(cond,ptrue,pfalse) -> - let cond = convert_logic_expr env cond in - let ptrue = convert_pred_named env ptrue in - let pfalse = convert_pred_named env pfalse in - PLif(cond,ptrue,pfalse) + let env, cond = convert_logic_expr env cond in + let env, ptrue = convert_pred_named env ptrue in + let env, pfalse = convert_pred_named env pfalse in + env, PLif(cond,ptrue,pfalse) | Plet(li,p) -> - let body = convert_inner_body env li in - let p = convert_pred_named env p in - PLlet(li.li_name.decl_name,body,p) + let env, body = convert_inner_body env li in + let env, p = convert_pred_named env p in + env, PLlet(li.li_name.decl_name,body,p) | Pforall (x,p) -> - let quants = List.map (convert_var_decl env) x in - let p = convert_pred_named env p in - PLforall(quants,p) + let env, quants = Convert_env.env_map convert_var_decl env x in + let env, p = convert_pred_named env p in + env, PLforall(quants,p) | Pexists(x,p) -> - let quants = List.map (convert_var_decl env) x in - let p = convert_pred_named env p in - PLexists(quants,p) + let env, quants = Convert_env.env_map convert_var_decl env x in + let env, p = convert_pred_named env p in + env, PLexists(quants,p) | Pat(l,p) -> let l = convert_logic_label l in - let p = convert_pred_named env p in - PLat(p,l) + let env, p = convert_pred_named env p in + env, PLat(p,l) | Pvalid_function(t) -> - let t = convert_logic_expr env t in - PLvalid_function(t) + let env, t = convert_logic_expr env t in + env, PLvalid_function(t) | Pvalid_read(l,t) -> let l = convert_logic_label_opt l in - let t = convert_logic_expr env t in - PLvalid_read(l,t) + let env, t = convert_logic_expr env t in + env, PLvalid_read(l,t) | Pvalid(l,t) -> let l = convert_logic_label_opt l in - let t = convert_logic_expr env t in - PLvalid(l,t) + let env, t = convert_logic_expr env t in + env, PLvalid(l,t) | Pinitialized(l,t) -> let l = convert_logic_label_opt l in - let t = convert_logic_expr env t in - PLinitialized(l,t) + let env, t = convert_logic_expr env t in + env, PLinitialized(l,t) | Pallocable(l,t) -> let l = convert_logic_label_opt l in - let t = convert_logic_expr env t in - PLallocable(l,t) + let env, t = convert_logic_expr env t in + env, PLallocable(l,t) | Pfreeable(l,t) -> let l = convert_logic_label_opt l in - let t = convert_logic_expr env t in - PLfreeable(l,t) + let env, t = convert_logic_expr env t in + env, PLfreeable(l,t) | Pfresh(Some l1, Some l2,t1,t2) -> let l1 = convert_logic_label l1 in let l2 = convert_logic_label l2 in - let t1 = convert_logic_expr env t1 in - let t2 = convert_logic_expr env t2 in - PLfresh (Some(l1,l2),t1,t2) + let env, t1 = convert_logic_expr env t1 in + let env, t2 = convert_logic_expr env t2 in + env, PLfresh (Some(l1,l2),t1,t2) | Pfresh(None,None,t1,t2) -> - let t1 = convert_logic_expr env t1 in - let t2 = convert_logic_expr env t2 in - PLfresh (None,t1,t2) + let env, t1 = convert_logic_expr env t1 in + let env, t2 = convert_logic_expr env t2 in + env, PLfresh (None,t1,t2) | Pfresh(_,_,_,_) -> Frama_Clang_option.fatal "zero or two labels needed in fresh construct" | Psubtype _ -> Frama_Clang_option.not_yet_implemented "subtyping relation" and convert_inner_body env li = - let body = + let env, body = match li.fun_body with | LBnone -> Convert_env.fatal env "local binding without body" | LBreads _ -> Convert_env.fatal env "local binding with read clause" @@ -543,14 +594,15 @@ and convert_inner_body env li = | LBpred p -> convert_pred_named env p in match li.profile with - | [] -> body + | [] -> env, body | prms -> - let convert_arg_decl a = - let typ = convert_logic_type env a.la_type in + let convert_arg_decl env a = + let env, typ = convert_logic_type env a.la_type in let v = a.la_name in - typ, v + env, (typ, v) in - let prms = List.map convert_arg_decl prms in + let env, prms = Convert_env.env_map convert_arg_decl env prms in + env, { lexpr_node = PLlambda(prms,body); lexpr_loc = Convert_env.get_loc env } let convert_logic_ctor env ctor = @@ -564,39 +616,50 @@ let convert_logic_ctor env ctor = = Convert_env.typedef_normalize env ctor.ctor_name TStandard in Mangling.mangle ctor_name t None in - let prms = List.map (convert_logic_type env) ctor.ctor_params in - (name,prms) + let env, prms = + Convert_env.env_map convert_logic_type env ctor.ctor_params + in + env, (name,prms) let convert_logic_type_def env = function - | LTsum ctors -> TDsum (List.map (convert_logic_ctor env) ctors) - | LTsyn t -> TDsyn (convert_logic_type env t) + | LTsum ctors -> + let env, ctors = Convert_env.env_map convert_logic_ctor env ctors in + env, TDsum ctors + | LTsyn t -> + let env, t = convert_logic_type env t in env, TDsyn t let convert_extended env e = - (e.ext_name, List.map (convert_pred_named env) e.predicates) + let env, preds = Convert_env.env_map convert_pred_named env e.predicates in + env, (e.ext_name, preds) let convert_allocation env = function | Intermediate_format.FreeAlloc(f,a) -> - Logic_ptree.FreeAlloc - (List.map (convert_logic_expr env) f, List.map (convert_logic_expr env) a) - | Intermediate_format.FreeAllocAny -> Logic_ptree.FreeAllocAny + let env, f = Convert_env.env_map convert_logic_expr env f in + let env, a = Convert_env.env_map convert_logic_expr env a in + env, Logic_ptree.FreeAlloc (f,a) + | Intermediate_format.FreeAllocAny -> env, Logic_ptree.FreeAllocAny let convert_deps env = function | Intermediate_format.From l -> - Logic_ptree.From (List.map (convert_logic_expr env) l) - | Intermediate_format.FromAny -> Logic_ptree.FromAny + let env, l = Convert_env.env_map convert_logic_expr env l in + env, Logic_ptree.From l + | Intermediate_format.FromAny -> env, Logic_ptree.FromAny let convert_from env f = - convert_logic_expr env f.floc, convert_deps env f.vars + let env, w = convert_logic_expr env f.floc in + let env, r = convert_deps env f.vars in + env, (w,r) let convert_assigns env = function - | Intermediate_format.WritesAny -> Logic_ptree.WritesAny + | Intermediate_format.WritesAny -> env, Logic_ptree.WritesAny | Intermediate_format.Writes l -> - Logic_ptree.Writes (List.map (convert_from env) l) + let env, l = Convert_env.env_map convert_from env l in + env, Logic_ptree.Writes l let convert_pred_tp env ?(kind=Cil_types.Assert) p = (* TODO: support check and admit in ACSL++. *) - let tp_statement = convert_pred_named env p in - { tp_kind = kind; tp_statement } + let env, tp_statement = convert_pred_named env p in + env, { tp_kind = kind; tp_statement } let convert_termination_kind = function | Intermediate_format.Normal -> Cil_types.Normal @@ -606,26 +669,35 @@ let convert_termination_kind = function | Intermediate_format.Returns -> Cil_types.Returns let convert_post_cond env p = - convert_termination_kind p.tkind, convert_pred_tp env p.pred + let kind = convert_termination_kind p.tkind in + let env, p = convert_pred_tp env p.pred in + env, (kind, p) let convert_behavior env bhv = let b_name = bhv.beh_name in - let b_requires = List.map (convert_pred_tp env) bhv.requires in - let b_assumes = List.map (convert_pred_named env) bhv.assumes in - let b_post_cond = List.map (convert_post_cond env) bhv.post_cond in - let b_assigns = convert_assigns env bhv.assignements in - let b_allocation = convert_allocation env bhv.alloc in - let b_extended = List.map (convert_extended env) bhv.extended in - { b_name; b_requires; b_assumes; b_post_cond; - b_assigns; b_allocation; b_extended } - -let convert_variant env v = convert_logic_expr env v.vbody, v.vname + let env_map = Convert_env.env_map in + (* optional arguments do not mix well with higher-order funcs *) + let convert_pred_tp env p = convert_pred_tp env p in + let env, b_requires = env_map convert_pred_tp env bhv.requires in + let env, b_assumes = env_map convert_pred_named env bhv.assumes in + let env, b_post_cond = env_map convert_post_cond env bhv.post_cond in + let env, b_assigns = convert_assigns env bhv.assignements in + let env, b_allocation = convert_allocation env bhv.alloc in + let env, b_extended = env_map convert_extended env bhv.extended in + env, { b_name; b_requires; b_assumes; b_post_cond; + b_assigns; b_allocation; b_extended } + +let convert_variant env v = + let env, body = convert_logic_expr env v.vbody in + env, (body, v.vname) let convert_function_contract env contract = - let spec_behavior = List.map (convert_behavior env) contract.behavior in - let spec_variant = Option.map (convert_variant env) contract.variant in - let spec_terminates = - Option.map (convert_pred_named env) contract.terminates + let env_map = Convert_env.env_map in + let env_opt = Convert_env.env_opt in + let env, spec_behavior = env_map convert_behavior env contract.behavior in + let env, spec_variant = env_opt convert_variant env contract.variant in + let env, spec_terminates = + env_opt convert_pred_named env contract.terminates in let spec_complete_behaviors = List.map (fun c -> c.behaviors) contract.complete_behaviors @@ -633,8 +705,9 @@ let convert_function_contract env contract = let spec_disjoint_behaviors = List.map (fun c -> c.behaviors) contract.disjoint_behaviors in - { spec_behavior; spec_variant; spec_terminates; spec_complete_behaviors; - spec_disjoint_behaviors } + env, + { spec_behavior; spec_variant; spec_terminates; + spec_complete_behaviors; spec_disjoint_behaviors } let convert_inv_kind = function | InvariantAsAssertion -> false @@ -642,46 +715,65 @@ let convert_inv_kind = function let convert_loop_pragma env = function | Intermediate_format.Unroll_specs l -> - Logic_ptree.Unroll_specs (List.map (convert_logic_expr env) l) + let env, l = Convert_env.env_map convert_logic_expr env l in + env, Logic_ptree.Unroll_specs l | Intermediate_format.Widen_hints l -> - Logic_ptree.Unroll_specs (List.map(convert_logic_expr env) l) + let env, l = Convert_env.env_map convert_logic_expr env l in + env, Logic_ptree.Widen_hints l | Intermediate_format.Widen_variables l -> - Logic_ptree.Widen_variables (List.map (convert_logic_expr env) l) + let env, l = Convert_env.env_map convert_logic_expr env l in + env, Logic_ptree.Widen_variables l let convert_slice_pragma env = function | Intermediate_format.SPexpr e -> - Logic_ptree.SPexpr (convert_logic_expr env e) - | Intermediate_format.SPctrl -> Logic_ptree.SPctrl - | Intermediate_format.SPstmt -> Logic_ptree.SPstmt + let env, e = convert_logic_expr env e in + env, Logic_ptree.SPexpr e + | Intermediate_format.SPctrl -> env, Logic_ptree.SPctrl + | Intermediate_format.SPstmt -> env, Logic_ptree.SPstmt let convert_impact_pragma env = function | Intermediate_format.IPexpr e -> - Logic_ptree.IPexpr (convert_logic_expr env e) - | Intermediate_format.IPstmt -> Logic_ptree.IPstmt + let env, e = convert_logic_expr env e in + env, Logic_ptree.IPexpr e + | Intermediate_format.IPstmt -> env, Logic_ptree.IPstmt let convert_pragma env = function | Intermediate_format.Loop_pragma p -> - Logic_ptree.Loop_pragma (convert_loop_pragma env p) + let env, p = convert_loop_pragma env p in + env, Logic_ptree.Loop_pragma p | Intermediate_format.Slice_pragma p -> - Logic_ptree.Slice_pragma (convert_slice_pragma env p) + let env, p = convert_slice_pragma env p in + env, Logic_ptree.Slice_pragma p | Intermediate_format.Impact_pragma p -> - Logic_ptree.Impact_pragma (convert_impact_pragma env p) + let env, p = convert_impact_pragma env p in + env, Logic_ptree.Impact_pragma p let convert_code_annot env = function | Intermediate_format.Assert(bhvs,pred) -> - AAssert(bhvs, convert_pred_tp env pred) - | StmtSpec(bhvs,spec) -> AStmtSpec(bhvs,convert_function_contract env spec) + let env, pred = convert_pred_tp env pred in + env, AAssert(bhvs, pred) + | StmtSpec(bhvs,spec) -> + let env, spec = convert_function_contract env spec in + env, AStmtSpec(bhvs, spec) | Invariant(bhvs,kind,inv) -> let kind = convert_inv_kind kind in - let inv = convert_pred_tp env inv in - AInvariant(bhvs,kind,inv) - | Variant v -> AVariant (convert_variant env v) - | Assigns (bhvs,a) -> AAssigns(bhvs,convert_assigns env a) - | Allocation(bhvs,a) -> AAllocation(bhvs,convert_allocation env a) - | Pragma p -> APragma (convert_pragma env p) + let env, inv = convert_pred_tp env inv in + env, AInvariant(bhvs,kind,inv) + | Variant v -> + let env, v = convert_variant env v in + env, AVariant v + | Assigns (bhvs,a) -> + let env, a = convert_assigns env a in + env, AAssigns(bhvs, a) + | Allocation(bhvs,a) -> + let env, a = convert_allocation env a in + env, AAllocation(bhvs,a) + | Pragma p -> + let env, p = convert_pragma env p in + env, APragma p let rec convert_annot env annot = - let annot, env = + let env, annot = match annot with | Dfun_or_pred (loc,info) -> let env = Convert_env.set_loc env loc in @@ -698,77 +790,81 @@ let rec convert_annot env annot = Mangling.mangle info_name t None in let labels = List.map convert_logic_label info.arg_labels in - let rt = Option.map (convert_logic_type env) info.returned_type in - let params = List.map (convert_logic_param env) info.profile in + let env, rt = + Convert_env.env_opt convert_logic_type env info.returned_type + in + let env, params = + Convert_env.env_map convert_logic_param env info.profile + in (match info.fun_body,rt with | LBnone, None -> - LDpredicate_reads(name,labels,info.tparams,params,None) + env, LDpredicate_reads(name,labels,info.tparams,params,None) | LBnone, Some rt -> - LDlogic_reads(name,labels,info.tparams,rt,params,None) + env, LDlogic_reads(name,labels,info.tparams,rt,params,None) | LBreads l, None -> - let reads = List.map (convert_logic_expr env) l in - LDpredicate_reads(name,labels,info.tparams,params,Some reads) + let env, reads = Convert_env.env_map convert_logic_expr env l in + env, LDpredicate_reads(name,labels,info.tparams,params,Some reads) | LBreads l, Some rt -> - let reads = List.map (convert_logic_expr env) l in - LDlogic_reads(name,labels,info.tparams,rt,params,Some reads) + let env, reads = Convert_env.env_map convert_logic_expr env l in + env, LDlogic_reads(name,labels,info.tparams,rt,params,Some reads) | LBterm _, None -> Convert_env.fatal env "predicate definition with a term as body" | LBterm body, Some rt -> - let body = convert_logic_expr env body in - LDlogic_def(name,labels,info.tparams,rt,params,body) + let env, body = convert_logic_expr env body in + env, LDlogic_def(name,labels,info.tparams,rt,params,body) | LBpred _, Some _ -> Convert_env.fatal env "logic function definition with a predicate as body" | LBpred body, None -> - let body = convert_pred_named env body in - LDpredicate_def(name,labels,info.tparams,params,body) + let env, body = convert_pred_named env body in + env, LDpredicate_def(name,labels,info.tparams,params,body) | LBinductive _, Some _ -> Convert_env.fatal env "logic function definition with inductive body" | LBinductive body, None -> - let inductive_case ind = + let inductive_case env ind = let labs = List.map convert_logic_label ind.labels in - let def = convert_pred_named env ind.def in - (ind.def_name,labs,ind.arguments,def) + let env, def = convert_pred_named env ind.def in + env, (ind.def_name,labs,ind.arguments,def) in - let body = List.map inductive_case body in - LDinductive_def(name,labels,info.tparams,params,body) - ), env + let env, body = Convert_env.env_map inductive_case env body in + env, LDinductive_def(name,labels,info.tparams,params,body) + ) | Dvolatile(loc,mem,read,write) -> let env = Convert_env.set_loc env loc in - let mem = List.map (convert_logic_expr env) mem in + let env, mem = Convert_env.env_map convert_logic_expr env mem in (* NB: should we have the real type of the arguments of the functions?*) let mangle name signature = let name, t = Convert_env.typedef_normalize env name TStandard in Mangling.mangle name t signature in - let read = Option.map (Fun.flip mangle None) - read in - let write = Option.map (Fun.flip mangle None) - write in - LDvolatile(mem,(read,write)), env + let read = Option.map (Fun.flip mangle None) read in + let write = Option.map (Fun.flip mangle None) write in + env, LDvolatile(mem,(read,write)) | Daxiomatic(loc,s,annots) -> let env = Convert_env.set_loc env loc in - let annots = List.map (convert_annot env) annots in - LDaxiomatic(s,annots), env + let env, annots = Convert_env.env_map convert_annot env annots in + env, LDaxiomatic(s,annots) | Dtype(loc,lt_info) -> let env = Convert_env.set_loc env loc in let name = if lt_info.logic_type_info_is_extern_c then lt_info.type_name.decl_name else - let info_name, t = Convert_env.typedef_normalize - env lt_info.type_name TStandard in + let info_name, t = + Convert_env.typedef_normalize env lt_info.type_name TStandard + in Mangling.mangle info_name t None in - let def = Option.map (convert_logic_type_def env) - lt_info.definition in - LDtype(name, lt_info.params, def), env + let env, def = + Convert_env.env_opt convert_logic_type_def env lt_info.definition + in + env, LDtype(name, lt_info.params, def) | Dlemma(loc,name,is_axiom,labs,params,body) -> let env = Convert_env.set_loc env loc in let labs = List.map convert_logic_label labs in let kind = if is_axiom then Cil_types.Admit else Assert in - let body = convert_pred_tp env ~kind body in - LDlemma(name,labs,params,body), env + let env, body = convert_pred_tp env ~kind body in + env, LDlemma(name,labs,params,body) | Dinvariant(loc,body) -> let env = Convert_env.set_loc env loc in let name = @@ -779,43 +875,45 @@ let rec convert_annot env annot = env body.li_name TStandard in Mangling.mangle body_name t None in - let body = + let env, body = match body.fun_body with | LBpred p -> convert_pred_named env p | _ -> Convert_env.fatal env "unexpected body for a global invariant" in - LDinvariant(name, body), env + env, LDinvariant(name, body) | Dtype_annot (loc, body) -> let env = Convert_env.set_loc env loc in let inv_name = if body.li_extern_c then body.li_name.decl_name else - let body_name, t = Convert_env.typedef_normalize - env body.li_name TStandard in + let body_name, t = + Convert_env.typedef_normalize env body.li_name TStandard + in Mangling.mangle body_name t None in - let this_type, this_name = + let env, (this_type, this_name) = match body.profile with - | [ { la_type = t; la_name = s } ] -> convert_logic_type env t, s + | [ { la_type = t; la_name = s } ] -> + let env, t = convert_logic_type env t in env, (t, s) | _ -> Convert_env.fatal env "unexpected number of parameters \ in definition of type invariant" in - let inv = + let env, inv = match body.fun_body with | LBpred p -> convert_pred_named env p | _ -> Convert_env.fatal env "unexpected body for a type invariant" in - LDtype_annot { inv_name; this_type; this_name; inv }, env + env, LDtype_annot { inv_name; this_type; this_name; inv } | Dmodel_annot(loc,model) -> let env = Convert_env.set_loc env loc in let model_name = model.Intermediate_format.model_name in - let model_type = convert_logic_type env model.field_type in - let model_for_type = convert_logic_type env model.base_type in - LDmodel_annot { model_for_type; model_type; model_name }, env + let env, model_type = convert_logic_type env model.field_type in + let env, model_for_type = convert_logic_type env model.base_type in + env, LDmodel_annot { model_for_type; model_type; model_name } in - { decl_node = annot; decl_loc = Convert_env.get_loc env; } + env, { decl_node = annot; decl_loc = Convert_env.get_loc env; } diff --git a/convert_acsl.mli b/convert_acsl.mli index 9f6abe0ce6251a985e212a5b1a99f2ecaff67d94..55a5faa6f43de5dc0785bbd31cd0f3ec2f022034 100644 --- a/convert_acsl.mli +++ b/convert_acsl.mli @@ -24,11 +24,14 @@ val convert_function_contract: Convert_env.env -> - Intermediate_format.function_contract -> Logic_ptree.spec + Intermediate_format.function_contract -> + Convert_env.env * Logic_ptree.spec val convert_code_annot: Convert_env.env -> - Intermediate_format.code_annotation -> Logic_ptree.code_annot + Intermediate_format.code_annotation -> + Convert_env.env * Logic_ptree.code_annot val convert_annot: - Convert_env.env -> Intermediate_format.global_annotation -> Logic_ptree.decl + Convert_env.env -> Intermediate_format.global_annotation -> + Convert_env.env * Logic_ptree.decl diff --git a/convert_env.ml b/convert_env.ml index e3466772f26ca65eaff72d1ef1f7028c8b58b521..5adbb515f34916e97195b4d2c99ac0bd25803d18 100644 --- a/convert_env.ml +++ b/convert_env.ml @@ -258,6 +258,24 @@ let get_typedef env name = let has_typedef env name = Fclang_datatype.Qualified_name.Map.mem (name, TStandard) env.typedefs +let memo_wchar env = + let wchar_name = { prequalification=[];decl_name="wchar_t"} in + if has_typedef env wchar_name then env + else begin + let kind = Cil.theMachine.wcharKind in + let repr = Cxx_utils.(unqual_type (int_type kind)) in + let env = add_typedef env wchar_name repr in + let ghost = is_ghost env in + let env = set_ghost env false in + let loc = get_loc env in + let spec = Cxx_utils.spec_of_ikind kind in + let name = ["wchar_t", Cabs.JUSTBASE, [], loc] in + let def = Cabs.TYPEDEF((spec,name),loc) in + let env = add_c_global env def in + let env = set_ghost env ghost in + env + end + let rec template_parameter_normalize env tparam = match tparam with | TPStructOrClass name -> TPStructOrClass { name with prequalification @@ -790,3 +808,12 @@ let reset_closure env = match env.captured_vars with | [] -> env | _::captured_vars -> { env with captured_vars } + +let env_map f env l = + let do_one (env, acc) x = let env, y = f env x in env,y::acc in + let env, res = List.fold_left do_one (env,[]) l in + env, List.rev res + +let env_opt f env = function + | Some x -> let env, y = f env x in env, Some y + | None -> env, None diff --git a/convert_env.mli b/convert_env.mli index b5d3c8bb4da058253821bb9570ced546ace6715b..9ab4dbe64b996f6ed92a47043c6de01120e2e3c3 100644 --- a/convert_env.mli +++ b/convert_env.mli @@ -128,6 +128,11 @@ val get_typedef: env -> qualified_name -> qual_type val has_typedef: env -> qualified_name -> bool +val memo_wchar: env -> env +(** adds a definition of wchar_t if not already present. Used when encountering + [wchar_t] on the C++ side. +*) + val add_struct: env -> (qualified_name * tkind) -> (string * qual_type) list -> env @@ -315,3 +320,13 @@ val reset_closure: env -> env val add_closure_info: env -> capture list -> env (** Associates the given identifiers to the appropriate closure kind. *) + +(** iterates a function that might change the environment over a list, + and returns the final environment together with the list of results +*) +val env_map: (env -> 'a -> (env * 'b)) -> env -> 'a list -> (env * 'b list) + +(** [env_opt f env opt] applies [f] if [opt] has a value, and [None], without + changing the environment otherwise. +*) +val env_opt: (env -> 'a -> (env * 'b)) -> env -> 'a option -> (env * 'b option) diff --git a/cxx_utils.ml b/cxx_utils.ml index a4c74979e904f1c2f515492504456dd521a640ca..c4ed3ab1edf599adcf9396042304d084d91ff289 100644 --- a/cxx_utils.ml +++ b/cxx_utils.ml @@ -393,6 +393,23 @@ let meth_name class_name tkind decl_name = let prequalification= List.append class_name.prequalification [last_elt] in { prequalification; decl_name } +let int_kind = function + | Cil_types.IBool -> IBool + | IChar -> + if Cil.theMachine.theMachine.char_is_unsigned then IChar_u else IChar_s + | IUChar -> IUChar + | ISChar -> ISChar + | IInt -> IInt + | IUInt -> IUInt + | IShort -> IShort + | IUShort -> IUShort + | ILong -> ILong + | IULong -> IULong + | ILongLong -> ILongLong + | IULongLong -> IULongLong + +let int_type ikind = Intermediate_format.Int (int_kind ikind) + let unqual_type t = { qualifier = []; plain_type = t } let const_type t = { qualifier = [ Const ]; plain_type = t } @@ -431,3 +448,20 @@ let class_ptr (n,t) = unqual_type (plain_class_ptr (n,t)) let class_lvref (n,t) = unqual_type (plain_class_lvref (n,t)) let class_rvref (n,t) = unqual_type (plain_class_rvref (n,t)) + +let spec_of_ikind s = + let open Cabs in + let open Cil_types in + match s with + | IBool -> [ SpecType Tbool ] + | IChar -> [ SpecType Tchar ] + | ISChar -> [ SpecType Tsigned; SpecType Tchar ] + | IUChar -> [ SpecType Tunsigned; SpecType Tchar ] + | IInt -> [ SpecType Tint ] + | IUInt -> [ SpecType Tunsigned ] + | IShort -> [ SpecType Tshort ] + | IUShort -> [ SpecType Tunsigned; SpecType Tshort ] + | ILong -> [ SpecType Tlong ] + | IULong -> [ SpecType Tunsigned; SpecType Tlong ] + | ILongLong -> [ SpecType Tlong; SpecType Tlong ] + | IULongLong -> [ SpecType Tunsigned; SpecType Tlong; SpecType Tlong ] diff --git a/cxx_utils.mli b/cxx_utils.mli index f5d77c22e7a0647cf68ddb7fcb48e5c585b07a86..a5990517ad3a16e9d96585370cf04e5ac9c55442 100644 --- a/cxx_utils.mli +++ b/cxx_utils.mli @@ -59,6 +59,9 @@ val meth_name: qualified_name -> tkind -> string -> qualified_name (** {3 Types}. *) +(** returns an IR typ corresponding to the Cil's kind *) +val int_type: Cil_types.ikind -> typ + (** returns the unqualified version of the given typ. *) val unqual_type: typ -> qual_type @@ -99,3 +102,5 @@ val class_ptr: Fclang_datatype.Qualified_name.t -> qual_type val class_lvref: Fclang_datatype.Qualified_name.t -> qual_type val class_rvref: Fclang_datatype.Qualified_name.t -> qual_type + +val spec_of_ikind: Cil_types.ikind -> Cabs.specifier diff --git a/fclang_datatype.ml b/fclang_datatype.ml index 1a89bafbd2178fd91c4859d3dae737e062707f95..0e8651e41747edc17aa070c5f5b83a6a729adb80 100644 --- a/fclang_datatype.ml +++ b/fclang_datatype.ml @@ -83,8 +83,6 @@ and pretty_type fmt typ = | IChar32 -> Format.pp_print_string fmt "char32_t" | IWChar_u | IWChar_s -> Format.pp_print_string fmt "wchar_t" - | IWUChar -> Format.pp_print_string fmt "unsigned wchar_t" - | IWSChar -> Format.pp_print_string fmt "signed wchar_t" | IChar -> Format.pp_print_string fmt "char" | IWChar -> Format.pp_print_string fmt "wchar_t" | IShort -> Format.pp_print_string fmt "short" diff --git a/framaCIRGen_src/ACSLComment.cpp b/framaCIRGen_src/ACSLComment.cpp index e5c18ec6d483c84a8b80388e0f88867680ff105e..6a2c6c4320088e018ffcbaa8d6c93ae2d807ede6 100644 --- a/framaCIRGen_src/ACSLComment.cpp +++ b/framaCIRGen_src/ACSLComment.cpp @@ -32,6 +32,7 @@ #include "clang/Parse/Parser.h" #include "clang/AST/ASTConsumer.h" #include "clang/Sema/Scope.h" +#include <sstream> #include <string> bool @@ -261,12 +262,18 @@ void ACSLComment::parseGhostGlobal( code = code.substr(_startOfGhost); clang::SourceLocation loc = getSourceLocation().getLocWithOffset(_startOfGhost); // FIXME - check this for correct location + auto& source_manager = compilerInstance.getSourceManager(); + auto filename = source_manager.getFilename(loc); + auto line = source_manager.getSpellingLineNumber(loc); + std::ostringstream content; + content << "#line " << line << " \"" << filename.str() << "\"\n"; + auto buffer = content.str(); + buffer+=code; clang::Preprocessor& cpp = compilerInstance.getPreprocessor(); clang::Parser* parser = static_cast<clang::Parser*>(cpp.getCodeCompletionHandler()); std::unique_ptr<llvm::MemoryBuffer> buff = - llvm::MemoryBuffer::getMemBufferCopy(code, "ghost.cxx"); - clang::SourceManager& source_manager = compilerInstance.getSourceManager(); + llvm::MemoryBuffer::getMemBufferCopy(buffer, filename); clang::FileID file = source_manager.createFileID( std::move(buff),clang::SrcMgr::C_User,0,0,loc); @@ -280,6 +287,7 @@ void ACSLComment::parseGhostGlobal( while (!parser->ParseTopLevelDecl(Decl)) { #endif clang::DeclGroupRef DGR = Decl.get(); + for (auto decl: DGR) decl->setDeclContext(clangContext); consumer->HandleTopLevelDecl(DGR); } cpp.enableIncrementalProcessing(false); diff --git a/framaCIRGen_src/ACSLLogicType.cpp b/framaCIRGen_src/ACSLLogicType.cpp index 034f23a8b12229ad772c3f48880396f16b7b587a..09d8d6509f8deb3f2a06788d1c81d6781af87e27 100644 --- a/framaCIRGen_src/ACSLLogicType.cpp +++ b/framaCIRGen_src/ACSLLogicType.cpp @@ -36,7 +36,6 @@ bool is_signed(ikind i, Parser::Arguments &context) { case ICHAR_U: case IUCHAR: case IWCHAR_U: - case IWUCHAR: case IUSHORT: case IUINT: case IULONG: @@ -872,8 +871,9 @@ LogicType::readToken(Parser::State& state, Parser::Arguments& arguments) { DefineAddErrorAndParse("'unsigned' meaningless for char16_t") case ICHAR32: DefineAddErrorAndParse("'unsigned' meaningless for char32_t") + case IWCHAR: + DefineAddErrorAndParse("'unsigned' meaningless for wchar_t") case IUCHAR: - case IWUCHAR: case IUSHORT: case IUINT: case IULONG: @@ -882,9 +882,6 @@ LogicType::readToken(Parser::State& state, Parser::Arguments& arguments) { case ICHAR: _typeResult->cons_logic_type.Lint.kind = IUCHAR; break; - case IWCHAR: - _typeResult->cons_logic_type.Lint.kind = IWUCHAR; - break; case ISHORT: _typeResult->cons_logic_type.Lint.kind = IUSHORT; break; @@ -916,8 +913,9 @@ LogicType::readToken(Parser::State& state, Parser::Arguments& arguments) { DefineAddErrorAndParse("'signed' meaningless for char16_t") case ICHAR32: DefineAddErrorAndParse("'signed' meaningless for char32_t") + case IWCHAR: + DefineAddErrorAndParse("'signed' meaningless for wchar_t") case IUCHAR: - case IWUCHAR: case IUSHORT: case IUINT: case IULONG: @@ -925,7 +923,6 @@ LogicType::readToken(Parser::State& state, Parser::Arguments& arguments) { DefineAddErrorAndParse( "mixing 'signed' and 'unsigned' in type specification") case ICHAR: - case IWCHAR: case ISHORT: case ILONG: case ILONGLONG: diff --git a/framaCIRGen_src/ACSLTermOrPredicate.cpp b/framaCIRGen_src/ACSLTermOrPredicate.cpp index 6dbc2d5d3f2a19933c78a651af20c31f1da9bd7c..ed0baeefa0ecfdccf4cc362e1829ad898351d956 100644 --- a/framaCIRGen_src/ACSLTermOrPredicate.cpp +++ b/framaCIRGen_src/ACSLTermOrPredicate.cpp @@ -26,6 +26,7 @@ // #include "ACSLTermOrPredicate.h" +#include "Clang_utils.h" #include "clang/AST/DeclTemplate.h" namespace Acsl { @@ -580,19 +581,7 @@ term TermOrPredicate::applyTermCast(logic_type& ccastType, term targument, logic_type ltype, Parser::Arguments& context) { GuardLogicType guardType(ccastType); - logic_type alternateType = NULL; - GuardLogicType guardAlternate(alternateType); - if (ltype->tag_logic_type == LINTEGER) { - alternateType = ltype = logic_type_Lint(IINT); - targument = term_cons(term_node_TCastE(logic_type_dup(ltype), targument), - copy_loc(targument->loc), NULL); - } - else if (ltype->tag_logic_type == LREAL) { - alternateType = ltype = logic_type_Lfloat(FDOUBLE); - targument = term_cons(term_node_TCastE(logic_type_dup(ltype), targument), - copy_loc(targument->loc), NULL); - }; - if (isCType(ltype)) { + if (isCType(ltype)||isPlainBooleanType(ltype,context)) { if (isCPointerType(ccastType, context) && isCArrayType(ltype, context)) { if (!isCArray(targument,ltype,context)) { context.addErrorMessage("cannot cast logic array to pointer type"); @@ -607,29 +596,6 @@ TermOrPredicate::applyTermCast(logic_type& ccastType, term targument, && qualified_name_equal(ccastType->cons_logic_type.Lenum.name, ltype->cons_logic_type.Lenum.name)) return targument; - if (!needLogicCast(ltype, ccastType)) - return targument; - // if (isCPointerType(ccastType, context) - // && targument->node->tag_term_node == TCASTE) { - // logic_type oldType = targument->node->cons_term_node.TCastE.oldtype; - // if (isCPointerType(oldType, context)) { - // // Old cast can be removed... - // if (needLogicCast(ccastType, oldType)) { - // free_logic_type(targument->node->cons_term_node.TCastE.code_type); - // targument->node->cons_term_node.TCastE.code_type - // = logic_type_dup(ccastType); - // targument->ltype = logic_type_Ctype(ccastType); - // ccastType = NULL; - // return targument; - // }; - // // In fact, both casts can be removed. - // term result = targument->node->cons_term_node.TCastE.subexpr; - // targument->node->cons_term_node.TCastE.subexpr = NULL; - // targument->node->tag_term_node = (tag_term_node) (TLET + 1); - // return result; - // }; - // // Do not remove old cast because they are conversions !!! - // }; term_node valueResult = term_node_TCastE(ccastType, targument); term result = term_cons(valueResult, copy_loc(targument->loc), NULL); ccastType = NULL; @@ -674,7 +640,7 @@ TermOrPredicate::isSignedInteger(logic_type ctype, Parser::Arguments& context) { if (ctype->tag_logic_type == LINT) { ikind kind = ctype->cons_logic_type.Lint.kind; result = (kind == ICHAR_S || kind == ISCHAR || kind == IWCHAR_S - || kind == IWSCHAR || kind == ISHORT || kind == IINT || kind == ILONG); + || kind == ISHORT || kind == IINT || kind == ILONG); } else if (ctype->tag_logic_type == LINTEGER) result = true; @@ -3769,20 +3735,25 @@ TermOrPredicate::apply(Operator& operation, logic_type& ltypeResult, ltypeResult = logic_type_dup((logic_type) f->returned_type->content.container); if (isPlainBooleanType(ltypeResult, context)) { + predicate relation; location zeroLoc = copy_loc(expressionResult->loc); zeroLoc->linenum1 = zeroLoc->linenum2; zeroLoc->charnum1 = zeroLoc->charnum2; + if (context.is_builtin_boolean(ltypeResult)) { + relation = + predicate_Prel(REQ,term_dup(expressionResult),term_true(zeroLoc)); + } else { term zero = tzero(zeroLoc); - predicate relation; if (ltypeResult->tag_logic_type == LINTEGER) relation = predicate_Prel(RNEQ, term_dup(expressionResult), zero); else relation = predicate_Prel(RNEQ, term_cons(term_node_TLogic_coerce( logic_type_Linteger(), term_dup(expressionResult)), copy_loc(expressionResult->loc), NULL), zero); + } predicateResult = predicate_named_cons(NULL, copy_loc(expressionResult->loc), relation); - }; + } } else { predicateResult = @@ -4022,31 +3993,26 @@ TermOrPredicate::apply(Operator& operation, logic_type& ltypeResult, operation._startLocation, ltypeResult, context); operation._startLocation = NULL; return true; - case Operator::TNaming: + case Operator::TNaming: { // add naming to the local alias table; assert(operation._startLocation); free_location(operation._startLocation); operation._startLocation = NULL; - { list *endTermNames = NULL, *endPredicateNames = NULL; - if (targument) { - endTermNames = &targument->names; - while (*endTermNames) - endTermNames= &(*endTermNames)->next; - *endTermNames = cons_container(strdup(operation._fieldName.c_str()), - NULL); - ltypeResult = ltypeArgument; - expressionResult = targument; - }; - if (pargument) { - endPredicateNames = &pargument->pred_name; - while (*endPredicateNames) - endPredicateNames= &(*endPredicateNames)->next; - *endPredicateNames = cons_container(strdup( - operation._fieldName.c_str()), NULL); + if (targument) { + targument->names = + cons_container(strdup(operation._fieldName.c_str()), + targument->names); + ltypeResult = ltypeArgument; + expressionResult = targument; + }; + if (pargument) { + pargument->pred_name = + cons_container(strdup(operation._fieldName.c_str()), + pargument->pred_name); predicateResult = pargument; - }; }; return true; + } case Operator::TStructAccess: if (!targument) { if (pargument) { @@ -6323,21 +6289,11 @@ TermOrPredicate::readToken(Parser::State& state, Parser::Arguments& arguments) { if (token.isChar()) { constant = logic_constant_LChr(token.getChar()); valueType = logic_type_Lint(ICHAR); - node = - term_node_TCastE( - logic_type_dup(valueType), - term_cons( - term_node_TConst(constant), - arguments.newTokenLocation(), NULL)); + node = term_node_TConst(constant); } else { //wide char constant = logic_constant_LWChr(token.getWideChar()); valueType = logic_type_Lint(IWCHAR); - node = - term_node_TCastE( - logic_type_dup(valueType), - term_cons( - term_node_TConst(constant), - arguments.newTokenLocation(),NULL)); + node = term_node_TConst(constant); } break; } diff --git a/framaCIRGen_src/Clang_utils.cpp b/framaCIRGen_src/Clang_utils.cpp index b671d4baeed4be1da83a7bb72d9d0841f108a615..0f5b2837c38f78d0dde42ce139519ec5330c126f 100644 --- a/framaCIRGen_src/Clang_utils.cpp +++ b/framaCIRGen_src/Clang_utils.cpp @@ -1692,11 +1692,7 @@ Clang_utils::makePlainType( tkind templateParameters = NULL; const char* dec_name = get_aggregate_name(record, &templateParameters); const clang::DeclContext* ctx = record->getDeclContext(); - qualified_name name; - if (!isExternCContext(ctx)) - name = makeQualifiedName(ctx,dec_name,record); - else - name = qualified_name_cons(NULL, dec_name); + qualified_name name = makeQualifiedName(ctx,dec_name,record); switch (tagKind) { case clang::TTK_Struct: case clang::TTK_Class: diff --git a/intermediate_format.ast b/intermediate_format.ast index 34b149ca1b3ccf7e0fe848bc15f9f28cc3edc9f4..0977d39270a0534a6c4e4e7eab005ee36d02ef94 100644 --- a/intermediate_format.ast +++ b/intermediate_format.ast @@ -33,8 +33,6 @@ type ikind = | IChar32 { } (* char32_t. Same as uint_least32_t *) | IWChar_u { } | IWChar_s { } - | IWUChar { } - | IWSChar { } | IChar { } | IWChar { } | IShort { } diff --git a/mangling.ml b/mangling.ml index 936f417f76297494c730d5b7250c6605dbcc2881..cdb0045107d7880a8a07eb9a0bf88b4f03d87be3 100644 --- a/mangling.ml +++ b/mangling.ml @@ -152,8 +152,6 @@ let mangle_ikind = function | IShort -> "s" | IUShort -> "t" | IWChar | IWChar_s | IWChar_u -> "w" - | IWUChar -> "u6WUChar" - | IWSChar -> "u6WSChar" let mangle_fkind = function | FFloat -> "f" diff --git a/tests/basic/cxx_c_link.c b/tests/basic/cxx_c_link.c new file mode 100644 index 0000000000000000000000000000000000000000..c8b3cfa87270cad892814abc92ceb9099a58aa3d --- /dev/null +++ b/tests/basic/cxx_c_link.c @@ -0,0 +1,6 @@ +/* run.config +DONTRUN: main test file is in cxx_c_link.cpp +*/ + +#include "__fc_alloc_axiomatic.h" +#include "stdlib.h" diff --git a/tests/basic/cxx_c_link.cpp b/tests/basic/cxx_c_link.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1ffb0ac936bfaa12e34946602bc8a4f4cab47d82 --- /dev/null +++ b/tests/basic/cxx_c_link.cpp @@ -0,0 +1,6 @@ +/* run.config +OPT: %{dep:@PTEST_DIR@/@PTEST_NAME@.c} -print +*/ + +#include "__fc_alloc_axiomatic.h" +#include "stdlib.h" diff --git a/tests/basic/ghost_extern_c.cpp b/tests/basic/ghost_extern_c.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dd4755356bb4b9a14bbfc115f525d44ab61741d1 --- /dev/null +++ b/tests/basic/ghost_extern_c.cpp @@ -0,0 +1,9 @@ +/* run.config + OPT: -cxx-unmangling=none -print +*/ +extern "C" { + /*@ ghost int ghost_x; */ + int real_x; + + /*@ lemma sync: ghost_x == real_x; */ +} diff --git a/tests/basic/oracle/cxx_c_link.res.oracle b/tests/basic/oracle/cxx_c_link.res.oracle new file mode 100644 index 0000000000000000000000000000000000000000..82252579b854b4677ad8caf908330b69bf5b38f1 --- /dev/null +++ b/tests/basic/oracle/cxx_c_link.res.oracle @@ -0,0 +1,326 @@ +[kernel] Parsing cxx_c_link.cpp (external front-end) +Now output intermediate result +[kernel] Parsing cxx_c_link.c (with preprocessing) +/* Generated by Frama-C */ +#include "__fc_alloc_axiomatic.h" +#include "stdlib.h" +typedef unsigned long size_t; +typedef int wchar_t; +typedef struct __fc_div_t div_t; +typedef struct __fc_ldiv_t ldiv_t; +typedef struct __fc_lldiv_t lldiv_t; +/*@ +axiomatic dynamic_allocation { + predicate is_allocable{L}(ℤ n) + reads __fc_heap_status; + + axiom never_allocable{L}: + ∀ ℤ i; i < 0 ∨ i > 18446744073709551615UL ⇒ ¬is_allocable(i); + + } + */ +/*@ +axiomatic MemCmp { + logic ℤ memcmp{L1, L2}(char *s1, char *s2, ℤ n) + reads \at(*(s1 + (0 .. n - 1)),L1), \at(*(s2 + (0 .. n - 1)),L2); + + axiom memcmp_zero{L1, L2}: + ∀ char *s1, char *s2; + ∀ ℤ n; + memcmp{L1, L2}(s1, s2, n) ≡ 0 ⇔ + (∀ ℤ i; 0 ≤ i < n ⇒ \at(*(s1 + i),L1) ≡ \at(*(s2 + i),L2)); + + } + */ +/*@ +axiomatic MemChr { + logic 𔹠memchr{L}(char *s, ℤ c, ℤ n) + reads *(s + (0 .. n - 1)); + + logic ℤ memchr_off{L}(char *s, ℤ c, ℤ n) + reads *(s + (0 .. n - 1)); + + axiom memchr_def{L}: + ∀ char *s; + ∀ ℤ c; + ∀ ℤ n; + memchr(s, c, n) ≡ \true ⇔ + (∃ int i; 0 ≤ i < n ∧ *(s + i) ≡ c); + + } + */ +/*@ +axiomatic MemSet { + logic 𔹠memset{L}(char *s, ℤ c, ℤ n) + reads *(s + (0 .. n - 1)); + + axiom memset_def{L}: + ∀ char *s; + ∀ ℤ c; + ∀ ℤ n; + memset(s, c, n) ≡ \true ⇔ + (∀ ℤ i; 0 ≤ i < n ⇒ *(s + i) ≡ c); + + } + */ +/*@ +axiomatic StrLen { + logic ℤ strlen{L}(char *s) + reads *(s + (0 ..)); + + axiom strlen_pos_or_null{L}: + ∀ char *s; + ∀ ℤ i; + 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ '\000') ∧ + *(s + i) ≡ '\000' ⇒ strlen(s) ≡ i; + + axiom strlen_neg{L}: + ∀ char *s; + (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ '\000') ⇒ strlen(s) < 0; + + axiom strlen_before_null{L}: + ∀ char *s; + ∀ ℤ i; 0 ≤ i < strlen(s) ⇒ *(s + i) ≢ '\000'; + + axiom strlen_at_null{L}: + ∀ char *s; 0 ≤ strlen(s) ⇒ *(s + strlen(s)) ≡ '\000'; + + axiom strlen_not_zero{L}: + ∀ char *s; + ∀ ℤ i; + 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≢ '\000' ⇒ i < strlen(s); + + axiom strlen_zero{L}: + ∀ char *s; + ∀ ℤ i; + 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ '\000' ⇒ i ≡ strlen(s); + + axiom strlen_sup{L}: + ∀ char *s; + ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ '\000' ⇒ 0 ≤ strlen(s) ≤ i; + + axiom strlen_shift{L}: + ∀ char *s; + ∀ ℤ i; 0 ≤ i ≤ strlen(s) ⇒ strlen(s + i) ≡ strlen(s) - i; + + axiom strlen_create{L}: + ∀ char *s; + ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ '\000' ⇒ 0 ≤ strlen(s) ≤ i; + + axiom strlen_create_shift{L}: + ∀ char *s; + ∀ ℤ i; + ∀ ℤ k; + 0 ≤ k ≤ i ∧ *(s + i) ≡ '\000' ⇒ 0 ≤ strlen(s + k) ≤ i - k; + + axiom memcmp_strlen_left{L}: + ∀ char *s1, char *s2; + ∀ ℤ n; + memcmp{L, L}(s1, s2, n) ≡ 0 ∧ strlen(s1) < n ⇒ + strlen(s1) ≡ strlen(s2); + + axiom memcmp_strlen_right{L}: + ∀ char *s1, char *s2; + ∀ ℤ n; + memcmp{L, L}(s1, s2, n) ≡ 0 ∧ strlen(s2) < n ⇒ + strlen(s1) ≡ strlen(s2); + + axiom memcmp_strlen_shift_left{L}: + ∀ char *s1, char *s2; + ∀ ℤ k, ℤ n; + memcmp{L, L}(s1, s2 + k, n) ≡ 0 ≤ k ∧ strlen(s1) < n ⇒ + 0 ≤ strlen(s2) ≤ k + strlen(s1); + + axiom memcmp_strlen_shift_right{L}: + ∀ char *s1, char *s2; + ∀ ℤ k, ℤ n; + memcmp{L, L}(s1 + k, s2, n) ≡ 0 ≤ k ∧ strlen(s2) < n ⇒ + 0 ≤ strlen(s1) ≤ k + strlen(s2); + + } + */ +/*@ +axiomatic StrCmp { + logic ℤ strcmp{L}(char *s1, char *s2) + reads *(s1 + (0 .. strlen(s1))), *(s2 + (0 .. strlen(s2))); + + axiom strcmp_zero{L}: + ∀ char *s1, char *s2; + strcmp(s1, s2) ≡ 0 ⇔ + strlen(s1) ≡ strlen(s2) ∧ + (∀ ℤ i; 0 ≤ i ≤ strlen(s1) ⇒ *(s1 + i) ≡ *(s2 + i)); + + } + */ +/*@ +axiomatic StrNCmp { + logic ℤ strncmp{L}(char *s1, char *s2, ℤ n) + reads *(s1 + (0 .. n - 1)), *(s2 + (0 .. n - 1)); + + axiom strncmp_zero{L}: + ∀ char *s1, char *s2; + ∀ ℤ n; + strncmp(s1, s2, n) ≡ 0 ⇔ + (strlen(s1) < n ∧ strcmp(s1, s2) ≡ 0) ∨ + (∀ ℤ i; 0 ≤ i < n ⇒ *(s1 + i) ≡ *(s2 + i)); + + } + */ +/*@ +axiomatic StrChr { + logic 𔹠strchr{L}(char *s, ℤ c) + reads *(s + (0 .. strlen(s))); + + axiom strchr_def{L}: + ∀ char *s; + ∀ ℤ c; + strchr(s, c) ≡ \true ⇔ + (∃ ℤ i; 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ (char)c); + + } + */ +/*@ +axiomatic WMemChr { + logic 𔹠wmemchr{L}(wchar_t *s, wchar_t c, ℤ n) + reads *(s + (0 .. n - 1)); + + logic ℤ wmemchr_off{L}(wchar_t *s, wchar_t c, ℤ n) + reads *(s + (0 .. n - 1)); + + axiom wmemchr_def{L}: + ∀ wchar_t *s; + ∀ int c; + ∀ ℤ n; + wmemchr(s, c, n) ≡ \true ⇔ + (∃ int i; 0 ≤ i < n ∧ *(s + i) ≡ c); + + } + */ +/*@ +axiomatic WcsLen { + logic ℤ wcslen{L}(wchar_t *s) + reads *(s + (0 ..)); + + axiom wcslen_pos_or_null{L}: + ∀ wchar_t *s; + ∀ ℤ i; + 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ 0) ∧ + *(s + i) ≡ 0 ⇒ wcslen(s) ≡ i; + + axiom wcslen_neg{L}: + ∀ wchar_t *s; (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ 0) ⇒ wcslen(s) < 0; + + axiom wcslen_before_null{L}: + ∀ wchar_t *s; + ∀ int i; 0 ≤ i < wcslen(s) ⇒ *(s + i) ≢ 0; + + axiom wcslen_at_null{L}: + ∀ wchar_t *s; 0 ≤ wcslen(s) ⇒ *(s + wcslen(s)) ≡ 0; + + axiom wcslen_not_zero{L}: + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≢ 0 ⇒ i < wcslen(s); + + axiom wcslen_zero{L}: + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≡ 0 ⇒ i ≡ wcslen(s); + + axiom wcslen_sup{L}: + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ∧ *(s + i) ≡ 0 ⇒ 0 ≤ wcslen(s) ≤ i; + + axiom wcslen_shift{L}: + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ≤ wcslen(s) ⇒ wcslen(s + i) ≡ wcslen(s) - i; + + axiom wcslen_create{L}: + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ∧ *(s + i) ≡ 0 ⇒ 0 ≤ wcslen(s) ≤ i; + + axiom wcslen_create_shift{L}: + ∀ wchar_t *s; + ∀ int i; + ∀ int k; + 0 ≤ k ≤ i ∧ *(s + i) ≡ 0 ⇒ 0 ≤ wcslen(s + k) ≤ i - k; + + } + */ +/*@ +axiomatic WcsCmp { + logic ℤ wcscmp{L}(wchar_t *s1, wchar_t *s2) + reads *(s1 + (0 .. wcslen(s1))), *(s2 + (0 .. wcslen(s2))); + + axiom wcscmp_zero{L}: + ∀ wchar_t *s1, wchar_t *s2; + wcscmp(s1, s2) ≡ 0 ⇔ + wcslen(s1) ≡ wcslen(s2) ∧ + (∀ ℤ i; 0 ≤ i ≤ wcslen(s1) ⇒ *(s1 + i) ≡ *(s2 + i)); + + } + */ +/*@ +axiomatic WcsNCmp { + logic ℤ wcsncmp{L}(wchar_t *s1, wchar_t *s2, ℤ n) + reads *(s1 + (0 .. n - 1)), *(s2 + (0 .. n - 1)); + + axiom wcsncmp_zero{L}: + ∀ wchar_t *s1, wchar_t *s2; + ∀ ℤ n; + wcsncmp(s1, s2, n) ≡ 0 ⇔ + (wcslen(s1) < n ∧ wcscmp(s1, s2) ≡ 0) ∨ + (∀ ℤ i; 0 ≤ i < n ⇒ *(s1 + i) ≡ *(s2 + i)); + + } + */ +/*@ +axiomatic WcsChr { + logic 𔹠wcschr{L}(wchar_t *wcs, ℤ wc) + reads *(wcs + (0 .. wcslen(wcs))); + + axiom wcschr_def{L}: + ∀ wchar_t *wcs; + ∀ ℤ wc; + wcschr(wcs, wc) ≡ \true ⇔ + (∃ ℤ i; 0 ≤ i ≤ wcslen(wcs) ∧ *(wcs + i) ≡ (wchar_t)wc); + + } + */ +/*@ logic ℤ minimum(ℤ i, ℤ j) = i < j? i: j; + */ +/*@ logic ℤ maximum(ℤ i, ℤ j) = i < j? j: i; + */ +/*@ +predicate valid_string{L}(char *s) = + 0 ≤ strlen(s) ∧ \valid(s + (0 .. strlen(s))); + */ +/*@ +predicate valid_read_string{L}(char *s) = + 0 ≤ strlen(s) ∧ \valid_read(s + (0 .. strlen(s))); + */ +/*@ +predicate valid_read_nstring{L}(char *s, ℤ n) = + (\valid_read(s + (0 .. n - 1)) ∧ \initialized(s + (0 .. n - 1))) ∨ + valid_read_string(s); + */ +/*@ +predicate valid_string_or_null{L}(char *s) = s ≡ \null ∨ valid_string(s); + */ +/*@ +predicate valid_wstring{L}(wchar_t *s) = + 0 ≤ wcslen(s) ∧ \valid(s + (0 .. wcslen(s))); + */ +/*@ +predicate valid_read_wstring{L}(wchar_t *s) = + 0 ≤ wcslen(s) ∧ \valid_read(s + (0 .. wcslen(s))); + */ +/*@ +predicate valid_read_nwstring{L}(wchar_t *s, ℤ n) = + (\valid_read(s + (0 .. n - 1)) ∧ \initialized(s + (0 .. n - 1))) ∨ + valid_read_wstring(s); + */ +/*@ +predicate valid_wstring_or_null{L}(wchar_t *s) = + s ≡ \null ∨ valid_wstring(s); + +*/ + diff --git a/tests/basic/oracle/ghost_extern_c.res.oracle b/tests/basic/oracle/ghost_extern_c.res.oracle new file mode 100644 index 0000000000000000000000000000000000000000..a82f884e3cb4106c390bbefdba9a06542697a0fe --- /dev/null +++ b/tests/basic/oracle/ghost_extern_c.res.oracle @@ -0,0 +1,8 @@ +[kernel] Parsing ghost_extern_c.cpp (external front-end) +Now output intermediate result +/* Generated by Frama-C */ +/*@ ghost int ghost_x; */ +int real_x; +/*@ lemma sync{L}: ghost_x ≡ real_x; + */ + diff --git a/tests/basic/oracle/placement_new.res.oracle b/tests/basic/oracle/placement_new.res.oracle index 7404de4d8ea2e13942a395ef7afe0e23289f221b..7e1a1b5555b633a20a637213b53ad36e2e995df5 100644 --- a/tests/basic/oracle/placement_new.res.oracle +++ b/tests/basic/oracle/placement_new.res.oracle @@ -24,6 +24,7 @@ struct _frama_c_rtti_name_info_node { struct _frama_c_vmt *pvmt ; }; typedef unsigned int size_t; +typedef long wchar_t; struct __fc_div_t { int quot ; int rem ; @@ -133,7 +134,7 @@ axiomatic MemChr { ∀ char *s; ∀ ℤ c; ∀ ℤ n; - memchr(s, c, n) ≢ (0 ≢ 0) ⇔ + memchr(s, c, n) ≡ \true ⇔ (∃ int i; 0 ≤ i < n ∧ *(s + i) ≡ c); } @@ -147,7 +148,7 @@ axiomatic MemSet { ∀ char *s; ∀ ℤ c; ∀ ℤ n; - memset(s, c, n) ≢ (0 ≢ 0) ⇔ + memset(s, c, n) ≡ \true ⇔ (∀ ℤ i; 0 ≤ i < n ⇒ *(s + i) ≡ c); } @@ -160,33 +161,33 @@ axiomatic StrLen { axiom strlen_pos_or_null{L}: ∀ char *s; ∀ ℤ i; - 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ (char)0) ∧ - *(s + i) ≡ (char)0 ⇒ strlen(s) ≡ i; + 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ '\000') ∧ + *(s + i) ≡ '\000' ⇒ strlen(s) ≡ i; axiom strlen_neg{L}: ∀ char *s; - (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ (char)0) ⇒ strlen(s) < 0; + (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ '\000') ⇒ strlen(s) < 0; axiom strlen_before_null{L}: ∀ char *s; - ∀ ℤ i; 0 ≤ i < strlen(s) ⇒ *(s + i) ≢ (char)0; + ∀ ℤ i; 0 ≤ i < strlen(s) ⇒ *(s + i) ≢ '\000'; axiom strlen_at_null{L}: - ∀ char *s; 0 ≤ strlen(s) ⇒ *(s + strlen(s)) ≡ (char)0; + ∀ char *s; 0 ≤ strlen(s) ⇒ *(s + strlen(s)) ≡ '\000'; axiom strlen_not_zero{L}: ∀ char *s; ∀ ℤ i; - 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≢ (char)0 ⇒ i < strlen(s); + 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≢ '\000' ⇒ i < strlen(s); axiom strlen_zero{L}: ∀ char *s; ∀ ℤ i; - 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ (char)0 ⇒ i ≡ strlen(s); + 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ '\000' ⇒ i ≡ strlen(s); axiom strlen_sup{L}: ∀ char *s; - ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ (char)0 ⇒ 0 ≤ strlen(s) ≤ i; + ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ '\000' ⇒ 0 ≤ strlen(s) ≤ i; axiom strlen_shift{L}: ∀ char *s; @@ -194,14 +195,13 @@ axiomatic StrLen { axiom strlen_create{L}: ∀ char *s; - ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ (char)0 ⇒ 0 ≤ strlen(s) ≤ i; + ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ '\000' ⇒ 0 ≤ strlen(s) ≤ i; axiom strlen_create_shift{L}: ∀ char *s; ∀ ℤ i; ∀ ℤ k; - 0 ≤ k ≤ i ∧ *(s + i) ≡ (char)0 ⇒ - 0 ≤ strlen(s + k) ≤ i - k; + 0 ≤ k ≤ i ∧ *(s + i) ≡ '\000' ⇒ 0 ≤ strlen(s + k) ≤ i - k; axiom memcmp_strlen_left{L}: ∀ char *s1, char *s2; @@ -264,88 +264,84 @@ axiomatic StrChr { axiom strchr_def{L}: ∀ char *s; ∀ ℤ c; - strchr(s, c) ≢ (0 ≢ 0) ⇔ - (∃ ℤ i; 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ (char)((int)c)); + strchr(s, c) ≡ \true ⇔ + (∃ ℤ i; 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ (char)c); } */ /*@ axiomatic WMemChr { - logic 𔹠wmemchr{L}(long *s, long c, ℤ n) + logic 𔹠wmemchr{L}(wchar_t *s, wchar_t c, ℤ n) reads *(s + (0 .. n - 1)); - logic ℤ wmemchr_off{L}(long *s, long c, ℤ n) + logic ℤ wmemchr_off{L}(wchar_t *s, wchar_t c, ℤ n) reads *(s + (0 .. n - 1)); axiom wmemchr_def{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ long c; ∀ ℤ n; - wmemchr(s, c, n) ≢ (0 ≢ 0) ⇔ + wmemchr(s, c, n) ≡ \true ⇔ (∃ int i; 0 ≤ i < n ∧ *(s + i) ≡ c); } */ /*@ axiomatic WcsLen { - logic ℤ wcslen{L}(long *s) + logic ℤ wcslen{L}(wchar_t *s) reads *(s + (0 ..)); axiom wcslen_pos_or_null{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ ℤ i; - 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ (long)0) ∧ - *(s + i) ≡ (long)0 ⇒ wcslen(s) ≡ i; + 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ 0) ∧ + *(s + i) ≡ 0 ⇒ wcslen(s) ≡ i; axiom wcslen_neg{L}: - ∀ long *s; - (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ (long)0) ⇒ wcslen(s) < 0; + ∀ wchar_t *s; (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ 0) ⇒ wcslen(s) < 0; axiom wcslen_before_null{L}: - ∀ long *s; - ∀ int i; 0 ≤ i < wcslen(s) ⇒ *(s + i) ≢ (long)0; + ∀ wchar_t *s; + ∀ int i; 0 ≤ i < wcslen(s) ⇒ *(s + i) ≢ 0; axiom wcslen_at_null{L}: - ∀ long *s; 0 ≤ wcslen(s) ⇒ *(s + wcslen(s)) ≡ (long)0; + ∀ wchar_t *s; 0 ≤ wcslen(s) ⇒ *(s + wcslen(s)) ≡ 0; axiom wcslen_not_zero{L}: - ∀ long *s; - ∀ int i; - 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≢ (long)0 ⇒ i < wcslen(s); + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≢ 0 ⇒ i < wcslen(s); axiom wcslen_zero{L}: - ∀ long *s; - ∀ int i; - 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≡ (long)0 ⇒ i ≡ wcslen(s); + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≡ 0 ⇒ i ≡ wcslen(s); axiom wcslen_sup{L}: - ∀ long *s; - ∀ int i; 0 ≤ i ∧ *(s + i) ≡ (long)0 ⇒ 0 ≤ wcslen(s) ≤ i; + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ∧ *(s + i) ≡ 0 ⇒ 0 ≤ wcslen(s) ≤ i; axiom wcslen_shift{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ int i; 0 ≤ i ≤ wcslen(s) ⇒ wcslen(s + i) ≡ wcslen(s) - i; axiom wcslen_create{L}: - ∀ long *s; - ∀ int i; 0 ≤ i ∧ *(s + i) ≡ (long)0 ⇒ 0 ≤ wcslen(s) ≤ i; + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ∧ *(s + i) ≡ 0 ⇒ 0 ≤ wcslen(s) ≤ i; axiom wcslen_create_shift{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ int i; ∀ int k; - 0 ≤ k ≤ i ∧ *(s + i) ≡ (long)0 ⇒ - 0 ≤ wcslen(s + k) ≤ i - k; + 0 ≤ k ≤ i ∧ *(s + i) ≡ 0 ⇒ 0 ≤ wcslen(s + k) ≤ i - k; } */ /*@ axiomatic WcsCmp { - logic ℤ wcscmp{L}(long *s1, long *s2) + logic ℤ wcscmp{L}(wchar_t *s1, wchar_t *s2) reads *(s1 + (0 .. wcslen(s1))), *(s2 + (0 .. wcslen(s2))); axiom wcscmp_zero{L}: - ∀ long *s1, long *s2; + ∀ wchar_t *s1, wchar_t *s2; wcscmp(s1, s2) ≡ 0 ⇔ wcslen(s1) ≡ wcslen(s2) ∧ (∀ ℤ i; 0 ≤ i ≤ wcslen(s1) ⇒ *(s1 + i) ≡ *(s2 + i)); @@ -354,11 +350,11 @@ axiomatic WcsCmp { */ /*@ axiomatic WcsNCmp { - logic ℤ wcsncmp{L}(long *s1, long *s2, ℤ n) + logic ℤ wcsncmp{L}(wchar_t *s1, wchar_t *s2, ℤ n) reads *(s1 + (0 .. n - 1)), *(s2 + (0 .. n - 1)); axiom wcsncmp_zero{L}: - ∀ long *s1, long *s2; + ∀ wchar_t *s1, wchar_t *s2; ∀ ℤ n; wcsncmp(s1, s2, n) ≡ 0 ⇔ (wcslen(s1) < n ∧ wcscmp(s1, s2) ≡ 0) ∨ @@ -368,14 +364,14 @@ axiomatic WcsNCmp { */ /*@ axiomatic WcsChr { - logic 𔹠wcschr{L}(long *wcs, ℤ wc) + logic 𔹠wcschr{L}(wchar_t *wcs, ℤ wc) reads *(wcs + (0 .. wcslen(wcs))); axiom wcschr_def{L}: - ∀ long *wcs; + ∀ wchar_t *wcs; ∀ ℤ wc; - wcschr(wcs, wc) ≢ (0 ≢ 0) ⇔ - (∃ ℤ i; 0 ≤ i ≤ wcslen(wcs) ∧ *(wcs + i) ≡ (long)((int)wc)); + wcschr(wcs, wc) ≡ \true ⇔ + (∃ ℤ i; 0 ≤ i ≤ wcslen(wcs) ∧ *(wcs + i) ≡ (wchar_t)wc); } */ @@ -400,20 +396,20 @@ predicate valid_read_nstring{L}(char *s, ℤ n) = predicate valid_string_or_null{L}(char *s) = s ≡ \null ∨ valid_string(s); */ /*@ -predicate valid_wstring{L}(long *s) = +predicate valid_wstring{L}(wchar_t *s) = 0 ≤ wcslen(s) ∧ \valid(s + (0 .. wcslen(s))); */ /*@ -predicate valid_read_wstring{L}(long *s) = +predicate valid_read_wstring{L}(wchar_t *s) = 0 ≤ wcslen(s) ∧ \valid_read(s + (0 .. wcslen(s))); */ /*@ -predicate valid_read_nwstring{L}(long *s, ℤ n) = +predicate valid_read_nwstring{L}(wchar_t *s, ℤ n) = (\valid_read(s + (0 .. n - 1)) ∧ \initialized(s + (0 .. n - 1))) ∨ valid_read_wstring(s); */ /*@ -predicate valid_wstring_or_null{L}(long *s) = +predicate valid_wstring_or_null{L}(wchar_t *s) = s ≡ \null ∨ valid_wstring(s); */ /*@ requires valid_nptr: \valid_read(nptr); @@ -705,7 +701,7 @@ unsigned short *__fc_p_random48_counter = __fc_random48_counter; void srand48(long seed); /*@ requires - initialized_seed16v: initialization: \initialized(seed16v + (0 .. 2)); + initialization: initialized_seed16v: \initialized(seed16v + (0 .. 2)); ensures random48_initialized: __fc_random48_init ≡ 1; ensures result_counter: \result ≡ __fc_p_random48_counter; assigns __fc_random48_counter[0 .. 2], __fc_random48_init, \result; @@ -733,7 +729,7 @@ void lcong48(unsigned short param[7]); double drand48(void); /*@ requires - initialized_xsubi: initialization: \initialized(xsubi + (0 .. 2)); + initialization: initialized_xsubi: \initialized(xsubi + (0 .. 2)); ensures result_range: \is_finite(\result) ∧ 0.0 ≤ \result < 1.0; assigns __fc_random48_counter[0 .. 2], \result; assigns __fc_random48_counter[0 .. 2] @@ -752,7 +748,7 @@ double erand48(unsigned short xsubi[3]); long lrand48(void); /*@ requires - initialized_xsubi: initialization: \initialized(xsubi + (0 .. 2)); + initialization: initialized_xsubi: \initialized(xsubi + (0 .. 2)); ensures result_range: 0 ≤ \result < 2147483648; assigns __fc_random48_counter[0 .. 2], \result; assigns __fc_random48_counter[0 .. 2] @@ -771,7 +767,7 @@ long nrand48(unsigned short xsubi[3]); long mrand48(void); /*@ requires - initialized_xsubi: initialization: \initialized(xsubi + (0 .. 2)); + initialization: initialized_xsubi: \initialized(xsubi + (0 .. 2)); ensures result_range: -2147483648 ≤ \result < 2147483648; assigns __fc_random48_counter[0 .. 2], \result; assigns __fc_random48_counter[0 .. 2] @@ -1075,7 +1071,7 @@ int mblen(char const *s, size_t n); \from (indirect: s), *(s + (0 .. n - 1)), (indirect: n), __fc_mbtowc_state; */ -int mbtowc(long * restrict pwc, char const * restrict s, size_t n); +int mbtowc(wchar_t * restrict pwc, char const * restrict s, size_t n); /*@ ghost int __fc_wctomb_state; */ /*@ assigns \result, *(s + (0 ..)), __fc_wctomb_state; @@ -1083,7 +1079,7 @@ int mbtowc(long * restrict pwc, char const * restrict s, size_t n); assigns *(s + (0 ..)) \from wc, __fc_wctomb_state; assigns __fc_wctomb_state \from wc, __fc_wctomb_state; */ -int wctomb(char *s, long wc); +int wctomb(char *s, wchar_t wc); /*@ requires separation: \separated(pwcs, s); assigns \result, *(pwcs + (0 .. n - 1)); @@ -1092,7 +1088,7 @@ int wctomb(char *s, long wc); assigns *(pwcs + (0 .. n - 1)) \from (indirect: s), *(s + (0 .. n - 1)), (indirect: n); */ -size_t mbstowcs(long * restrict pwcs, char const * restrict s, size_t n); +size_t mbstowcs(wchar_t * restrict pwcs, char const * restrict s, size_t n); /*@ requires separation: \separated(s, pwcs); assigns \result, *(s + (0 .. n - 1)); @@ -1102,12 +1098,13 @@ size_t mbstowcs(long * restrict pwcs, char const * restrict s, size_t n); assigns *(s + (0 .. n - 1)) \from (indirect: pwcs), *(pwcs + (0 .. n - 1)), (indirect: n); */ -size_t wcstombs(char * restrict s, long const * restrict pwcs, size_t n); +size_t wcstombs(char * restrict s, wchar_t const * restrict pwcs, size_t n); /*@ requires valid_memptr: \valid(memptr); requires alignment_is_a_suitable_power_of_two: - alignment ≥ sizeof(void *) ∧ (alignment & alignment - 1) ≡ 0; + alignment ≥ sizeof(void *) ∧ + ((size_t)alignment & (size_t)alignment - 1) ≡ 0; assigns __fc_heap_status, \result; assigns __fc_heap_status \from (indirect: alignment), size, __fc_heap_status; diff --git a/tests/basic/oracle/placement_newb.res.oracle b/tests/basic/oracle/placement_newb.res.oracle index a12fa44c50c296a6e43f0884f0f45048e14df710..9a45df60bf414465446e3b3f8936b0cc0f519fdb 100644 --- a/tests/basic/oracle/placement_newb.res.oracle +++ b/tests/basic/oracle/placement_newb.res.oracle @@ -2,6 +2,7 @@ Now output intermediate result /* Generated by Frama-C */ typedef unsigned int size_t; +typedef long wchar_t; struct __fc_div_t { int quot ; int rem ; @@ -102,7 +103,7 @@ axiomatic MemChr { ∀ char *s; ∀ ℤ c; ∀ ℤ n; - memchr(s, c, n) ≢ (0 ≢ 0) ⇔ + memchr(s, c, n) ≡ \true ⇔ (∃ int i; 0 ≤ i < n ∧ *(s + i) ≡ c); } @@ -116,7 +117,7 @@ axiomatic MemSet { ∀ char *s; ∀ ℤ c; ∀ ℤ n; - memset(s, c, n) ≢ (0 ≢ 0) ⇔ + memset(s, c, n) ≡ \true ⇔ (∀ ℤ i; 0 ≤ i < n ⇒ *(s + i) ≡ c); } @@ -129,33 +130,33 @@ axiomatic StrLen { axiom strlen_pos_or_null{L}: ∀ char *s; ∀ ℤ i; - 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ (char)0) ∧ - *(s + i) ≡ (char)0 ⇒ strlen(s) ≡ i; + 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ '\000') ∧ + *(s + i) ≡ '\000' ⇒ strlen(s) ≡ i; axiom strlen_neg{L}: ∀ char *s; - (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ (char)0) ⇒ strlen(s) < 0; + (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ '\000') ⇒ strlen(s) < 0; axiom strlen_before_null{L}: ∀ char *s; - ∀ ℤ i; 0 ≤ i < strlen(s) ⇒ *(s + i) ≢ (char)0; + ∀ ℤ i; 0 ≤ i < strlen(s) ⇒ *(s + i) ≢ '\000'; axiom strlen_at_null{L}: - ∀ char *s; 0 ≤ strlen(s) ⇒ *(s + strlen(s)) ≡ (char)0; + ∀ char *s; 0 ≤ strlen(s) ⇒ *(s + strlen(s)) ≡ '\000'; axiom strlen_not_zero{L}: ∀ char *s; ∀ ℤ i; - 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≢ (char)0 ⇒ i < strlen(s); + 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≢ '\000' ⇒ i < strlen(s); axiom strlen_zero{L}: ∀ char *s; ∀ ℤ i; - 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ (char)0 ⇒ i ≡ strlen(s); + 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ '\000' ⇒ i ≡ strlen(s); axiom strlen_sup{L}: ∀ char *s; - ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ (char)0 ⇒ 0 ≤ strlen(s) ≤ i; + ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ '\000' ⇒ 0 ≤ strlen(s) ≤ i; axiom strlen_shift{L}: ∀ char *s; @@ -163,14 +164,13 @@ axiomatic StrLen { axiom strlen_create{L}: ∀ char *s; - ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ (char)0 ⇒ 0 ≤ strlen(s) ≤ i; + ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ '\000' ⇒ 0 ≤ strlen(s) ≤ i; axiom strlen_create_shift{L}: ∀ char *s; ∀ ℤ i; ∀ ℤ k; - 0 ≤ k ≤ i ∧ *(s + i) ≡ (char)0 ⇒ - 0 ≤ strlen(s + k) ≤ i - k; + 0 ≤ k ≤ i ∧ *(s + i) ≡ '\000' ⇒ 0 ≤ strlen(s + k) ≤ i - k; axiom memcmp_strlen_left{L}: ∀ char *s1, char *s2; @@ -233,88 +233,84 @@ axiomatic StrChr { axiom strchr_def{L}: ∀ char *s; ∀ ℤ c; - strchr(s, c) ≢ (0 ≢ 0) ⇔ - (∃ ℤ i; 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ (char)((int)c)); + strchr(s, c) ≡ \true ⇔ + (∃ ℤ i; 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ (char)c); } */ /*@ axiomatic WMemChr { - logic 𔹠wmemchr{L}(long *s, long c, ℤ n) + logic 𔹠wmemchr{L}(wchar_t *s, wchar_t c, ℤ n) reads *(s + (0 .. n - 1)); - logic ℤ wmemchr_off{L}(long *s, long c, ℤ n) + logic ℤ wmemchr_off{L}(wchar_t *s, wchar_t c, ℤ n) reads *(s + (0 .. n - 1)); axiom wmemchr_def{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ long c; ∀ ℤ n; - wmemchr(s, c, n) ≢ (0 ≢ 0) ⇔ + wmemchr(s, c, n) ≡ \true ⇔ (∃ int i; 0 ≤ i < n ∧ *(s + i) ≡ c); } */ /*@ axiomatic WcsLen { - logic ℤ wcslen{L}(long *s) + logic ℤ wcslen{L}(wchar_t *s) reads *(s + (0 ..)); axiom wcslen_pos_or_null{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ ℤ i; - 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ (long)0) ∧ - *(s + i) ≡ (long)0 ⇒ wcslen(s) ≡ i; + 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ 0) ∧ + *(s + i) ≡ 0 ⇒ wcslen(s) ≡ i; axiom wcslen_neg{L}: - ∀ long *s; - (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ (long)0) ⇒ wcslen(s) < 0; + ∀ wchar_t *s; (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ 0) ⇒ wcslen(s) < 0; axiom wcslen_before_null{L}: - ∀ long *s; - ∀ int i; 0 ≤ i < wcslen(s) ⇒ *(s + i) ≢ (long)0; + ∀ wchar_t *s; + ∀ int i; 0 ≤ i < wcslen(s) ⇒ *(s + i) ≢ 0; axiom wcslen_at_null{L}: - ∀ long *s; 0 ≤ wcslen(s) ⇒ *(s + wcslen(s)) ≡ (long)0; + ∀ wchar_t *s; 0 ≤ wcslen(s) ⇒ *(s + wcslen(s)) ≡ 0; axiom wcslen_not_zero{L}: - ∀ long *s; - ∀ int i; - 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≢ (long)0 ⇒ i < wcslen(s); + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≢ 0 ⇒ i < wcslen(s); axiom wcslen_zero{L}: - ∀ long *s; - ∀ int i; - 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≡ (long)0 ⇒ i ≡ wcslen(s); + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≡ 0 ⇒ i ≡ wcslen(s); axiom wcslen_sup{L}: - ∀ long *s; - ∀ int i; 0 ≤ i ∧ *(s + i) ≡ (long)0 ⇒ 0 ≤ wcslen(s) ≤ i; + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ∧ *(s + i) ≡ 0 ⇒ 0 ≤ wcslen(s) ≤ i; axiom wcslen_shift{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ int i; 0 ≤ i ≤ wcslen(s) ⇒ wcslen(s + i) ≡ wcslen(s) - i; axiom wcslen_create{L}: - ∀ long *s; - ∀ int i; 0 ≤ i ∧ *(s + i) ≡ (long)0 ⇒ 0 ≤ wcslen(s) ≤ i; + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ∧ *(s + i) ≡ 0 ⇒ 0 ≤ wcslen(s) ≤ i; axiom wcslen_create_shift{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ int i; ∀ int k; - 0 ≤ k ≤ i ∧ *(s + i) ≡ (long)0 ⇒ - 0 ≤ wcslen(s + k) ≤ i - k; + 0 ≤ k ≤ i ∧ *(s + i) ≡ 0 ⇒ 0 ≤ wcslen(s + k) ≤ i - k; } */ /*@ axiomatic WcsCmp { - logic ℤ wcscmp{L}(long *s1, long *s2) + logic ℤ wcscmp{L}(wchar_t *s1, wchar_t *s2) reads *(s1 + (0 .. wcslen(s1))), *(s2 + (0 .. wcslen(s2))); axiom wcscmp_zero{L}: - ∀ long *s1, long *s2; + ∀ wchar_t *s1, wchar_t *s2; wcscmp(s1, s2) ≡ 0 ⇔ wcslen(s1) ≡ wcslen(s2) ∧ (∀ ℤ i; 0 ≤ i ≤ wcslen(s1) ⇒ *(s1 + i) ≡ *(s2 + i)); @@ -323,11 +319,11 @@ axiomatic WcsCmp { */ /*@ axiomatic WcsNCmp { - logic ℤ wcsncmp{L}(long *s1, long *s2, ℤ n) + logic ℤ wcsncmp{L}(wchar_t *s1, wchar_t *s2, ℤ n) reads *(s1 + (0 .. n - 1)), *(s2 + (0 .. n - 1)); axiom wcsncmp_zero{L}: - ∀ long *s1, long *s2; + ∀ wchar_t *s1, wchar_t *s2; ∀ ℤ n; wcsncmp(s1, s2, n) ≡ 0 ⇔ (wcslen(s1) < n ∧ wcscmp(s1, s2) ≡ 0) ∨ @@ -337,14 +333,14 @@ axiomatic WcsNCmp { */ /*@ axiomatic WcsChr { - logic 𔹠wcschr{L}(long *wcs, ℤ wc) + logic 𔹠wcschr{L}(wchar_t *wcs, ℤ wc) reads *(wcs + (0 .. wcslen(wcs))); axiom wcschr_def{L}: - ∀ long *wcs; + ∀ wchar_t *wcs; ∀ ℤ wc; - wcschr(wcs, wc) ≢ (0 ≢ 0) ⇔ - (∃ ℤ i; 0 ≤ i ≤ wcslen(wcs) ∧ *(wcs + i) ≡ (long)((int)wc)); + wcschr(wcs, wc) ≡ \true ⇔ + (∃ ℤ i; 0 ≤ i ≤ wcslen(wcs) ∧ *(wcs + i) ≡ (wchar_t)wc); } */ @@ -369,20 +365,20 @@ predicate valid_read_nstring{L}(char *s, ℤ n) = predicate valid_string_or_null{L}(char *s) = s ≡ \null ∨ valid_string(s); */ /*@ -predicate valid_wstring{L}(long *s) = +predicate valid_wstring{L}(wchar_t *s) = 0 ≤ wcslen(s) ∧ \valid(s + (0 .. wcslen(s))); */ /*@ -predicate valid_read_wstring{L}(long *s) = +predicate valid_read_wstring{L}(wchar_t *s) = 0 ≤ wcslen(s) ∧ \valid_read(s + (0 .. wcslen(s))); */ /*@ -predicate valid_read_nwstring{L}(long *s, ℤ n) = +predicate valid_read_nwstring{L}(wchar_t *s, ℤ n) = (\valid_read(s + (0 .. n - 1)) ∧ \initialized(s + (0 .. n - 1))) ∨ valid_read_wstring(s); */ /*@ -predicate valid_wstring_or_null{L}(long *s) = +predicate valid_wstring_or_null{L}(wchar_t *s) = s ≡ \null ∨ valid_wstring(s); */ /*@ requires valid_nptr: \valid_read(nptr); @@ -674,7 +670,7 @@ unsigned short *__fc_p_random48_counter = __fc_random48_counter; void srand48(long seed); /*@ requires - initialized_seed16v: initialization: \initialized(seed16v + (0 .. 2)); + initialization: initialized_seed16v: \initialized(seed16v + (0 .. 2)); ensures random48_initialized: __fc_random48_init ≡ 1; ensures result_counter: \result ≡ __fc_p_random48_counter; assigns __fc_random48_counter[0 .. 2], __fc_random48_init, \result; @@ -702,7 +698,7 @@ void lcong48(unsigned short param[7]); double drand48(void); /*@ requires - initialized_xsubi: initialization: \initialized(xsubi + (0 .. 2)); + initialization: initialized_xsubi: \initialized(xsubi + (0 .. 2)); ensures result_range: \is_finite(\result) ∧ 0.0 ≤ \result < 1.0; assigns __fc_random48_counter[0 .. 2], \result; assigns __fc_random48_counter[0 .. 2] @@ -721,7 +717,7 @@ double erand48(unsigned short xsubi[3]); long lrand48(void); /*@ requires - initialized_xsubi: initialization: \initialized(xsubi + (0 .. 2)); + initialization: initialized_xsubi: \initialized(xsubi + (0 .. 2)); ensures result_range: 0 ≤ \result < 2147483648; assigns __fc_random48_counter[0 .. 2], \result; assigns __fc_random48_counter[0 .. 2] @@ -740,7 +736,7 @@ long nrand48(unsigned short xsubi[3]); long mrand48(void); /*@ requires - initialized_xsubi: initialization: \initialized(xsubi + (0 .. 2)); + initialization: initialized_xsubi: \initialized(xsubi + (0 .. 2)); ensures result_range: -2147483648 ≤ \result < 2147483648; assigns __fc_random48_counter[0 .. 2], \result; assigns __fc_random48_counter[0 .. 2] @@ -1044,7 +1040,7 @@ int mblen(char const *s, size_t n); \from (indirect: s), *(s + (0 .. n - 1)), (indirect: n), __fc_mbtowc_state; */ -int mbtowc(long * restrict pwc, char const * restrict s, size_t n); +int mbtowc(wchar_t * restrict pwc, char const * restrict s, size_t n); /*@ ghost int __fc_wctomb_state; */ /*@ assigns \result, *(s + (0 ..)), __fc_wctomb_state; @@ -1052,7 +1048,7 @@ int mbtowc(long * restrict pwc, char const * restrict s, size_t n); assigns *(s + (0 ..)) \from wc, __fc_wctomb_state; assigns __fc_wctomb_state \from wc, __fc_wctomb_state; */ -int wctomb(char *s, long wc); +int wctomb(char *s, wchar_t wc); /*@ requires separation: \separated(pwcs, s); assigns \result, *(pwcs + (0 .. n - 1)); @@ -1061,7 +1057,7 @@ int wctomb(char *s, long wc); assigns *(pwcs + (0 .. n - 1)) \from (indirect: s), *(s + (0 .. n - 1)), (indirect: n); */ -size_t mbstowcs(long * restrict pwcs, char const * restrict s, size_t n); +size_t mbstowcs(wchar_t * restrict pwcs, char const * restrict s, size_t n); /*@ requires separation: \separated(s, pwcs); assigns \result, *(s + (0 .. n - 1)); @@ -1071,12 +1067,13 @@ size_t mbstowcs(long * restrict pwcs, char const * restrict s, size_t n); assigns *(s + (0 .. n - 1)) \from (indirect: pwcs), *(pwcs + (0 .. n - 1)), (indirect: n); */ -size_t wcstombs(char * restrict s, long const * restrict pwcs, size_t n); +size_t wcstombs(char * restrict s, wchar_t const * restrict pwcs, size_t n); /*@ requires valid_memptr: \valid(memptr); requires alignment_is_a_suitable_power_of_two: - alignment ≥ sizeof(void *) ∧ (alignment & alignment - 1) ≡ 0; + alignment ≥ sizeof(void *) ∧ + ((size_t)alignment & (size_t)alignment - 1) ≡ 0; assigns __fc_heap_status, \result; assigns __fc_heap_status \from (indirect: alignment), size, __fc_heap_status; diff --git a/tests/class/extern_c_class.cpp b/tests/class/extern_c_class.cpp new file mode 100644 index 0000000000000000000000000000000000000000..14aa138321062005f75db113977d452c1d4d4760 --- /dev/null +++ b/tests/class/extern_c_class.cpp @@ -0,0 +1,7 @@ +extern "C"{ + class C { + void set(int* t) { *t = get_x(); foo(); } + int get_x() { return 0; } + virtual void foo(); + }; +} diff --git a/tests/class/oracle/extern_c_class.res.oracle b/tests/class/oracle/extern_c_class.res.oracle new file mode 100644 index 0000000000000000000000000000000000000000..900abea7d405005a2a08a4af3b4e6bd23aae9488 --- /dev/null +++ b/tests/class/oracle/extern_c_class.res.oracle @@ -0,0 +1,284 @@ +[kernel] Parsing extern_c_class.cpp (external front-end) +Now output intermediate result +/* Generated by Frama-C */ +struct _frama_c_vmt_content { + void (*method_ptr)() ; + int shift_this ; +}; +struct _frama_c_rtti_name_info_node; +struct _frama_c_vmt { + struct _frama_c_vmt_content *table ; + int table_size ; + struct _frama_c_rtti_name_info_node *rtti_info ; +}; +struct _frama_c_rtti_name_info_content { + struct _frama_c_rtti_name_info_node *value ; + int shift_object ; + int shift_vmt ; +}; +struct _frama_c_rtti_name_info_node { + char const *name ; + struct _frama_c_rtti_name_info_content *base_classes ; + int number_of_base_classes ; + struct _frama_c_vmt *pvmt ; +}; +struct C; +struct C { + struct _frama_c_vmt *pvmt ; +}; +struct _frama_c_vmt _frama_c_vmt_header; + +struct _frama_c_rtti_name_info_node _frama_c_rtti_name_info; + +struct _frama_c_vmt_content _frama_c_vmt[1]; + +void set(struct C *this, int *t); + +int get_x(struct C *this); + +/*@ requires \valid(this); */ +void set(struct C *this, int *t) +{ + *t = get_x(this); + struct _frama_c_vmt_content *__virtual_tmp_0 = + (*((struct _frama_c_vmt **)this))->table + 0; + (*((void (*)(struct C *))__virtual_tmp_0->method_ptr))((struct C *)( + (char *)this - __virtual_tmp_0->shift_this)); + return; +} + +int _frama_c_find_dynamic_cast_aux(struct _frama_c_rtti_name_info_node *target_info, + struct _frama_c_rtti_name_info_content *concrete_base, + int number_of_bases, + int found_shift_object, + int found_shift_vmt, int last_shift_vmt, + int *shift_object, int *distance) +{ + int result = 0; + struct _frama_c_rtti_name_info_content *cursor = concrete_base; + int is_over = 0; + int base_index = 0; + while (base_index < number_of_bases) { + if (cursor->value == target_info) { + if (*distance < 0) goto _LOR; + else + if (*distance >= 1) { + _LOR: + { + if (found_shift_vmt == cursor->shift_vmt) *distance = 0; + else *distance = 1; + *shift_object = found_shift_object - cursor->shift_object; + result = 1; + } + } + } + else + if (cursor->shift_vmt <= found_shift_vmt) { + int tmp_5; + if (base_index < number_of_bases - 1) tmp_5 = (cursor + 1)->shift_vmt > found_shift_vmt; + else { + int tmp_4; + if (last_shift_vmt == -1) tmp_4 = 1; + else + if (found_shift_vmt < last_shift_vmt) tmp_4 = 1; else tmp_4 = 0; + tmp_5 = tmp_4; + } + if (tmp_5) { + int tmp_0; + int tmp; + int local_distance = 0; + int local_shift_object = 0; + if (base_index < number_of_bases - 1) tmp = (cursor + 1)->shift_vmt; + else tmp = last_shift_vmt; + ; + ; + ; + ; + ; + tmp_0 = _frama_c_find_dynamic_cast_aux(target_info, + (cursor->value)->base_classes, + (cursor->value)->number_of_base_classes, + found_shift_object - cursor->shift_object, + found_shift_vmt - cursor->shift_vmt, + tmp,& local_shift_object, + & local_distance); + int local_result = tmp_0; + if (local_result != 0) + if (local_distance >= 0) + if (*distance < 0) goto _LOR_0; + else + if (*distance >= local_distance) { + _LOR_0: + { + result = local_result; + *shift_object = local_shift_object - cursor->shift_object; + *distance = local_distance; + } + } + is_over = 1; + } + else goto _LAND; + } + else { + _LAND: ; + if (*distance < 0) goto _LOR_2; + else + if (*distance >= 1) { + _LOR_2: + { + int tmp_2; + int tmp_1; + int local_distance_0 = 0; + int local_shift_object_0 = 0; + if (base_index < number_of_bases + 1) tmp_1 = (cursor + 1)->shift_vmt; + else tmp_1 = last_shift_vmt; + ; + ; + ; + ; + ; + tmp_2 = _frama_c_find_dynamic_cast_aux(target_info, + (cursor->value)->base_classes, + (cursor->value)->number_of_base_classes, + found_shift_object - cursor->shift_object, + found_shift_vmt - cursor->shift_vmt, + tmp_1, + & local_shift_object_0, + & local_distance_0); + int local_result_0 = tmp_2; + if (local_result_0 != 0) + if (local_distance_0 >= 0) + if (*distance < 0) goto _LOR_1; + else { + int tmp_3; + if (is_over == 0) tmp_3 = local_distance_0; + else tmp_3 = local_distance_0 + 1; + ; + if (*distance > tmp_3) { + _LOR_1: + { + result = local_result_0; + *shift_object = local_shift_object_0 - cursor->shift_object; + *distance = local_distance_0 + 1; + } + } + } + } + } + } + cursor ++; + base_index ++; + } + return result; +} + +int _frama_c_find_dynamic_cast(struct _frama_c_rtti_name_info_node *declared_info, + struct _frama_c_vmt *declared_vmt, + struct _frama_c_rtti_name_info_node *target_info, + int *shift_object) +{ + int __retres; + int shift_vmt; + int elaborated_shift_target; + struct _frama_c_rtti_name_info_content *cursor; + int number_of_bases; + int tmp_0; + struct _frama_c_rtti_name_info_node *concrete_info = + declared_vmt->rtti_info; + int elaborated_shift_vmt = 0; + int elaborated_shift_object = 0; + int cursor_index = 0; + int distance = -1; + if (concrete_info->pvmt > declared_vmt) { + __retres = 0; + goto return_label; + } + else + if (declared_vmt > concrete_info->pvmt + declared_vmt->table_size) { + __retres = 0; + goto return_label; + } + shift_vmt = declared_vmt - concrete_info->pvmt; + if (concrete_info == declared_info) { + *shift_object = 0; + __retres = target_info == declared_info; + goto return_label; + } + if (target_info == concrete_info) elaborated_shift_target = 0; + else elaborated_shift_target = -1; + cursor = concrete_info->base_classes; + number_of_bases = concrete_info->number_of_base_classes; + while (1) { + while (1) { + if (cursor_index < number_of_bases) { + if (! (elaborated_shift_vmt + cursor->shift_vmt < shift_vmt)) + break; + } + else break; + { + struct _frama_c_rtti_name_info_content *tmp; + if (cursor_index < number_of_bases - 1) tmp = cursor + 1; + else tmp = (struct _frama_c_rtti_name_info_content *)0; + struct _frama_c_rtti_name_info_content *next_cursor = tmp; + if (next_cursor != (struct _frama_c_rtti_name_info_content *)0) + if (elaborated_shift_vmt + next_cursor->shift_vmt <= shift_vmt) { + cursor = next_cursor; + cursor_index ++; + } + else break; + else break; + } + } + if (cursor_index < number_of_bases) { + elaborated_shift_vmt += cursor->shift_vmt; + elaborated_shift_object += cursor->shift_object; + if (cursor->value == target_info) elaborated_shift_target = elaborated_shift_object; + if (elaborated_shift_vmt == shift_vmt) + if (cursor->value == declared_info) { + if (elaborated_shift_target >= 0) { + *shift_object = elaborated_shift_target - elaborated_shift_object; + __retres = 1; + goto return_label; + } + break; + } + cursor = (cursor->value)->base_classes; + number_of_bases = (cursor->value)->number_of_base_classes; + cursor_index = 0; + } + if (! (cursor_index < number_of_bases)) break; + } + if (cursor_index >= number_of_bases) { + __retres = 0; + goto return_label; + } + tmp_0 = _frama_c_find_dynamic_cast_aux(target_info, + concrete_info->base_classes, + concrete_info->number_of_base_classes, + elaborated_shift_object,shift_vmt, + -1,shift_object,& distance); + __retres = tmp_0; + return_label: return __retres; +} + +void foo(struct C *this); + +struct _frama_c_vmt_content _frama_c_vmt[1] = + {{.method_ptr = (void (*)())(& foo), .shift_this = 0}}; +struct _frama_c_rtti_name_info_node _frama_c_rtti_name_info = + {.name = "C", + .base_classes = (struct _frama_c_rtti_name_info_content *)0, + .number_of_base_classes = 0, + .pvmt = & _frama_c_vmt_header}; +struct _frama_c_vmt _frama_c_vmt_header = + {.table = _frama_c_vmt, + .table_size = 1, + .rtti_info = & _frama_c_rtti_name_info}; +int get_x(struct C *this) +{ + int __retres; + __retres = 0; + return __retres; +} + + diff --git a/tests/specs/cxx_c_acsl.c b/tests/specs/cxx_c_acsl.c new file mode 100644 index 0000000000000000000000000000000000000000..30d915ede2cdf1bf490bbf79c47cafb7e14b8e2a --- /dev/null +++ b/tests/specs/cxx_c_acsl.c @@ -0,0 +1,13 @@ +/* run.config +DONTRUN: main test is the .cpp file +*/ + +//@ predicate test1(double x) = \is_finite(x) && 0.0 < x && x < 2.0; + +//@ predicate test2(double x) = \is_finite(x) && 0.0 < x < 2.0; + +//@ predicate test3(double x) = (\is_finite(x) && 0.0 < x) && x < 2.0; + +//@ predicate test4(double x) = \is_finite(x) && (0.0 < x && x < 2.0); + +//@ predicate test5(double x) = (\is_finite(x) && 0.0 < x) && (x < 2.0 && \is_finite(x)); diff --git a/tests/specs/cxx_c_acsl.cpp b/tests/specs/cxx_c_acsl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c7cec0e24d0d2b1827b82e8ea5c8c0f7fdcf9ac3 --- /dev/null +++ b/tests/specs/cxx_c_acsl.cpp @@ -0,0 +1,6 @@ +/* run.config +OPT: %{dep:@PTEST_DIR@/@PTEST_NAME@.c} -print +*/ +extern "C" { +#include "cxx_c_acsl.c" +} diff --git a/tests/specs/oracle/basic.res.oracle b/tests/specs/oracle/basic.res.oracle index 2de5b3b93c9d5a72f7c1c8ecd4b9869ffdb189a1..a92d6f6db2c1fd896d5fac8202416c04b7e57dad 100644 --- a/tests/specs/oracle/basic.res.oracle +++ b/tests/specs/oracle/basic.res.oracle @@ -1,6 +1,6 @@ [kernel] Parsing basic.cpp (external front-end) Now output intermediate result /* Generated by Frama-C */ -/*@ lemma test_char: (char)0 ≢ (char)97; +/*@ lemma test_char: '\000' ≢ 'a'; */ diff --git a/tests/specs/oracle/cxx_c_acsl.res.oracle b/tests/specs/oracle/cxx_c_acsl.res.oracle new file mode 100644 index 0000000000000000000000000000000000000000..135f9fd837a8a1cd7906bc983d6efbe26d550342 --- /dev/null +++ b/tests/specs/oracle/cxx_c_acsl.res.oracle @@ -0,0 +1,17 @@ +[kernel] Parsing cxx_c_acsl.cpp (external front-end) +Now output intermediate result +[kernel] Parsing cxx_c_acsl.c (with preprocessing) +/* Generated by Frama-C */ +/*@ predicate test1(double x) = \is_finite(x) ∧ 0.0 < x < 2.0; + */ +/*@ predicate test2(double x) = \is_finite(x) ∧ 0.0 < x < 2.0; + */ +/*@ predicate test3(double x) = \is_finite(x) ∧ 0.0 < x < 2.0; + */ +/*@ predicate test4(double x) = \is_finite(x) ∧ 0.0 < x < 2.0; + */ +/*@ +predicate test5(double x) = + \is_finite(x) ∧ 0.0 < x < 2.0 ∧ \is_finite(x); + */ + diff --git a/tests/specs/oracle/logic.res.oracle b/tests/specs/oracle/logic.res.oracle index 7d8efbcd699da9c9e90aeb9f54caee9d7da8f194..6807083f8fc3ecbf84481027efe07d7fa9a51e4d 100644 --- a/tests/specs/oracle/logic.res.oracle +++ b/tests/specs/oracle/logic.res.oracle @@ -17,7 +17,7 @@ lemma f_def{L}: */ /*@ lemma f_inf: ∀ int x; 0 < x ≤ f(x); */ -/*@ logic long long g(long long x) = (long long)((int)(x - 1)); +/*@ logic long long g(long long x) = (long long)(x - 1); */ /*@ behavior default: ensures \result ≡ f(\old(x)); */ diff --git a/tests/specs/oracle/logic_defs.res.oracle b/tests/specs/oracle/logic_defs.res.oracle index 609fc25c2c0350579a409117bf2fc21a4b89575a..03bdce44fe63d1a40b1c6fc2437753a443c0cc53 100644 --- a/tests/specs/oracle/logic_defs.res.oracle +++ b/tests/specs/oracle/logic_defs.res.oracle @@ -54,9 +54,7 @@ struct _frama_c_rtti_name_info_node _frama_c_rtti_name_info = /*@ logic 𔹠test5(int a, struct A b) = a ≡ b.x; */ /*@ -lemma foo: - ∀ int a; - ∀ struct A b; test(a, b) ⇔ test5(a, b) ≢ (0 ≢ 0); +lemma foo: ∀ int a; ∀ struct A b; test(a, b) ⇔ test5(a, b) ≡ \true; */ int main(void) diff --git a/tests/specs/oracle/wchar_t.res.oracle b/tests/specs/oracle/wchar_t.res.oracle index 351afe930821eef0911613a67ddd4a86301b653e..942aac0eb71929122f14a660400add29964fdf94 100644 --- a/tests/specs/oracle/wchar_t.res.oracle +++ b/tests/specs/oracle/wchar_t.res.oracle @@ -1,13 +1,14 @@ [kernel] Parsing wchar_t.cpp (external front-end) Now output intermediate result /* Generated by Frama-C */ -/*@ predicate is_normal_char(long c) = 0 ≤ c ≤ 255; +typedef long wchar_t; +/*@ predicate is_normal_char(wchar_t c) = 0 ≤ c ≤ 255; */ -/*@ predicate wchar_buff{L}(long *p, ℤ l) = \at(*(p + l) ≡ (long)0,L); +/*@ predicate wchar_buff{L}(wchar_t *p, ℤ l) = \at(*(p + l) ≡ 0,L); */ int freq[256]; /*@ requires is_normal_char(c); */ -void count(long c) +void count(wchar_t c) { (freq[c]) ++; return; diff --git a/tests/stl/oracle/limits.res.oracle b/tests/stl/oracle/limits.res.oracle index d32240c5d192920a22376af29057eaa289f4be22..1d54ee54127ab740700d723a3ae986d5b7834a5e 100644 --- a/tests/stl/oracle/limits.res.oracle +++ b/tests/stl/oracle/limits.res.oracle @@ -31,6 +31,7 @@ struct _frama_c_rtti_name_info_node { int number_of_base_classes ; struct _frama_c_vmt *pvmt ; }; +typedef long wchar_t; float __builtin_huge_valf(void); float __builtin_nanf(char const *__frama_c_arg_0); @@ -569,23 +570,23 @@ struct _frama_c_rtti_name_info_node _frama_c_rtti_name_info; _Bool const is_specialized = (_Bool)1; _Bool const is_signed = (_Bool)1; -long min(void) +wchar_t min(void) { - long __retres; + wchar_t __retres; __retres = -2147483647L - 1L; return __retres; } -long max(void) +wchar_t max(void) { - long __retres; + wchar_t __retres; __retres = 2147483647L; return __retres; } -long lowest(void) +wchar_t lowest(void) { - long tmp; + wchar_t tmp; tmp = min(); return tmp; } @@ -596,17 +597,17 @@ int const max_digits10 = 0; _Bool const is_integer = (_Bool)1; _Bool const is_exact = (_Bool)1; int const radix = 2; -long epsilon(void) +wchar_t epsilon(void) { - long __retres; - __retres = (long)0; + wchar_t __retres; + __retres = (wchar_t)0; return __retres; } -long round_error(void) +wchar_t round_error(void) { - long __retres; - __retres = (long)0; + wchar_t __retres; + __retres = (wchar_t)0; return __retres; } @@ -618,31 +619,31 @@ _Bool const has_infinity = (_Bool)0; _Bool const has_quiet_NaN = (_Bool)0; _Bool const has_signaling_NaN = (_Bool)0; _Bool const has_denorm_loss = (_Bool)0; -long infinity(void) +wchar_t infinity(void) { - long __retres; - __retres = (long)0; + wchar_t __retres; + __retres = (wchar_t)0; return __retres; } -long quiet_NaN(void) +wchar_t quiet_NaN(void) { - long __retres; - __retres = (long)0; + wchar_t __retres; + __retres = (wchar_t)0; return __retres; } -long signaling_NaN(void) +wchar_t signaling_NaN(void) { - long __retres; - __retres = (long)0; + wchar_t __retres; + __retres = (wchar_t)0; return __retres; } -long denorm_min(void) +wchar_t denorm_min(void) { - long __retres; - __retres = (long)0; + wchar_t __retres; + __retres = (wchar_t)0; return __retres; } diff --git a/tests/stl/oracle/stl_algorithm.res.oracle b/tests/stl/oracle/stl_algorithm.res.oracle index 116484a4efbe6cb54b5bdc4035ce7350c687bda6..14b3aa84e4abf55e34ea7ffabfaccceb26d16342 100644 --- a/tests/stl/oracle/stl_algorithm.res.oracle +++ b/tests/stl/oracle/stl_algorithm.res.oracle @@ -65,6 +65,7 @@ struct pair<int*,int*> { int *first ; int *second ; }; +typedef long wchar_t; struct exception; struct bad_exception; struct nested_exception; @@ -540,7 +541,7 @@ axiomatic MemChr { ∀ char *s; ∀ ℤ c; ∀ ℤ n; - memchr(s, c, n) ≢ (0 ≢ 0) ⇔ + memchr(s, c, n) ≡ \true ⇔ (∃ int i; 0 ≤ i < n ∧ *(s + i) ≡ c); } @@ -554,7 +555,7 @@ axiomatic MemSet { ∀ char *s; ∀ ℤ c; ∀ ℤ n; - memset(s, c, n) ≢ (0 ≢ 0) ⇔ + memset(s, c, n) ≡ \true ⇔ (∀ ℤ i; 0 ≤ i < n ⇒ *(s + i) ≡ c); } @@ -567,33 +568,33 @@ axiomatic StrLen { axiom strlen_pos_or_null{L}: ∀ char *s; ∀ ℤ i; - 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ (char)0) ∧ - *(s + i) ≡ (char)0 ⇒ strlen(s) ≡ i; + 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ '\000') ∧ + *(s + i) ≡ '\000' ⇒ strlen(s) ≡ i; axiom strlen_neg{L}: ∀ char *s; - (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ (char)0) ⇒ strlen(s) < 0; + (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ '\000') ⇒ strlen(s) < 0; axiom strlen_before_null{L}: ∀ char *s; - ∀ ℤ i; 0 ≤ i < strlen(s) ⇒ *(s + i) ≢ (char)0; + ∀ ℤ i; 0 ≤ i < strlen(s) ⇒ *(s + i) ≢ '\000'; axiom strlen_at_null{L}: - ∀ char *s; 0 ≤ strlen(s) ⇒ *(s + strlen(s)) ≡ (char)0; + ∀ char *s; 0 ≤ strlen(s) ⇒ *(s + strlen(s)) ≡ '\000'; axiom strlen_not_zero{L}: ∀ char *s; ∀ ℤ i; - 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≢ (char)0 ⇒ i < strlen(s); + 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≢ '\000' ⇒ i < strlen(s); axiom strlen_zero{L}: ∀ char *s; ∀ ℤ i; - 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ (char)0 ⇒ i ≡ strlen(s); + 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ '\000' ⇒ i ≡ strlen(s); axiom strlen_sup{L}: ∀ char *s; - ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ (char)0 ⇒ 0 ≤ strlen(s) ≤ i; + ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ '\000' ⇒ 0 ≤ strlen(s) ≤ i; axiom strlen_shift{L}: ∀ char *s; @@ -601,14 +602,13 @@ axiomatic StrLen { axiom strlen_create{L}: ∀ char *s; - ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ (char)0 ⇒ 0 ≤ strlen(s) ≤ i; + ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ '\000' ⇒ 0 ≤ strlen(s) ≤ i; axiom strlen_create_shift{L}: ∀ char *s; ∀ ℤ i; ∀ ℤ k; - 0 ≤ k ≤ i ∧ *(s + i) ≡ (char)0 ⇒ - 0 ≤ strlen(s + k) ≤ i - k; + 0 ≤ k ≤ i ∧ *(s + i) ≡ '\000' ⇒ 0 ≤ strlen(s + k) ≤ i - k; axiom memcmp_strlen_left{L}: ∀ char *s1, char *s2; @@ -671,88 +671,84 @@ axiomatic StrChr { axiom strchr_def{L}: ∀ char *s; ∀ ℤ c; - strchr(s, c) ≢ (0 ≢ 0) ⇔ - (∃ ℤ i; 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ (char)((int)c)); + strchr(s, c) ≡ \true ⇔ + (∃ ℤ i; 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ (char)c); } */ /*@ axiomatic WMemChr { - logic 𔹠wmemchr{L}(long *s, long c, ℤ n) + logic 𔹠wmemchr{L}(wchar_t *s, wchar_t c, ℤ n) reads *(s + (0 .. n - 1)); - logic ℤ wmemchr_off{L}(long *s, long c, ℤ n) + logic ℤ wmemchr_off{L}(wchar_t *s, wchar_t c, ℤ n) reads *(s + (0 .. n - 1)); axiom wmemchr_def{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ long c; ∀ ℤ n; - wmemchr(s, c, n) ≢ (0 ≢ 0) ⇔ + wmemchr(s, c, n) ≡ \true ⇔ (∃ int i; 0 ≤ i < n ∧ *(s + i) ≡ c); } */ /*@ axiomatic WcsLen { - logic ℤ wcslen{L}(long *s) + logic ℤ wcslen{L}(wchar_t *s) reads *(s + (0 ..)); axiom wcslen_pos_or_null{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ ℤ i; - 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ (long)0) ∧ - *(s + i) ≡ (long)0 ⇒ wcslen(s) ≡ i; + 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ 0) ∧ + *(s + i) ≡ 0 ⇒ wcslen(s) ≡ i; axiom wcslen_neg{L}: - ∀ long *s; - (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ (long)0) ⇒ wcslen(s) < 0; + ∀ wchar_t *s; (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ 0) ⇒ wcslen(s) < 0; axiom wcslen_before_null{L}: - ∀ long *s; - ∀ int i; 0 ≤ i < wcslen(s) ⇒ *(s + i) ≢ (long)0; + ∀ wchar_t *s; + ∀ int i; 0 ≤ i < wcslen(s) ⇒ *(s + i) ≢ 0; axiom wcslen_at_null{L}: - ∀ long *s; 0 ≤ wcslen(s) ⇒ *(s + wcslen(s)) ≡ (long)0; + ∀ wchar_t *s; 0 ≤ wcslen(s) ⇒ *(s + wcslen(s)) ≡ 0; axiom wcslen_not_zero{L}: - ∀ long *s; - ∀ int i; - 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≢ (long)0 ⇒ i < wcslen(s); + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≢ 0 ⇒ i < wcslen(s); axiom wcslen_zero{L}: - ∀ long *s; - ∀ int i; - 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≡ (long)0 ⇒ i ≡ wcslen(s); + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≡ 0 ⇒ i ≡ wcslen(s); axiom wcslen_sup{L}: - ∀ long *s; - ∀ int i; 0 ≤ i ∧ *(s + i) ≡ (long)0 ⇒ 0 ≤ wcslen(s) ≤ i; + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ∧ *(s + i) ≡ 0 ⇒ 0 ≤ wcslen(s) ≤ i; axiom wcslen_shift{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ int i; 0 ≤ i ≤ wcslen(s) ⇒ wcslen(s + i) ≡ wcslen(s) - i; axiom wcslen_create{L}: - ∀ long *s; - ∀ int i; 0 ≤ i ∧ *(s + i) ≡ (long)0 ⇒ 0 ≤ wcslen(s) ≤ i; + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ∧ *(s + i) ≡ 0 ⇒ 0 ≤ wcslen(s) ≤ i; axiom wcslen_create_shift{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ int i; ∀ int k; - 0 ≤ k ≤ i ∧ *(s + i) ≡ (long)0 ⇒ - 0 ≤ wcslen(s + k) ≤ i - k; + 0 ≤ k ≤ i ∧ *(s + i) ≡ 0 ⇒ 0 ≤ wcslen(s + k) ≤ i - k; } */ /*@ axiomatic WcsCmp { - logic ℤ wcscmp{L}(long *s1, long *s2) + logic ℤ wcscmp{L}(wchar_t *s1, wchar_t *s2) reads *(s1 + (0 .. wcslen(s1))), *(s2 + (0 .. wcslen(s2))); axiom wcscmp_zero{L}: - ∀ long *s1, long *s2; + ∀ wchar_t *s1, wchar_t *s2; wcscmp(s1, s2) ≡ 0 ⇔ wcslen(s1) ≡ wcslen(s2) ∧ (∀ ℤ i; 0 ≤ i ≤ wcslen(s1) ⇒ *(s1 + i) ≡ *(s2 + i)); @@ -761,11 +757,11 @@ axiomatic WcsCmp { */ /*@ axiomatic WcsNCmp { - logic ℤ wcsncmp{L}(long *s1, long *s2, ℤ n) + logic ℤ wcsncmp{L}(wchar_t *s1, wchar_t *s2, ℤ n) reads *(s1 + (0 .. n - 1)), *(s2 + (0 .. n - 1)); axiom wcsncmp_zero{L}: - ∀ long *s1, long *s2; + ∀ wchar_t *s1, wchar_t *s2; ∀ ℤ n; wcsncmp(s1, s2, n) ≡ 0 ⇔ (wcslen(s1) < n ∧ wcscmp(s1, s2) ≡ 0) ∨ @@ -775,14 +771,14 @@ axiomatic WcsNCmp { */ /*@ axiomatic WcsChr { - logic 𔹠wcschr{L}(long *wcs, ℤ wc) + logic 𔹠wcschr{L}(wchar_t *wcs, ℤ wc) reads *(wcs + (0 .. wcslen(wcs))); axiom wcschr_def{L}: - ∀ long *wcs; + ∀ wchar_t *wcs; ∀ ℤ wc; - wcschr(wcs, wc) ≢ (0 ≢ 0) ⇔ - (∃ ℤ i; 0 ≤ i ≤ wcslen(wcs) ∧ *(wcs + i) ≡ (long)((int)wc)); + wcschr(wcs, wc) ≡ \true ⇔ + (∃ ℤ i; 0 ≤ i ≤ wcslen(wcs) ∧ *(wcs + i) ≡ (wchar_t)wc); } */ @@ -807,20 +803,20 @@ predicate valid_read_nstring{L}(char *s, ℤ n) = predicate valid_string_or_null{L}(char *s) = s ≡ \null ∨ valid_string(s); */ /*@ -predicate valid_wstring{L}(long *s) = +predicate valid_wstring{L}(wchar_t *s) = 0 ≤ wcslen(s) ∧ \valid(s + (0 .. wcslen(s))); */ /*@ -predicate valid_read_wstring{L}(long *s) = +predicate valid_read_wstring{L}(wchar_t *s) = 0 ≤ wcslen(s) ∧ \valid_read(s + (0 .. wcslen(s))); */ /*@ -predicate valid_read_nwstring{L}(long *s, ℤ n) = +predicate valid_read_nwstring{L}(wchar_t *s, ℤ n) = (\valid_read(s + (0 .. n - 1)) ∧ \initialized(s + (0 .. n - 1))) ∨ valid_read_wstring(s); */ /*@ -predicate valid_wstring_or_null{L}(long *s) = +predicate valid_wstring_or_null{L}(wchar_t *s) = s ≡ \null ∨ valid_wstring(s); */ /*@ ghost int __fc_heap_status; */ @@ -855,10 +851,10 @@ predicate valid_read_or_empty{L}(void *s, size_t n) = */ /*@ requires valid_s1: valid_read_or_empty(s1, n); requires valid_s2: valid_read_or_empty(s2, n); - requires s1: initialization: \initialized((char *)s1 + (0 .. n - 1)); - requires s2: initialization: \initialized((char *)s2 + (0 .. n - 1)); - requires s1: danglingness: non_escaping(s1, n); - requires s2: danglingness: non_escaping(s2, n); + requires initialization: s1: \initialized((char *)s1 + (0 .. n - 1)); + requires initialization: s2: \initialized((char *)s2 + (0 .. n - 1)); + requires danglingness: s1: non_escaping(s1, n); + requires danglingness: s2: non_escaping(s2, n); ensures logic_spec: \result ≡ @@ -881,12 +877,12 @@ int memcmp(void const *s1, void const *s2, size_t n); requires danglingness: non_escaping(s, n) ∨ - non_escaping(s, (size_t)((int)(memchr_off((char *)s, c, n) + 1))); + non_escaping(s, (size_t)(memchr_off((char *)s, c, n) + 1)); assigns \result; assigns \result \from s, c, *((unsigned char *)s + (0 .. n - 1)); behavior found: - assumes char_found: memchr((char *)s, c, n) ≢ (0 ≢ 0); + assumes char_found: memchr((char *)s, c, n) ≡ \true; ensures result_same_base: \base_addr(\result) ≡ \base_addr(\old(s)); ensures result_char: (int)*((char *)\result) ≡ \old(c); ensures @@ -897,7 +893,7 @@ int memcmp(void const *s1, void const *s2, size_t n); (unsigned char *)\result ≤ (unsigned char *)\old(s) + i; behavior not_found: - assumes char_not_found: memchr((char *)s, c, n) ≡ (0 ≢ 0); + assumes char_not_found: ¬(memchr((char *)s, c, n) ≡ \true); ensures result_null: \result ≡ \null; */ void *memchr(void const *s, int c, size_t n); @@ -952,7 +948,7 @@ void *memmove(void *dest, void const *src, size_t n); /*@ requires valid_s: valid_or_empty(s, n); ensures - acsl_c_equiv: memset((char *)\old(s), \old(c), \old(n)) ≢ (0 ≢ 0); + acsl_c_equiv: memset((char *)\old(s), \old(c), \old(n)) ≡ \true; ensures result_ptr: \result ≡ \old(s); assigns *((char *)s + (0 .. n - 1)), \result; assigns *((char *)s + (0 .. n - 1)) \from c; @@ -1008,7 +1004,7 @@ int strcoll(char const *s1, char const *s2); \from s, (indirect: *(s + (0 .. strlen{Old}(s)))), (indirect: c); behavior found: - assumes char_found: strchr(s, c) ≢ (0 ≢ 0); + assumes char_found: strchr(s, c) ≡ \true; ensures result_char: *\result ≡ (char)\old(c); ensures result_same_base: \base_addr(\result) ≡ \base_addr(\old(s)); ensures @@ -1019,7 +1015,7 @@ int strcoll(char const *s1, char const *s2); ∀ char *p; \old(s) ≤ p < \result ⇒ *p ≢ (char)\old(c); behavior not_found: - assumes char_not_found: strchr(s, c) ≡ (0 ≢ 0); + assumes char_not_found: ¬(strchr(s, c) ≡ \true); ensures result_null: \result ≡ \null; behavior default: @@ -1043,13 +1039,13 @@ char *strchrnul(char const *s, int c); assigns \result \from s, *(s + (0 ..)), c; behavior found: - assumes char_found: strchr(s, c) ≢ (0 ≢ 0); + assumes char_found: strchr(s, c) ≡ \true; ensures result_char: (int)*\result ≡ \old(c); ensures result_same_base: \base_addr(\result) ≡ \base_addr(\old(s)); ensures result_valid_string: valid_read_string(\result); behavior not_found: - assumes char_not_found: strchr(s, c) ≡ (0 ≢ 0); + assumes char_not_found: ¬(strchr(s, c) ≡ \true); ensures result_null: \result ≡ \null; behavior default: @@ -1143,7 +1139,7 @@ char *__fc_strtok_ptr; (valid_read_string(s) ∧ (∀ int i; 0 ≤ i < strlen(delim) ⇒ - strchr(s, *(delim + i)) ≡ (0 ≢ 0))); + ¬(strchr(s, *(delim + i)) ≡ \true))); ensures result_subset: \result ≡ \null ∨ \subset(\result, \old(s) + (0 ..)); @@ -1205,7 +1201,7 @@ char *strtok(char * restrict s, char const * restrict delim); (valid_read_string(s) ∧ (∀ int i; 0 ≤ i < strlen(delim) ⇒ - strchr(s, *(delim + i)) ≡ (0 ≢ 0))); + ¬(strchr(s, *(delim + i)) ≡ \true))); ensures result_subset: \result ≡ \null ∨ \subset(\result, \old(s) + (0 ..)); @@ -1222,7 +1218,7 @@ char *strtok(char * restrict s, char const * restrict delim); behavior resume_str: assumes s_null: s ≡ \null; requires not_first_call: *saveptr ≢ \null; - requires saveptr: initialization: \initialized(saveptr); + requires initialization: saveptr: \initialized(saveptr); ensures result_subset: \result ≡ \null ∨ \subset(\result, \old(*saveptr) + (0 ..)); @@ -1337,7 +1333,7 @@ char *stpcpy(char * restrict dest, char const * restrict src); ensures sum_of_lengths: strlen(\old(dest)) ≡ \old(strlen(dest) + strlen(src)); ensures - dest: initialization: + initialization: dest: \initialized(\old(dest) + (0 .. \old(strlen(dest) + strlen(src)))); ensures dest_null_terminated: @@ -1488,7 +1484,7 @@ char *strsignal(int signum); /*@ requires valid_memory_area: \valid((char *)s + (0 .. n - 1)); ensures - initialization: s_initialized: + s_initialized: initialization: \initialized((char *)\old(s) + (0 .. \old(n) - 1)); ensures zero_initialized: \subset(*((char *)\old(s) + (0 .. \old(n) - 1)), {0}); diff --git a/tests/stl/oracle/stl_atomic.res.oracle b/tests/stl/oracle/stl_atomic.res.oracle index fc10dce3d1da3ab9cd30fcd808aed257793d0106..2da7908d106cc4a1d27f9a13e2a4214e0be57821 100644 --- a/tests/stl/oracle/stl_atomic.res.oracle +++ b/tests/stl/oracle/stl_atomic.res.oracle @@ -113,8 +113,9 @@ struct __atomic<char16_t> { struct __atomic<char32_t> { unsigned int __val ; }; +typedef long wchar_t; struct __atomic<wchar_t> { - long __val ; + wchar_t __val ; }; struct atomic<bool> { struct __atomic<bool> _frama_c__ZN3stdE8__atomicIbE ; @@ -3502,187 +3503,204 @@ _Bool is_lock_free(struct __atomic<wchar_t> const volatile *this); _Bool is_lock_free(struct __atomic<wchar_t> const *this); /*@ requires \valid(this); */ -void store(struct __atomic<wchar_t> volatile *this, long c, memory_order o); +void store(struct __atomic<wchar_t> volatile *this, wchar_t c, memory_order o); /*@ requires \valid(this); */ -void store(struct __atomic<wchar_t> *this, long c, memory_order o); +void store(struct __atomic<wchar_t> *this, wchar_t c, memory_order o); /*@ requires \valid_read(this); */ -long load(struct __atomic<wchar_t> const volatile *this, - memory_order __frama_c_arg_0); +wchar_t load(struct __atomic<wchar_t> const volatile *this, + memory_order __frama_c_arg_0); /*@ requires \valid_read(this); */ -long load(struct __atomic<wchar_t> const *this, memory_order __frama_c_arg_0); +wchar_t load(struct __atomic<wchar_t> const *this, + memory_order __frama_c_arg_0); /*@ requires \valid_read(this); */ -long conversion(wchar_t)(struct __atomic<wchar_t> const volatile *this); +wchar_t conversion(wchar_t)(struct __atomic<wchar_t> const volatile *this); /*@ requires \valid_read(this); */ -long conversion(wchar_t)(struct __atomic<wchar_t> const *this); +wchar_t conversion(wchar_t)(struct __atomic<wchar_t> const *this); /*@ requires \valid(this); */ -long exchange(struct __atomic<wchar_t> volatile *this, long __frama_c_arg_0, - memory_order __frama_c_arg_1); +wchar_t exchange(struct __atomic<wchar_t> volatile *this, + wchar_t __frama_c_arg_0, memory_order __frama_c_arg_1); /*@ requires \valid(this); */ -long exchange(struct __atomic<wchar_t> *this, long __frama_c_arg_0, - memory_order __frama_c_arg_1); +wchar_t exchange(struct __atomic<wchar_t> *this, wchar_t __frama_c_arg_0, + memory_order __frama_c_arg_1); /*@ requires \valid(this); requires \valid(__frama_c_arg_0); */ _Bool compare_exchange_weak(struct __atomic<wchar_t> volatile *this, - long *__frama_c_arg_0, long __frama_c_arg_1, + wchar_t *__frama_c_arg_0, + wchar_t __frama_c_arg_1, memory_order __frama_c_arg_2, memory_order __frama_c_arg_3); /*@ requires \valid(this); requires \valid(__frama_c_arg_0); */ _Bool compare_exchange_weak(struct __atomic<wchar_t> *this, - long *__frama_c_arg_0, long __frama_c_arg_1, + wchar_t *__frama_c_arg_0, + wchar_t __frama_c_arg_1, memory_order __frama_c_arg_2, memory_order __frama_c_arg_3); /*@ requires \valid(this); requires \valid(__frama_c_arg_0); */ _Bool compare_exchange_strong(struct __atomic<wchar_t> volatile *this, - long *__frama_c_arg_0, long __frama_c_arg_1, + wchar_t *__frama_c_arg_0, + wchar_t __frama_c_arg_1, memory_order __frama_c_arg_2, memory_order __frama_c_arg_3); /*@ requires \valid(this); requires \valid(__frama_c_arg_0); */ _Bool compare_exchange_strong(struct __atomic<wchar_t> *this, - long *__frama_c_arg_0, long __frama_c_arg_1, + wchar_t *__frama_c_arg_0, + wchar_t __frama_c_arg_1, memory_order __frama_c_arg_2, memory_order __frama_c_arg_3); /*@ requires \valid(this); requires \valid(__frama_c_arg_0); */ _Bool compare_exchange_weak(struct __atomic<wchar_t> volatile *this, - long *__frama_c_arg_0, long __frama_c_arg_1, + wchar_t *__frama_c_arg_0, + wchar_t __frama_c_arg_1, memory_order __frama_c_arg_2); /*@ requires \valid(this); requires \valid(__frama_c_arg_0); */ _Bool compare_exchange_weak(struct __atomic<wchar_t> *this, - long *__frama_c_arg_0, long __frama_c_arg_1, + wchar_t *__frama_c_arg_0, + wchar_t __frama_c_arg_1, memory_order __frama_c_arg_2); /*@ requires \valid(this); requires \valid(__frama_c_arg_0); */ _Bool compare_exchange_strong(struct __atomic<wchar_t> volatile *this, - long *__frama_c_arg_0, long __frama_c_arg_1, + wchar_t *__frama_c_arg_0, + wchar_t __frama_c_arg_1, memory_order __frama_c_arg_2); /*@ requires \valid(this); requires \valid(__frama_c_arg_0); */ _Bool compare_exchange_strong(struct __atomic<wchar_t> *this, - long *__frama_c_arg_0, long __frama_c_arg_1, + wchar_t *__frama_c_arg_0, + wchar_t __frama_c_arg_1, memory_order __frama_c_arg_2); /*@ requires \valid(this); */ -long fetch_add(struct __atomic<wchar_t> volatile *this, long __frama_c_arg_0, - memory_order __frama_c_arg_1); +wchar_t fetch_add(struct __atomic<wchar_t> volatile *this, + wchar_t __frama_c_arg_0, memory_order __frama_c_arg_1); /*@ requires \valid(this); */ -long fetch_add(struct __atomic<wchar_t> *this, long __frama_c_arg_0, - memory_order __frama_c_arg_1); +wchar_t fetch_add(struct __atomic<wchar_t> *this, wchar_t __frama_c_arg_0, + memory_order __frama_c_arg_1); /*@ requires \valid(this); */ -long fetch_sub(struct __atomic<wchar_t> volatile *this, long __frama_c_arg_0, - memory_order __frama_c_arg_1); +wchar_t fetch_sub(struct __atomic<wchar_t> volatile *this, + wchar_t __frama_c_arg_0, memory_order __frama_c_arg_1); /*@ requires \valid(this); */ -long fetch_sub(struct __atomic<wchar_t> *this, long __frama_c_arg_0, - memory_order __frama_c_arg_1); +wchar_t fetch_sub(struct __atomic<wchar_t> *this, wchar_t __frama_c_arg_0, + memory_order __frama_c_arg_1); /*@ requires \valid(this); */ -long fetch_and(struct __atomic<wchar_t> volatile *this, long __frama_c_arg_0, - memory_order __frama_c_arg_1); +wchar_t fetch_and(struct __atomic<wchar_t> volatile *this, + wchar_t __frama_c_arg_0, memory_order __frama_c_arg_1); /*@ requires \valid(this); */ -long fetch_and(struct __atomic<wchar_t> *this, long __frama_c_arg_0, - memory_order __frama_c_arg_1); +wchar_t fetch_and(struct __atomic<wchar_t> *this, wchar_t __frama_c_arg_0, + memory_order __frama_c_arg_1); /*@ requires \valid(this); */ -long fetch_or(struct __atomic<wchar_t> volatile *this, long __frama_c_arg_0, - memory_order __frama_c_arg_1); +wchar_t fetch_or(struct __atomic<wchar_t> volatile *this, + wchar_t __frama_c_arg_0, memory_order __frama_c_arg_1); /*@ requires \valid(this); */ -long fetch_or(struct __atomic<wchar_t> *this, long __frama_c_arg_0, - memory_order __frama_c_arg_1); +wchar_t fetch_or(struct __atomic<wchar_t> *this, wchar_t __frama_c_arg_0, + memory_order __frama_c_arg_1); /*@ requires \valid(this); */ -long fetch_xor(struct __atomic<wchar_t> volatile *this, long __frama_c_arg_0, - memory_order __frama_c_arg_1); +wchar_t fetch_xor(struct __atomic<wchar_t> volatile *this, + wchar_t __frama_c_arg_0, memory_order __frama_c_arg_1); /*@ requires \valid(this); */ -long fetch_xor(struct __atomic<wchar_t> *this, long __frama_c_arg_0, - memory_order __frama_c_arg_1); +wchar_t fetch_xor(struct __atomic<wchar_t> *this, wchar_t __frama_c_arg_0, + memory_order __frama_c_arg_1); /*@ requires \valid_read(this); */ void __atomic<wchar_t>::Ctor(struct __atomic<wchar_t> const *this, - long __frama_c_arg_0); + wchar_t __frama_c_arg_0); /*@ requires \valid(this); */ -long operator=(struct __atomic<wchar_t> volatile *this, long __frama_c_arg_0); +wchar_t operator=(struct __atomic<wchar_t> volatile *this, + wchar_t __frama_c_arg_0); /*@ requires \valid(this); */ -long operator=(struct __atomic<wchar_t> *this, long __frama_c_arg_0); +wchar_t operator=(struct __atomic<wchar_t> *this, wchar_t __frama_c_arg_0); /*@ requires \valid(this); */ -long operator++(struct __atomic<wchar_t> volatile *this, int __frama_c_arg_0); +wchar_t operator++(struct __atomic<wchar_t> volatile *this, + int __frama_c_arg_0); /*@ requires \valid(this); */ -long operator++(struct __atomic<wchar_t> *this, int __frama_c_arg_0); +wchar_t operator++(struct __atomic<wchar_t> *this, int __frama_c_arg_0); /*@ requires \valid(this); */ -long operator--(struct __atomic<wchar_t> volatile *this, int __frama_c_arg_0); +wchar_t operator--(struct __atomic<wchar_t> volatile *this, + int __frama_c_arg_0); /*@ requires \valid(this); */ -long operator--(struct __atomic<wchar_t> *this, int __frama_c_arg_0); +wchar_t operator--(struct __atomic<wchar_t> *this, int __frama_c_arg_0); /*@ requires \valid(this); */ -long operator++(struct __atomic<wchar_t> volatile *this); +wchar_t operator++(struct __atomic<wchar_t> volatile *this); /*@ requires \valid(this); */ -long operator++(struct __atomic<wchar_t> *this); +wchar_t operator++(struct __atomic<wchar_t> *this); /*@ requires \valid(this); */ -long operator--(struct __atomic<wchar_t> volatile *this); +wchar_t operator--(struct __atomic<wchar_t> volatile *this); /*@ requires \valid(this); */ -long operator--(struct __atomic<wchar_t> *this); +wchar_t operator--(struct __atomic<wchar_t> *this); /*@ requires \valid(this); */ -long operator+=(struct __atomic<wchar_t> volatile *this, long __frama_c_arg_0); +wchar_t operator+=(struct __atomic<wchar_t> volatile *this, + wchar_t __frama_c_arg_0); /*@ requires \valid(this); */ -long operator+=(struct __atomic<wchar_t> *this, long __frama_c_arg_0); +wchar_t operator+=(struct __atomic<wchar_t> *this, wchar_t __frama_c_arg_0); /*@ requires \valid(this); */ -long operator-=(struct __atomic<wchar_t> volatile *this, long __frama_c_arg_0); +wchar_t operator-=(struct __atomic<wchar_t> volatile *this, + wchar_t __frama_c_arg_0); /*@ requires \valid(this); */ -long operator-=(struct __atomic<wchar_t> *this, long __frama_c_arg_0); +wchar_t operator-=(struct __atomic<wchar_t> *this, wchar_t __frama_c_arg_0); /*@ requires \valid(this); */ -long operator&=(struct __atomic<wchar_t> volatile *this, long __frama_c_arg_0); +wchar_t operator&=(struct __atomic<wchar_t> volatile *this, + wchar_t __frama_c_arg_0); /*@ requires \valid(this); */ -long operator&=(struct __atomic<wchar_t> *this, long __frama_c_arg_0); +wchar_t operator&=(struct __atomic<wchar_t> *this, wchar_t __frama_c_arg_0); /*@ requires \valid(this); */ -long operator|=(struct __atomic<wchar_t> volatile *this, long __frama_c_arg_0); +wchar_t operator|=(struct __atomic<wchar_t> volatile *this, + wchar_t __frama_c_arg_0); /*@ requires \valid(this); */ -long operator|=(struct __atomic<wchar_t> *this, long __frama_c_arg_0); +wchar_t operator|=(struct __atomic<wchar_t> *this, wchar_t __frama_c_arg_0); /*@ requires \valid(this); */ -long operator^=(struct __atomic<wchar_t> volatile *this, long __frama_c_arg_0); +wchar_t operator^=(struct __atomic<wchar_t> volatile *this, + wchar_t __frama_c_arg_0); /*@ requires \valid(this); */ -long operator^=(struct __atomic<wchar_t> *this, long __frama_c_arg_0); +wchar_t operator^=(struct __atomic<wchar_t> *this, wchar_t __frama_c_arg_0); struct _frama_c_rtti_name_info_node _frama_c_rtti_name_info = {.name = "__atomic", @@ -3836,7 +3854,7 @@ void atomic<char32_t>::Ctor(struct atomic<char32_t> const *this, struct _frama_c_rtti_name_info_node _frama_c_rtti_name_info; /*@ requires \valid_read(this); */ -void atomic<wchar_t>::Ctor(struct atomic<wchar_t> const *this, long x) +void atomic<wchar_t>::Ctor(struct atomic<wchar_t> const *this, wchar_t x) { __atomic<wchar_t>::Ctor(& this->_frama_c__ZN3stdE8__atomicIwE,x); return; diff --git a/tests/stl/oracle/stl_bool.res.oracle b/tests/stl/oracle/stl_bool.res.oracle index 750ea7a998b32d7be0fa12af092d4b466308d8c2..5a2dfc20ffe2fbada62b3c1985ac4a1aff258ad2 100644 --- a/tests/stl/oracle/stl_bool.res.oracle +++ b/tests/stl/oracle/stl_bool.res.oracle @@ -43,6 +43,7 @@ struct piecewise_construct_t; struct piecewise_construct_t { }; +typedef long wchar_t; struct exception; struct bad_exception; struct nested_exception; @@ -188,7 +189,7 @@ axiomatic MemChr { ∀ char *s; ∀ ℤ c; ∀ ℤ n; - memchr(s, c, n) ≢ (0 ≢ 0) ⇔ + memchr(s, c, n) ≡ \true ⇔ (∃ int i; 0 ≤ i < n ∧ *(s + i) ≡ c); } @@ -202,7 +203,7 @@ axiomatic MemSet { ∀ char *s; ∀ ℤ c; ∀ ℤ n; - memset(s, c, n) ≢ (0 ≢ 0) ⇔ + memset(s, c, n) ≡ \true ⇔ (∀ ℤ i; 0 ≤ i < n ⇒ *(s + i) ≡ c); } @@ -215,33 +216,33 @@ axiomatic StrLen { axiom strlen_pos_or_null{L}: ∀ char *s; ∀ ℤ i; - 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ (char)0) ∧ - *(s + i) ≡ (char)0 ⇒ strlen(s) ≡ i; + 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ '\000') ∧ + *(s + i) ≡ '\000' ⇒ strlen(s) ≡ i; axiom strlen_neg{L}: ∀ char *s; - (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ (char)0) ⇒ strlen(s) < 0; + (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ '\000') ⇒ strlen(s) < 0; axiom strlen_before_null{L}: ∀ char *s; - ∀ ℤ i; 0 ≤ i < strlen(s) ⇒ *(s + i) ≢ (char)0; + ∀ ℤ i; 0 ≤ i < strlen(s) ⇒ *(s + i) ≢ '\000'; axiom strlen_at_null{L}: - ∀ char *s; 0 ≤ strlen(s) ⇒ *(s + strlen(s)) ≡ (char)0; + ∀ char *s; 0 ≤ strlen(s) ⇒ *(s + strlen(s)) ≡ '\000'; axiom strlen_not_zero{L}: ∀ char *s; ∀ ℤ i; - 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≢ (char)0 ⇒ i < strlen(s); + 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≢ '\000' ⇒ i < strlen(s); axiom strlen_zero{L}: ∀ char *s; ∀ ℤ i; - 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ (char)0 ⇒ i ≡ strlen(s); + 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ '\000' ⇒ i ≡ strlen(s); axiom strlen_sup{L}: ∀ char *s; - ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ (char)0 ⇒ 0 ≤ strlen(s) ≤ i; + ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ '\000' ⇒ 0 ≤ strlen(s) ≤ i; axiom strlen_shift{L}: ∀ char *s; @@ -249,14 +250,13 @@ axiomatic StrLen { axiom strlen_create{L}: ∀ char *s; - ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ (char)0 ⇒ 0 ≤ strlen(s) ≤ i; + ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ '\000' ⇒ 0 ≤ strlen(s) ≤ i; axiom strlen_create_shift{L}: ∀ char *s; ∀ ℤ i; ∀ ℤ k; - 0 ≤ k ≤ i ∧ *(s + i) ≡ (char)0 ⇒ - 0 ≤ strlen(s + k) ≤ i - k; + 0 ≤ k ≤ i ∧ *(s + i) ≡ '\000' ⇒ 0 ≤ strlen(s + k) ≤ i - k; axiom memcmp_strlen_left{L}: ∀ char *s1, char *s2; @@ -319,88 +319,84 @@ axiomatic StrChr { axiom strchr_def{L}: ∀ char *s; ∀ ℤ c; - strchr(s, c) ≢ (0 ≢ 0) ⇔ - (∃ ℤ i; 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ (char)((int)c)); + strchr(s, c) ≡ \true ⇔ + (∃ ℤ i; 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ (char)c); } */ /*@ axiomatic WMemChr { - logic 𔹠wmemchr{L}(long *s, long c, ℤ n) + logic 𔹠wmemchr{L}(wchar_t *s, wchar_t c, ℤ n) reads *(s + (0 .. n - 1)); - logic ℤ wmemchr_off{L}(long *s, long c, ℤ n) + logic ℤ wmemchr_off{L}(wchar_t *s, wchar_t c, ℤ n) reads *(s + (0 .. n - 1)); axiom wmemchr_def{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ long c; ∀ ℤ n; - wmemchr(s, c, n) ≢ (0 ≢ 0) ⇔ + wmemchr(s, c, n) ≡ \true ⇔ (∃ int i; 0 ≤ i < n ∧ *(s + i) ≡ c); } */ /*@ axiomatic WcsLen { - logic ℤ wcslen{L}(long *s) + logic ℤ wcslen{L}(wchar_t *s) reads *(s + (0 ..)); axiom wcslen_pos_or_null{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ ℤ i; - 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ (long)0) ∧ - *(s + i) ≡ (long)0 ⇒ wcslen(s) ≡ i; + 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ 0) ∧ + *(s + i) ≡ 0 ⇒ wcslen(s) ≡ i; axiom wcslen_neg{L}: - ∀ long *s; - (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ (long)0) ⇒ wcslen(s) < 0; + ∀ wchar_t *s; (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ 0) ⇒ wcslen(s) < 0; axiom wcslen_before_null{L}: - ∀ long *s; - ∀ int i; 0 ≤ i < wcslen(s) ⇒ *(s + i) ≢ (long)0; + ∀ wchar_t *s; + ∀ int i; 0 ≤ i < wcslen(s) ⇒ *(s + i) ≢ 0; axiom wcslen_at_null{L}: - ∀ long *s; 0 ≤ wcslen(s) ⇒ *(s + wcslen(s)) ≡ (long)0; + ∀ wchar_t *s; 0 ≤ wcslen(s) ⇒ *(s + wcslen(s)) ≡ 0; axiom wcslen_not_zero{L}: - ∀ long *s; - ∀ int i; - 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≢ (long)0 ⇒ i < wcslen(s); + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≢ 0 ⇒ i < wcslen(s); axiom wcslen_zero{L}: - ∀ long *s; - ∀ int i; - 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≡ (long)0 ⇒ i ≡ wcslen(s); + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≡ 0 ⇒ i ≡ wcslen(s); axiom wcslen_sup{L}: - ∀ long *s; - ∀ int i; 0 ≤ i ∧ *(s + i) ≡ (long)0 ⇒ 0 ≤ wcslen(s) ≤ i; + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ∧ *(s + i) ≡ 0 ⇒ 0 ≤ wcslen(s) ≤ i; axiom wcslen_shift{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ int i; 0 ≤ i ≤ wcslen(s) ⇒ wcslen(s + i) ≡ wcslen(s) - i; axiom wcslen_create{L}: - ∀ long *s; - ∀ int i; 0 ≤ i ∧ *(s + i) ≡ (long)0 ⇒ 0 ≤ wcslen(s) ≤ i; + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ∧ *(s + i) ≡ 0 ⇒ 0 ≤ wcslen(s) ≤ i; axiom wcslen_create_shift{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ int i; ∀ int k; - 0 ≤ k ≤ i ∧ *(s + i) ≡ (long)0 ⇒ - 0 ≤ wcslen(s + k) ≤ i - k; + 0 ≤ k ≤ i ∧ *(s + i) ≡ 0 ⇒ 0 ≤ wcslen(s + k) ≤ i - k; } */ /*@ axiomatic WcsCmp { - logic ℤ wcscmp{L}(long *s1, long *s2) + logic ℤ wcscmp{L}(wchar_t *s1, wchar_t *s2) reads *(s1 + (0 .. wcslen(s1))), *(s2 + (0 .. wcslen(s2))); axiom wcscmp_zero{L}: - ∀ long *s1, long *s2; + ∀ wchar_t *s1, wchar_t *s2; wcscmp(s1, s2) ≡ 0 ⇔ wcslen(s1) ≡ wcslen(s2) ∧ (∀ ℤ i; 0 ≤ i ≤ wcslen(s1) ⇒ *(s1 + i) ≡ *(s2 + i)); @@ -409,11 +405,11 @@ axiomatic WcsCmp { */ /*@ axiomatic WcsNCmp { - logic ℤ wcsncmp{L}(long *s1, long *s2, ℤ n) + logic ℤ wcsncmp{L}(wchar_t *s1, wchar_t *s2, ℤ n) reads *(s1 + (0 .. n - 1)), *(s2 + (0 .. n - 1)); axiom wcsncmp_zero{L}: - ∀ long *s1, long *s2; + ∀ wchar_t *s1, wchar_t *s2; ∀ ℤ n; wcsncmp(s1, s2, n) ≡ 0 ⇔ (wcslen(s1) < n ∧ wcscmp(s1, s2) ≡ 0) ∨ @@ -423,14 +419,14 @@ axiomatic WcsNCmp { */ /*@ axiomatic WcsChr { - logic 𔹠wcschr{L}(long *wcs, ℤ wc) + logic 𔹠wcschr{L}(wchar_t *wcs, ℤ wc) reads *(wcs + (0 .. wcslen(wcs))); axiom wcschr_def{L}: - ∀ long *wcs; + ∀ wchar_t *wcs; ∀ ℤ wc; - wcschr(wcs, wc) ≢ (0 ≢ 0) ⇔ - (∃ ℤ i; 0 ≤ i ≤ wcslen(wcs) ∧ *(wcs + i) ≡ (long)((int)wc)); + wcschr(wcs, wc) ≡ \true ⇔ + (∃ ℤ i; 0 ≤ i ≤ wcslen(wcs) ∧ *(wcs + i) ≡ (wchar_t)wc); } */ @@ -455,20 +451,20 @@ predicate valid_read_nstring{L}(char *s, ℤ n) = predicate valid_string_or_null{L}(char *s) = s ≡ \null ∨ valid_string(s); */ /*@ -predicate valid_wstring{L}(long *s) = +predicate valid_wstring{L}(wchar_t *s) = 0 ≤ wcslen(s) ∧ \valid(s + (0 .. wcslen(s))); */ /*@ -predicate valid_read_wstring{L}(long *s) = +predicate valid_read_wstring{L}(wchar_t *s) = 0 ≤ wcslen(s) ∧ \valid_read(s + (0 .. wcslen(s))); */ /*@ -predicate valid_read_nwstring{L}(long *s, ℤ n) = +predicate valid_read_nwstring{L}(wchar_t *s, ℤ n) = (\valid_read(s + (0 .. n - 1)) ∧ \initialized(s + (0 .. n - 1))) ∨ valid_read_wstring(s); */ /*@ -predicate valid_wstring_or_null{L}(long *s) = +predicate valid_wstring_or_null{L}(wchar_t *s) = s ≡ \null ∨ valid_wstring(s); */ /*@ ghost int __fc_heap_status; */ @@ -503,10 +499,10 @@ predicate valid_read_or_empty{L}(void *s, size_t n) = */ /*@ requires valid_s1: valid_read_or_empty(s1, n); requires valid_s2: valid_read_or_empty(s2, n); - requires s1: initialization: \initialized((char *)s1 + (0 .. n - 1)); - requires s2: initialization: \initialized((char *)s2 + (0 .. n - 1)); - requires s1: danglingness: non_escaping(s1, n); - requires s2: danglingness: non_escaping(s2, n); + requires initialization: s1: \initialized((char *)s1 + (0 .. n - 1)); + requires initialization: s2: \initialized((char *)s2 + (0 .. n - 1)); + requires danglingness: s1: non_escaping(s1, n); + requires danglingness: s2: non_escaping(s2, n); ensures logic_spec: \result ≡ @@ -529,12 +525,12 @@ int memcmp(void const *s1, void const *s2, size_t n); requires danglingness: non_escaping(s, n) ∨ - non_escaping(s, (size_t)((int)(memchr_off((char *)s, c, n) + 1))); + non_escaping(s, (size_t)(memchr_off((char *)s, c, n) + 1)); assigns \result; assigns \result \from s, c, *((unsigned char *)s + (0 .. n - 1)); behavior found: - assumes char_found: memchr((char *)s, c, n) ≢ (0 ≢ 0); + assumes char_found: memchr((char *)s, c, n) ≡ \true; ensures result_same_base: \base_addr(\result) ≡ \base_addr(\old(s)); ensures result_char: (int)*((char *)\result) ≡ \old(c); ensures @@ -545,7 +541,7 @@ int memcmp(void const *s1, void const *s2, size_t n); (unsigned char *)\result ≤ (unsigned char *)\old(s) + i; behavior not_found: - assumes char_not_found: memchr((char *)s, c, n) ≡ (0 ≢ 0); + assumes char_not_found: ¬(memchr((char *)s, c, n) ≡ \true); ensures result_null: \result ≡ \null; */ void *memchr(void const *s, int c, size_t n); @@ -600,7 +596,7 @@ void *memmove(void *dest, void const *src, size_t n); /*@ requires valid_s: valid_or_empty(s, n); ensures - acsl_c_equiv: memset((char *)\old(s), \old(c), \old(n)) ≢ (0 ≢ 0); + acsl_c_equiv: memset((char *)\old(s), \old(c), \old(n)) ≡ \true; ensures result_ptr: \result ≡ \old(s); assigns *((char *)s + (0 .. n - 1)), \result; assigns *((char *)s + (0 .. n - 1)) \from c; @@ -656,7 +652,7 @@ int strcoll(char const *s1, char const *s2); \from s, (indirect: *(s + (0 .. strlen{Old}(s)))), (indirect: c); behavior found: - assumes char_found: strchr(s, c) ≢ (0 ≢ 0); + assumes char_found: strchr(s, c) ≡ \true; ensures result_char: *\result ≡ (char)\old(c); ensures result_same_base: \base_addr(\result) ≡ \base_addr(\old(s)); ensures @@ -667,7 +663,7 @@ int strcoll(char const *s1, char const *s2); ∀ char *p; \old(s) ≤ p < \result ⇒ *p ≢ (char)\old(c); behavior not_found: - assumes char_not_found: strchr(s, c) ≡ (0 ≢ 0); + assumes char_not_found: ¬(strchr(s, c) ≡ \true); ensures result_null: \result ≡ \null; behavior default: @@ -691,13 +687,13 @@ char *strchrnul(char const *s, int c); assigns \result \from s, *(s + (0 ..)), c; behavior found: - assumes char_found: strchr(s, c) ≢ (0 ≢ 0); + assumes char_found: strchr(s, c) ≡ \true; ensures result_char: (int)*\result ≡ \old(c); ensures result_same_base: \base_addr(\result) ≡ \base_addr(\old(s)); ensures result_valid_string: valid_read_string(\result); behavior not_found: - assumes char_not_found: strchr(s, c) ≡ (0 ≢ 0); + assumes char_not_found: ¬(strchr(s, c) ≡ \true); ensures result_null: \result ≡ \null; behavior default: @@ -791,7 +787,7 @@ char *__fc_strtok_ptr; (valid_read_string(s) ∧ (∀ int i; 0 ≤ i < strlen(delim) ⇒ - strchr(s, *(delim + i)) ≡ (0 ≢ 0))); + ¬(strchr(s, *(delim + i)) ≡ \true))); ensures result_subset: \result ≡ \null ∨ \subset(\result, \old(s) + (0 ..)); @@ -853,7 +849,7 @@ char *strtok(char * restrict s, char const * restrict delim); (valid_read_string(s) ∧ (∀ int i; 0 ≤ i < strlen(delim) ⇒ - strchr(s, *(delim + i)) ≡ (0 ≢ 0))); + ¬(strchr(s, *(delim + i)) ≡ \true))); ensures result_subset: \result ≡ \null ∨ \subset(\result, \old(s) + (0 ..)); @@ -870,7 +866,7 @@ char *strtok(char * restrict s, char const * restrict delim); behavior resume_str: assumes s_null: s ≡ \null; requires not_first_call: *saveptr ≢ \null; - requires saveptr: initialization: \initialized(saveptr); + requires initialization: saveptr: \initialized(saveptr); ensures result_subset: \result ≡ \null ∨ \subset(\result, \old(*saveptr) + (0 ..)); @@ -985,7 +981,7 @@ char *stpcpy(char * restrict dest, char const * restrict src); ensures sum_of_lengths: strlen(\old(dest)) ≡ \old(strlen(dest) + strlen(src)); ensures - dest: initialization: + initialization: dest: \initialized(\old(dest) + (0 .. \old(strlen(dest) + strlen(src)))); ensures dest_null_terminated: @@ -1136,7 +1132,7 @@ char *strsignal(int signum); /*@ requires valid_memory_area: \valid((char *)s + (0 .. n - 1)); ensures - initialization: s_initialized: + s_initialized: initialization: \initialized((char *)\old(s) + (0 .. \old(n) - 1)); ensures zero_initialized: \subset(*((char *)\old(s) + (0 .. \old(n) - 1)), {0}); diff --git a/tests/stl/oracle/stl_functional.res.oracle b/tests/stl/oracle/stl_functional.res.oracle index 4a90e39711dae24bd20e6fd3fab7c3baff873174..9549fe96fbd4ea17f1dbfc551a67484af5cafe5a 100644 --- a/tests/stl/oracle/stl_functional.res.oracle +++ b/tests/stl/oracle/stl_functional.res.oracle @@ -50,6 +50,7 @@ struct piecewise_construct_t; struct piecewise_construct_t { }; +typedef long wchar_t; struct exception; struct bad_exception; struct nested_exception; @@ -348,7 +349,7 @@ axiomatic MemChr { ∀ char *s; ∀ ℤ c; ∀ ℤ n; - memchr(s, c, n) ≢ (0 ≢ 0) ⇔ + memchr(s, c, n) ≡ \true ⇔ (∃ int i; 0 ≤ i < n ∧ *(s + i) ≡ c); } @@ -362,7 +363,7 @@ axiomatic MemSet { ∀ char *s; ∀ ℤ c; ∀ ℤ n; - memset(s, c, n) ≢ (0 ≢ 0) ⇔ + memset(s, c, n) ≡ \true ⇔ (∀ ℤ i; 0 ≤ i < n ⇒ *(s + i) ≡ c); } @@ -375,33 +376,33 @@ axiomatic StrLen { axiom strlen_pos_or_null{L}: ∀ char *s; ∀ ℤ i; - 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ (char)0) ∧ - *(s + i) ≡ (char)0 ⇒ strlen(s) ≡ i; + 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ '\000') ∧ + *(s + i) ≡ '\000' ⇒ strlen(s) ≡ i; axiom strlen_neg{L}: ∀ char *s; - (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ (char)0) ⇒ strlen(s) < 0; + (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ '\000') ⇒ strlen(s) < 0; axiom strlen_before_null{L}: ∀ char *s; - ∀ ℤ i; 0 ≤ i < strlen(s) ⇒ *(s + i) ≢ (char)0; + ∀ ℤ i; 0 ≤ i < strlen(s) ⇒ *(s + i) ≢ '\000'; axiom strlen_at_null{L}: - ∀ char *s; 0 ≤ strlen(s) ⇒ *(s + strlen(s)) ≡ (char)0; + ∀ char *s; 0 ≤ strlen(s) ⇒ *(s + strlen(s)) ≡ '\000'; axiom strlen_not_zero{L}: ∀ char *s; ∀ ℤ i; - 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≢ (char)0 ⇒ i < strlen(s); + 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≢ '\000' ⇒ i < strlen(s); axiom strlen_zero{L}: ∀ char *s; ∀ ℤ i; - 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ (char)0 ⇒ i ≡ strlen(s); + 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ '\000' ⇒ i ≡ strlen(s); axiom strlen_sup{L}: ∀ char *s; - ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ (char)0 ⇒ 0 ≤ strlen(s) ≤ i; + ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ '\000' ⇒ 0 ≤ strlen(s) ≤ i; axiom strlen_shift{L}: ∀ char *s; @@ -409,14 +410,13 @@ axiomatic StrLen { axiom strlen_create{L}: ∀ char *s; - ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ (char)0 ⇒ 0 ≤ strlen(s) ≤ i; + ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ '\000' ⇒ 0 ≤ strlen(s) ≤ i; axiom strlen_create_shift{L}: ∀ char *s; ∀ ℤ i; ∀ ℤ k; - 0 ≤ k ≤ i ∧ *(s + i) ≡ (char)0 ⇒ - 0 ≤ strlen(s + k) ≤ i - k; + 0 ≤ k ≤ i ∧ *(s + i) ≡ '\000' ⇒ 0 ≤ strlen(s + k) ≤ i - k; axiom memcmp_strlen_left{L}: ∀ char *s1, char *s2; @@ -479,88 +479,84 @@ axiomatic StrChr { axiom strchr_def{L}: ∀ char *s; ∀ ℤ c; - strchr(s, c) ≢ (0 ≢ 0) ⇔ - (∃ ℤ i; 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ (char)((int)c)); + strchr(s, c) ≡ \true ⇔ + (∃ ℤ i; 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ (char)c); } */ /*@ axiomatic WMemChr { - logic 𔹠wmemchr{L}(long *s, long c, ℤ n) + logic 𔹠wmemchr{L}(wchar_t *s, wchar_t c, ℤ n) reads *(s + (0 .. n - 1)); - logic ℤ wmemchr_off{L}(long *s, long c, ℤ n) + logic ℤ wmemchr_off{L}(wchar_t *s, wchar_t c, ℤ n) reads *(s + (0 .. n - 1)); axiom wmemchr_def{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ long c; ∀ ℤ n; - wmemchr(s, c, n) ≢ (0 ≢ 0) ⇔ + wmemchr(s, c, n) ≡ \true ⇔ (∃ int i; 0 ≤ i < n ∧ *(s + i) ≡ c); } */ /*@ axiomatic WcsLen { - logic ℤ wcslen{L}(long *s) + logic ℤ wcslen{L}(wchar_t *s) reads *(s + (0 ..)); axiom wcslen_pos_or_null{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ ℤ i; - 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ (long)0) ∧ - *(s + i) ≡ (long)0 ⇒ wcslen(s) ≡ i; + 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ 0) ∧ + *(s + i) ≡ 0 ⇒ wcslen(s) ≡ i; axiom wcslen_neg{L}: - ∀ long *s; - (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ (long)0) ⇒ wcslen(s) < 0; + ∀ wchar_t *s; (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ 0) ⇒ wcslen(s) < 0; axiom wcslen_before_null{L}: - ∀ long *s; - ∀ int i; 0 ≤ i < wcslen(s) ⇒ *(s + i) ≢ (long)0; + ∀ wchar_t *s; + ∀ int i; 0 ≤ i < wcslen(s) ⇒ *(s + i) ≢ 0; axiom wcslen_at_null{L}: - ∀ long *s; 0 ≤ wcslen(s) ⇒ *(s + wcslen(s)) ≡ (long)0; + ∀ wchar_t *s; 0 ≤ wcslen(s) ⇒ *(s + wcslen(s)) ≡ 0; axiom wcslen_not_zero{L}: - ∀ long *s; - ∀ int i; - 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≢ (long)0 ⇒ i < wcslen(s); + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≢ 0 ⇒ i < wcslen(s); axiom wcslen_zero{L}: - ∀ long *s; - ∀ int i; - 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≡ (long)0 ⇒ i ≡ wcslen(s); + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≡ 0 ⇒ i ≡ wcslen(s); axiom wcslen_sup{L}: - ∀ long *s; - ∀ int i; 0 ≤ i ∧ *(s + i) ≡ (long)0 ⇒ 0 ≤ wcslen(s) ≤ i; + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ∧ *(s + i) ≡ 0 ⇒ 0 ≤ wcslen(s) ≤ i; axiom wcslen_shift{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ int i; 0 ≤ i ≤ wcslen(s) ⇒ wcslen(s + i) ≡ wcslen(s) - i; axiom wcslen_create{L}: - ∀ long *s; - ∀ int i; 0 ≤ i ∧ *(s + i) ≡ (long)0 ⇒ 0 ≤ wcslen(s) ≤ i; + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ∧ *(s + i) ≡ 0 ⇒ 0 ≤ wcslen(s) ≤ i; axiom wcslen_create_shift{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ int i; ∀ int k; - 0 ≤ k ≤ i ∧ *(s + i) ≡ (long)0 ⇒ - 0 ≤ wcslen(s + k) ≤ i - k; + 0 ≤ k ≤ i ∧ *(s + i) ≡ 0 ⇒ 0 ≤ wcslen(s + k) ≤ i - k; } */ /*@ axiomatic WcsCmp { - logic ℤ wcscmp{L}(long *s1, long *s2) + logic ℤ wcscmp{L}(wchar_t *s1, wchar_t *s2) reads *(s1 + (0 .. wcslen(s1))), *(s2 + (0 .. wcslen(s2))); axiom wcscmp_zero{L}: - ∀ long *s1, long *s2; + ∀ wchar_t *s1, wchar_t *s2; wcscmp(s1, s2) ≡ 0 ⇔ wcslen(s1) ≡ wcslen(s2) ∧ (∀ ℤ i; 0 ≤ i ≤ wcslen(s1) ⇒ *(s1 + i) ≡ *(s2 + i)); @@ -569,11 +565,11 @@ axiomatic WcsCmp { */ /*@ axiomatic WcsNCmp { - logic ℤ wcsncmp{L}(long *s1, long *s2, ℤ n) + logic ℤ wcsncmp{L}(wchar_t *s1, wchar_t *s2, ℤ n) reads *(s1 + (0 .. n - 1)), *(s2 + (0 .. n - 1)); axiom wcsncmp_zero{L}: - ∀ long *s1, long *s2; + ∀ wchar_t *s1, wchar_t *s2; ∀ ℤ n; wcsncmp(s1, s2, n) ≡ 0 ⇔ (wcslen(s1) < n ∧ wcscmp(s1, s2) ≡ 0) ∨ @@ -583,14 +579,14 @@ axiomatic WcsNCmp { */ /*@ axiomatic WcsChr { - logic 𔹠wcschr{L}(long *wcs, ℤ wc) + logic 𔹠wcschr{L}(wchar_t *wcs, ℤ wc) reads *(wcs + (0 .. wcslen(wcs))); axiom wcschr_def{L}: - ∀ long *wcs; + ∀ wchar_t *wcs; ∀ ℤ wc; - wcschr(wcs, wc) ≢ (0 ≢ 0) ⇔ - (∃ ℤ i; 0 ≤ i ≤ wcslen(wcs) ∧ *(wcs + i) ≡ (long)((int)wc)); + wcschr(wcs, wc) ≡ \true ⇔ + (∃ ℤ i; 0 ≤ i ≤ wcslen(wcs) ∧ *(wcs + i) ≡ (wchar_t)wc); } */ @@ -615,20 +611,20 @@ predicate valid_read_nstring{L}(char *s, ℤ n) = predicate valid_string_or_null{L}(char *s) = s ≡ \null ∨ valid_string(s); */ /*@ -predicate valid_wstring{L}(long *s) = +predicate valid_wstring{L}(wchar_t *s) = 0 ≤ wcslen(s) ∧ \valid(s + (0 .. wcslen(s))); */ /*@ -predicate valid_read_wstring{L}(long *s) = +predicate valid_read_wstring{L}(wchar_t *s) = 0 ≤ wcslen(s) ∧ \valid_read(s + (0 .. wcslen(s))); */ /*@ -predicate valid_read_nwstring{L}(long *s, ℤ n) = +predicate valid_read_nwstring{L}(wchar_t *s, ℤ n) = (\valid_read(s + (0 .. n - 1)) ∧ \initialized(s + (0 .. n - 1))) ∨ valid_read_wstring(s); */ /*@ -predicate valid_wstring_or_null{L}(long *s) = +predicate valid_wstring_or_null{L}(wchar_t *s) = s ≡ \null ∨ valid_wstring(s); */ /*@ ghost int __fc_heap_status; */ @@ -663,10 +659,10 @@ predicate valid_read_or_empty{L}(void *s, size_t n) = */ /*@ requires valid_s1: valid_read_or_empty(s1, n); requires valid_s2: valid_read_or_empty(s2, n); - requires s1: initialization: \initialized((char *)s1 + (0 .. n - 1)); - requires s2: initialization: \initialized((char *)s2 + (0 .. n - 1)); - requires s1: danglingness: non_escaping(s1, n); - requires s2: danglingness: non_escaping(s2, n); + requires initialization: s1: \initialized((char *)s1 + (0 .. n - 1)); + requires initialization: s2: \initialized((char *)s2 + (0 .. n - 1)); + requires danglingness: s1: non_escaping(s1, n); + requires danglingness: s2: non_escaping(s2, n); ensures logic_spec: \result ≡ @@ -689,12 +685,12 @@ int memcmp(void const *s1, void const *s2, size_t n); requires danglingness: non_escaping(s, n) ∨ - non_escaping(s, (size_t)((int)(memchr_off((char *)s, c, n) + 1))); + non_escaping(s, (size_t)(memchr_off((char *)s, c, n) + 1)); assigns \result; assigns \result \from s, c, *((unsigned char *)s + (0 .. n - 1)); behavior found: - assumes char_found: memchr((char *)s, c, n) ≢ (0 ≢ 0); + assumes char_found: memchr((char *)s, c, n) ≡ \true; ensures result_same_base: \base_addr(\result) ≡ \base_addr(\old(s)); ensures result_char: (int)*((char *)\result) ≡ \old(c); ensures @@ -705,7 +701,7 @@ int memcmp(void const *s1, void const *s2, size_t n); (unsigned char *)\result ≤ (unsigned char *)\old(s) + i; behavior not_found: - assumes char_not_found: memchr((char *)s, c, n) ≡ (0 ≢ 0); + assumes char_not_found: ¬(memchr((char *)s, c, n) ≡ \true); ensures result_null: \result ≡ \null; */ void *memchr(void const *s, int c, size_t n); @@ -760,7 +756,7 @@ void *memmove(void *dest, void const *src, size_t n); /*@ requires valid_s: valid_or_empty(s, n); ensures - acsl_c_equiv: memset((char *)\old(s), \old(c), \old(n)) ≢ (0 ≢ 0); + acsl_c_equiv: memset((char *)\old(s), \old(c), \old(n)) ≡ \true; ensures result_ptr: \result ≡ \old(s); assigns *((char *)s + (0 .. n - 1)), \result; assigns *((char *)s + (0 .. n - 1)) \from c; @@ -816,7 +812,7 @@ int strcoll(char const *s1, char const *s2); \from s, (indirect: *(s + (0 .. strlen{Old}(s)))), (indirect: c); behavior found: - assumes char_found: strchr(s, c) ≢ (0 ≢ 0); + assumes char_found: strchr(s, c) ≡ \true; ensures result_char: *\result ≡ (char)\old(c); ensures result_same_base: \base_addr(\result) ≡ \base_addr(\old(s)); ensures @@ -827,7 +823,7 @@ int strcoll(char const *s1, char const *s2); ∀ char *p; \old(s) ≤ p < \result ⇒ *p ≢ (char)\old(c); behavior not_found: - assumes char_not_found: strchr(s, c) ≡ (0 ≢ 0); + assumes char_not_found: ¬(strchr(s, c) ≡ \true); ensures result_null: \result ≡ \null; behavior default: @@ -851,13 +847,13 @@ char *strchrnul(char const *s, int c); assigns \result \from s, *(s + (0 ..)), c; behavior found: - assumes char_found: strchr(s, c) ≢ (0 ≢ 0); + assumes char_found: strchr(s, c) ≡ \true; ensures result_char: (int)*\result ≡ \old(c); ensures result_same_base: \base_addr(\result) ≡ \base_addr(\old(s)); ensures result_valid_string: valid_read_string(\result); behavior not_found: - assumes char_not_found: strchr(s, c) ≡ (0 ≢ 0); + assumes char_not_found: ¬(strchr(s, c) ≡ \true); ensures result_null: \result ≡ \null; behavior default: @@ -951,7 +947,7 @@ char *__fc_strtok_ptr; (valid_read_string(s) ∧ (∀ int i; 0 ≤ i < strlen(delim) ⇒ - strchr(s, *(delim + i)) ≡ (0 ≢ 0))); + ¬(strchr(s, *(delim + i)) ≡ \true))); ensures result_subset: \result ≡ \null ∨ \subset(\result, \old(s) + (0 ..)); @@ -1013,7 +1009,7 @@ char *strtok(char * restrict s, char const * restrict delim); (valid_read_string(s) ∧ (∀ int i; 0 ≤ i < strlen(delim) ⇒ - strchr(s, *(delim + i)) ≡ (0 ≢ 0))); + ¬(strchr(s, *(delim + i)) ≡ \true))); ensures result_subset: \result ≡ \null ∨ \subset(\result, \old(s) + (0 ..)); @@ -1030,7 +1026,7 @@ char *strtok(char * restrict s, char const * restrict delim); behavior resume_str: assumes s_null: s ≡ \null; requires not_first_call: *saveptr ≢ \null; - requires saveptr: initialization: \initialized(saveptr); + requires initialization: saveptr: \initialized(saveptr); ensures result_subset: \result ≡ \null ∨ \subset(\result, \old(*saveptr) + (0 ..)); @@ -1145,7 +1141,7 @@ char *stpcpy(char * restrict dest, char const * restrict src); ensures sum_of_lengths: strlen(\old(dest)) ≡ \old(strlen(dest) + strlen(src)); ensures - dest: initialization: + initialization: dest: \initialized(\old(dest) + (0 .. \old(strlen(dest) + strlen(src)))); ensures dest_null_terminated: @@ -1296,7 +1292,7 @@ char *strsignal(int signum); /*@ requires valid_memory_area: \valid((char *)s + (0 .. n - 1)); ensures - initialization: s_initialized: + s_initialized: initialization: \initialized((char *)\old(s) + (0 .. \old(n) - 1)); ensures zero_initialized: \subset(*((char *)\old(s) + (0 .. \old(n) - 1)), {0}); diff --git a/tests/stl/oracle/stl_memory.res.oracle b/tests/stl/oracle/stl_memory.res.oracle index 0f3b7fc03505686f69a3d7e875060ff73d3b8d60..1c1723c90d58e8a138784635ffdb9dfd46975c3e 100644 --- a/tests/stl/oracle/stl_memory.res.oracle +++ b/tests/stl/oracle/stl_memory.res.oracle @@ -67,6 +67,7 @@ struct piecewise_construct_t; struct piecewise_construct_t { }; +typedef long wchar_t; struct exception; struct bad_exception; struct nested_exception; @@ -354,7 +355,7 @@ axiomatic MemChr { ∀ char *s; ∀ ℤ c; ∀ ℤ n; - memchr(s, c, n) ≢ (0 ≢ 0) ⇔ + memchr(s, c, n) ≡ \true ⇔ (∃ int i; 0 ≤ i < n ∧ *(s + i) ≡ c); } @@ -368,7 +369,7 @@ axiomatic MemSet { ∀ char *s; ∀ ℤ c; ∀ ℤ n; - memset(s, c, n) ≢ (0 ≢ 0) ⇔ + memset(s, c, n) ≡ \true ⇔ (∀ ℤ i; 0 ≤ i < n ⇒ *(s + i) ≡ c); } @@ -381,33 +382,33 @@ axiomatic StrLen { axiom strlen_pos_or_null{L}: ∀ char *s; ∀ ℤ i; - 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ (char)0) ∧ - *(s + i) ≡ (char)0 ⇒ strlen(s) ≡ i; + 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ '\000') ∧ + *(s + i) ≡ '\000' ⇒ strlen(s) ≡ i; axiom strlen_neg{L}: ∀ char *s; - (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ (char)0) ⇒ strlen(s) < 0; + (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ '\000') ⇒ strlen(s) < 0; axiom strlen_before_null{L}: ∀ char *s; - ∀ ℤ i; 0 ≤ i < strlen(s) ⇒ *(s + i) ≢ (char)0; + ∀ ℤ i; 0 ≤ i < strlen(s) ⇒ *(s + i) ≢ '\000'; axiom strlen_at_null{L}: - ∀ char *s; 0 ≤ strlen(s) ⇒ *(s + strlen(s)) ≡ (char)0; + ∀ char *s; 0 ≤ strlen(s) ⇒ *(s + strlen(s)) ≡ '\000'; axiom strlen_not_zero{L}: ∀ char *s; ∀ ℤ i; - 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≢ (char)0 ⇒ i < strlen(s); + 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≢ '\000' ⇒ i < strlen(s); axiom strlen_zero{L}: ∀ char *s; ∀ ℤ i; - 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ (char)0 ⇒ i ≡ strlen(s); + 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ '\000' ⇒ i ≡ strlen(s); axiom strlen_sup{L}: ∀ char *s; - ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ (char)0 ⇒ 0 ≤ strlen(s) ≤ i; + ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ '\000' ⇒ 0 ≤ strlen(s) ≤ i; axiom strlen_shift{L}: ∀ char *s; @@ -415,14 +416,13 @@ axiomatic StrLen { axiom strlen_create{L}: ∀ char *s; - ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ (char)0 ⇒ 0 ≤ strlen(s) ≤ i; + ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ '\000' ⇒ 0 ≤ strlen(s) ≤ i; axiom strlen_create_shift{L}: ∀ char *s; ∀ ℤ i; ∀ ℤ k; - 0 ≤ k ≤ i ∧ *(s + i) ≡ (char)0 ⇒ - 0 ≤ strlen(s + k) ≤ i - k; + 0 ≤ k ≤ i ∧ *(s + i) ≡ '\000' ⇒ 0 ≤ strlen(s + k) ≤ i - k; axiom memcmp_strlen_left{L}: ∀ char *s1, char *s2; @@ -485,88 +485,84 @@ axiomatic StrChr { axiom strchr_def{L}: ∀ char *s; ∀ ℤ c; - strchr(s, c) ≢ (0 ≢ 0) ⇔ - (∃ ℤ i; 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ (char)((int)c)); + strchr(s, c) ≡ \true ⇔ + (∃ ℤ i; 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ (char)c); } */ /*@ axiomatic WMemChr { - logic 𔹠wmemchr{L}(long *s, long c, ℤ n) + logic 𔹠wmemchr{L}(wchar_t *s, wchar_t c, ℤ n) reads *(s + (0 .. n - 1)); - logic ℤ wmemchr_off{L}(long *s, long c, ℤ n) + logic ℤ wmemchr_off{L}(wchar_t *s, wchar_t c, ℤ n) reads *(s + (0 .. n - 1)); axiom wmemchr_def{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ long c; ∀ ℤ n; - wmemchr(s, c, n) ≢ (0 ≢ 0) ⇔ + wmemchr(s, c, n) ≡ \true ⇔ (∃ int i; 0 ≤ i < n ∧ *(s + i) ≡ c); } */ /*@ axiomatic WcsLen { - logic ℤ wcslen{L}(long *s) + logic ℤ wcslen{L}(wchar_t *s) reads *(s + (0 ..)); axiom wcslen_pos_or_null{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ ℤ i; - 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ (long)0) ∧ - *(s + i) ≡ (long)0 ⇒ wcslen(s) ≡ i; + 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ 0) ∧ + *(s + i) ≡ 0 ⇒ wcslen(s) ≡ i; axiom wcslen_neg{L}: - ∀ long *s; - (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ (long)0) ⇒ wcslen(s) < 0; + ∀ wchar_t *s; (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ 0) ⇒ wcslen(s) < 0; axiom wcslen_before_null{L}: - ∀ long *s; - ∀ int i; 0 ≤ i < wcslen(s) ⇒ *(s + i) ≢ (long)0; + ∀ wchar_t *s; + ∀ int i; 0 ≤ i < wcslen(s) ⇒ *(s + i) ≢ 0; axiom wcslen_at_null{L}: - ∀ long *s; 0 ≤ wcslen(s) ⇒ *(s + wcslen(s)) ≡ (long)0; + ∀ wchar_t *s; 0 ≤ wcslen(s) ⇒ *(s + wcslen(s)) ≡ 0; axiom wcslen_not_zero{L}: - ∀ long *s; - ∀ int i; - 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≢ (long)0 ⇒ i < wcslen(s); + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≢ 0 ⇒ i < wcslen(s); axiom wcslen_zero{L}: - ∀ long *s; - ∀ int i; - 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≡ (long)0 ⇒ i ≡ wcslen(s); + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≡ 0 ⇒ i ≡ wcslen(s); axiom wcslen_sup{L}: - ∀ long *s; - ∀ int i; 0 ≤ i ∧ *(s + i) ≡ (long)0 ⇒ 0 ≤ wcslen(s) ≤ i; + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ∧ *(s + i) ≡ 0 ⇒ 0 ≤ wcslen(s) ≤ i; axiom wcslen_shift{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ int i; 0 ≤ i ≤ wcslen(s) ⇒ wcslen(s + i) ≡ wcslen(s) - i; axiom wcslen_create{L}: - ∀ long *s; - ∀ int i; 0 ≤ i ∧ *(s + i) ≡ (long)0 ⇒ 0 ≤ wcslen(s) ≤ i; + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ∧ *(s + i) ≡ 0 ⇒ 0 ≤ wcslen(s) ≤ i; axiom wcslen_create_shift{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ int i; ∀ int k; - 0 ≤ k ≤ i ∧ *(s + i) ≡ (long)0 ⇒ - 0 ≤ wcslen(s + k) ≤ i - k; + 0 ≤ k ≤ i ∧ *(s + i) ≡ 0 ⇒ 0 ≤ wcslen(s + k) ≤ i - k; } */ /*@ axiomatic WcsCmp { - logic ℤ wcscmp{L}(long *s1, long *s2) + logic ℤ wcscmp{L}(wchar_t *s1, wchar_t *s2) reads *(s1 + (0 .. wcslen(s1))), *(s2 + (0 .. wcslen(s2))); axiom wcscmp_zero{L}: - ∀ long *s1, long *s2; + ∀ wchar_t *s1, wchar_t *s2; wcscmp(s1, s2) ≡ 0 ⇔ wcslen(s1) ≡ wcslen(s2) ∧ (∀ ℤ i; 0 ≤ i ≤ wcslen(s1) ⇒ *(s1 + i) ≡ *(s2 + i)); @@ -575,11 +571,11 @@ axiomatic WcsCmp { */ /*@ axiomatic WcsNCmp { - logic ℤ wcsncmp{L}(long *s1, long *s2, ℤ n) + logic ℤ wcsncmp{L}(wchar_t *s1, wchar_t *s2, ℤ n) reads *(s1 + (0 .. n - 1)), *(s2 + (0 .. n - 1)); axiom wcsncmp_zero{L}: - ∀ long *s1, long *s2; + ∀ wchar_t *s1, wchar_t *s2; ∀ ℤ n; wcsncmp(s1, s2, n) ≡ 0 ⇔ (wcslen(s1) < n ∧ wcscmp(s1, s2) ≡ 0) ∨ @@ -589,14 +585,14 @@ axiomatic WcsNCmp { */ /*@ axiomatic WcsChr { - logic 𔹠wcschr{L}(long *wcs, ℤ wc) + logic 𔹠wcschr{L}(wchar_t *wcs, ℤ wc) reads *(wcs + (0 .. wcslen(wcs))); axiom wcschr_def{L}: - ∀ long *wcs; + ∀ wchar_t *wcs; ∀ ℤ wc; - wcschr(wcs, wc) ≢ (0 ≢ 0) ⇔ - (∃ ℤ i; 0 ≤ i ≤ wcslen(wcs) ∧ *(wcs + i) ≡ (long)((int)wc)); + wcschr(wcs, wc) ≡ \true ⇔ + (∃ ℤ i; 0 ≤ i ≤ wcslen(wcs) ∧ *(wcs + i) ≡ (wchar_t)wc); } */ @@ -621,20 +617,20 @@ predicate valid_read_nstring{L}(char *s, ℤ n) = predicate valid_string_or_null{L}(char *s) = s ≡ \null ∨ valid_string(s); */ /*@ -predicate valid_wstring{L}(long *s) = +predicate valid_wstring{L}(wchar_t *s) = 0 ≤ wcslen(s) ∧ \valid(s + (0 .. wcslen(s))); */ /*@ -predicate valid_read_wstring{L}(long *s) = +predicate valid_read_wstring{L}(wchar_t *s) = 0 ≤ wcslen(s) ∧ \valid_read(s + (0 .. wcslen(s))); */ /*@ -predicate valid_read_nwstring{L}(long *s, ℤ n) = +predicate valid_read_nwstring{L}(wchar_t *s, ℤ n) = (\valid_read(s + (0 .. n - 1)) ∧ \initialized(s + (0 .. n - 1))) ∨ valid_read_wstring(s); */ /*@ -predicate valid_wstring_or_null{L}(long *s) = +predicate valid_wstring_or_null{L}(wchar_t *s) = s ≡ \null ∨ valid_wstring(s); */ /*@ ghost int __fc_heap_status; */ @@ -669,10 +665,10 @@ predicate valid_read_or_empty{L}(void *s, size_t n) = */ /*@ requires valid_s1: valid_read_or_empty(s1, n); requires valid_s2: valid_read_or_empty(s2, n); - requires s1: initialization: \initialized((char *)s1 + (0 .. n - 1)); - requires s2: initialization: \initialized((char *)s2 + (0 .. n - 1)); - requires s1: danglingness: non_escaping(s1, n); - requires s2: danglingness: non_escaping(s2, n); + requires initialization: s1: \initialized((char *)s1 + (0 .. n - 1)); + requires initialization: s2: \initialized((char *)s2 + (0 .. n - 1)); + requires danglingness: s1: non_escaping(s1, n); + requires danglingness: s2: non_escaping(s2, n); ensures logic_spec: \result ≡ @@ -695,12 +691,12 @@ int memcmp(void const *s1, void const *s2, size_t n); requires danglingness: non_escaping(s, n) ∨ - non_escaping(s, (size_t)((int)(memchr_off((char *)s, c, n) + 1))); + non_escaping(s, (size_t)(memchr_off((char *)s, c, n) + 1)); assigns \result; assigns \result \from s, c, *((unsigned char *)s + (0 .. n - 1)); behavior found: - assumes char_found: memchr((char *)s, c, n) ≢ (0 ≢ 0); + assumes char_found: memchr((char *)s, c, n) ≡ \true; ensures result_same_base: \base_addr(\result) ≡ \base_addr(\old(s)); ensures result_char: (int)*((char *)\result) ≡ \old(c); ensures @@ -711,7 +707,7 @@ int memcmp(void const *s1, void const *s2, size_t n); (unsigned char *)\result ≤ (unsigned char *)\old(s) + i; behavior not_found: - assumes char_not_found: memchr((char *)s, c, n) ≡ (0 ≢ 0); + assumes char_not_found: ¬(memchr((char *)s, c, n) ≡ \true); ensures result_null: \result ≡ \null; */ void *memchr(void const *s, int c, size_t n); @@ -766,7 +762,7 @@ void *memmove(void *dest, void const *src, size_t n); /*@ requires valid_s: valid_or_empty(s, n); ensures - acsl_c_equiv: memset((char *)\old(s), \old(c), \old(n)) ≢ (0 ≢ 0); + acsl_c_equiv: memset((char *)\old(s), \old(c), \old(n)) ≡ \true; ensures result_ptr: \result ≡ \old(s); assigns *((char *)s + (0 .. n - 1)), \result; assigns *((char *)s + (0 .. n - 1)) \from c; @@ -822,7 +818,7 @@ int strcoll(char const *s1, char const *s2); \from s, (indirect: *(s + (0 .. strlen{Old}(s)))), (indirect: c); behavior found: - assumes char_found: strchr(s, c) ≢ (0 ≢ 0); + assumes char_found: strchr(s, c) ≡ \true; ensures result_char: *\result ≡ (char)\old(c); ensures result_same_base: \base_addr(\result) ≡ \base_addr(\old(s)); ensures @@ -833,7 +829,7 @@ int strcoll(char const *s1, char const *s2); ∀ char *p; \old(s) ≤ p < \result ⇒ *p ≢ (char)\old(c); behavior not_found: - assumes char_not_found: strchr(s, c) ≡ (0 ≢ 0); + assumes char_not_found: ¬(strchr(s, c) ≡ \true); ensures result_null: \result ≡ \null; behavior default: @@ -857,13 +853,13 @@ char *strchrnul(char const *s, int c); assigns \result \from s, *(s + (0 ..)), c; behavior found: - assumes char_found: strchr(s, c) ≢ (0 ≢ 0); + assumes char_found: strchr(s, c) ≡ \true; ensures result_char: (int)*\result ≡ \old(c); ensures result_same_base: \base_addr(\result) ≡ \base_addr(\old(s)); ensures result_valid_string: valid_read_string(\result); behavior not_found: - assumes char_not_found: strchr(s, c) ≡ (0 ≢ 0); + assumes char_not_found: ¬(strchr(s, c) ≡ \true); ensures result_null: \result ≡ \null; behavior default: @@ -957,7 +953,7 @@ char *__fc_strtok_ptr; (valid_read_string(s) ∧ (∀ int i; 0 ≤ i < strlen(delim) ⇒ - strchr(s, *(delim + i)) ≡ (0 ≢ 0))); + ¬(strchr(s, *(delim + i)) ≡ \true))); ensures result_subset: \result ≡ \null ∨ \subset(\result, \old(s) + (0 ..)); @@ -1019,7 +1015,7 @@ char *strtok(char * restrict s, char const * restrict delim); (valid_read_string(s) ∧ (∀ int i; 0 ≤ i < strlen(delim) ⇒ - strchr(s, *(delim + i)) ≡ (0 ≢ 0))); + ¬(strchr(s, *(delim + i)) ≡ \true))); ensures result_subset: \result ≡ \null ∨ \subset(\result, \old(s) + (0 ..)); @@ -1036,7 +1032,7 @@ char *strtok(char * restrict s, char const * restrict delim); behavior resume_str: assumes s_null: s ≡ \null; requires not_first_call: *saveptr ≢ \null; - requires saveptr: initialization: \initialized(saveptr); + requires initialization: saveptr: \initialized(saveptr); ensures result_subset: \result ≡ \null ∨ \subset(\result, \old(*saveptr) + (0 ..)); @@ -1151,7 +1147,7 @@ char *stpcpy(char * restrict dest, char const * restrict src); ensures sum_of_lengths: strlen(\old(dest)) ≡ \old(strlen(dest) + strlen(src)); ensures - dest: initialization: + initialization: dest: \initialized(\old(dest) + (0 .. \old(strlen(dest) + strlen(src)))); ensures dest_null_terminated: @@ -1302,7 +1298,7 @@ char *strsignal(int signum); /*@ requires valid_memory_area: \valid((char *)s + (0 .. n - 1)); ensures - initialization: s_initialized: + s_initialized: initialization: \initialized((char *)\old(s) + (0 .. \old(n) - 1)); ensures zero_initialized: \subset(*((char *)\old(s) + (0 .. \old(n) - 1)), {0}); diff --git a/tests/stl/oracle/stl_shared_ptr_mistake10.res.oracle b/tests/stl/oracle/stl_shared_ptr_mistake10.res.oracle index 3aed66ca369e67ddf9554386637eb9d445456280..769ed4ab3a1da2b8bc8a5cac2e56d358ff028386 100644 --- a/tests/stl/oracle/stl_shared_ptr_mistake10.res.oracle +++ b/tests/stl/oracle/stl_shared_ptr_mistake10.res.oracle @@ -54,6 +54,7 @@ struct piecewise_construct_t; struct piecewise_construct_t { }; +typedef long wchar_t; struct exception; struct bad_exception; struct nested_exception; @@ -322,7 +323,7 @@ axiomatic MemChr { ∀ char *s; ∀ ℤ c; ∀ ℤ n; - memchr(s, c, n) ≢ (0 ≢ 0) ⇔ + memchr(s, c, n) ≡ \true ⇔ (∃ int i; 0 ≤ i < n ∧ *(s + i) ≡ c); } @@ -336,7 +337,7 @@ axiomatic MemSet { ∀ char *s; ∀ ℤ c; ∀ ℤ n; - memset(s, c, n) ≢ (0 ≢ 0) ⇔ + memset(s, c, n) ≡ \true ⇔ (∀ ℤ i; 0 ≤ i < n ⇒ *(s + i) ≡ c); } @@ -349,33 +350,33 @@ axiomatic StrLen { axiom strlen_pos_or_null{L}: ∀ char *s; ∀ ℤ i; - 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ (char)0) ∧ - *(s + i) ≡ (char)0 ⇒ strlen(s) ≡ i; + 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ '\000') ∧ + *(s + i) ≡ '\000' ⇒ strlen(s) ≡ i; axiom strlen_neg{L}: ∀ char *s; - (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ (char)0) ⇒ strlen(s) < 0; + (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ '\000') ⇒ strlen(s) < 0; axiom strlen_before_null{L}: ∀ char *s; - ∀ ℤ i; 0 ≤ i < strlen(s) ⇒ *(s + i) ≢ (char)0; + ∀ ℤ i; 0 ≤ i < strlen(s) ⇒ *(s + i) ≢ '\000'; axiom strlen_at_null{L}: - ∀ char *s; 0 ≤ strlen(s) ⇒ *(s + strlen(s)) ≡ (char)0; + ∀ char *s; 0 ≤ strlen(s) ⇒ *(s + strlen(s)) ≡ '\000'; axiom strlen_not_zero{L}: ∀ char *s; ∀ ℤ i; - 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≢ (char)0 ⇒ i < strlen(s); + 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≢ '\000' ⇒ i < strlen(s); axiom strlen_zero{L}: ∀ char *s; ∀ ℤ i; - 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ (char)0 ⇒ i ≡ strlen(s); + 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ '\000' ⇒ i ≡ strlen(s); axiom strlen_sup{L}: ∀ char *s; - ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ (char)0 ⇒ 0 ≤ strlen(s) ≤ i; + ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ '\000' ⇒ 0 ≤ strlen(s) ≤ i; axiom strlen_shift{L}: ∀ char *s; @@ -383,14 +384,13 @@ axiomatic StrLen { axiom strlen_create{L}: ∀ char *s; - ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ (char)0 ⇒ 0 ≤ strlen(s) ≤ i; + ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ '\000' ⇒ 0 ≤ strlen(s) ≤ i; axiom strlen_create_shift{L}: ∀ char *s; ∀ ℤ i; ∀ ℤ k; - 0 ≤ k ≤ i ∧ *(s + i) ≡ (char)0 ⇒ - 0 ≤ strlen(s + k) ≤ i - k; + 0 ≤ k ≤ i ∧ *(s + i) ≡ '\000' ⇒ 0 ≤ strlen(s + k) ≤ i - k; axiom memcmp_strlen_left{L}: ∀ char *s1, char *s2; @@ -453,88 +453,84 @@ axiomatic StrChr { axiom strchr_def{L}: ∀ char *s; ∀ ℤ c; - strchr(s, c) ≢ (0 ≢ 0) ⇔ - (∃ ℤ i; 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ (char)((int)c)); + strchr(s, c) ≡ \true ⇔ + (∃ ℤ i; 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ (char)c); } */ /*@ axiomatic WMemChr { - logic 𔹠wmemchr{L}(long *s, long c, ℤ n) + logic 𔹠wmemchr{L}(wchar_t *s, wchar_t c, ℤ n) reads *(s + (0 .. n - 1)); - logic ℤ wmemchr_off{L}(long *s, long c, ℤ n) + logic ℤ wmemchr_off{L}(wchar_t *s, wchar_t c, ℤ n) reads *(s + (0 .. n - 1)); axiom wmemchr_def{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ long c; ∀ ℤ n; - wmemchr(s, c, n) ≢ (0 ≢ 0) ⇔ + wmemchr(s, c, n) ≡ \true ⇔ (∃ int i; 0 ≤ i < n ∧ *(s + i) ≡ c); } */ /*@ axiomatic WcsLen { - logic ℤ wcslen{L}(long *s) + logic ℤ wcslen{L}(wchar_t *s) reads *(s + (0 ..)); axiom wcslen_pos_or_null{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ ℤ i; - 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ (long)0) ∧ - *(s + i) ≡ (long)0 ⇒ wcslen(s) ≡ i; + 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ 0) ∧ + *(s + i) ≡ 0 ⇒ wcslen(s) ≡ i; axiom wcslen_neg{L}: - ∀ long *s; - (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ (long)0) ⇒ wcslen(s) < 0; + ∀ wchar_t *s; (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ 0) ⇒ wcslen(s) < 0; axiom wcslen_before_null{L}: - ∀ long *s; - ∀ int i; 0 ≤ i < wcslen(s) ⇒ *(s + i) ≢ (long)0; + ∀ wchar_t *s; + ∀ int i; 0 ≤ i < wcslen(s) ⇒ *(s + i) ≢ 0; axiom wcslen_at_null{L}: - ∀ long *s; 0 ≤ wcslen(s) ⇒ *(s + wcslen(s)) ≡ (long)0; + ∀ wchar_t *s; 0 ≤ wcslen(s) ⇒ *(s + wcslen(s)) ≡ 0; axiom wcslen_not_zero{L}: - ∀ long *s; - ∀ int i; - 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≢ (long)0 ⇒ i < wcslen(s); + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≢ 0 ⇒ i < wcslen(s); axiom wcslen_zero{L}: - ∀ long *s; - ∀ int i; - 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≡ (long)0 ⇒ i ≡ wcslen(s); + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≡ 0 ⇒ i ≡ wcslen(s); axiom wcslen_sup{L}: - ∀ long *s; - ∀ int i; 0 ≤ i ∧ *(s + i) ≡ (long)0 ⇒ 0 ≤ wcslen(s) ≤ i; + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ∧ *(s + i) ≡ 0 ⇒ 0 ≤ wcslen(s) ≤ i; axiom wcslen_shift{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ int i; 0 ≤ i ≤ wcslen(s) ⇒ wcslen(s + i) ≡ wcslen(s) - i; axiom wcslen_create{L}: - ∀ long *s; - ∀ int i; 0 ≤ i ∧ *(s + i) ≡ (long)0 ⇒ 0 ≤ wcslen(s) ≤ i; + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ∧ *(s + i) ≡ 0 ⇒ 0 ≤ wcslen(s) ≤ i; axiom wcslen_create_shift{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ int i; ∀ int k; - 0 ≤ k ≤ i ∧ *(s + i) ≡ (long)0 ⇒ - 0 ≤ wcslen(s + k) ≤ i - k; + 0 ≤ k ≤ i ∧ *(s + i) ≡ 0 ⇒ 0 ≤ wcslen(s + k) ≤ i - k; } */ /*@ axiomatic WcsCmp { - logic ℤ wcscmp{L}(long *s1, long *s2) + logic ℤ wcscmp{L}(wchar_t *s1, wchar_t *s2) reads *(s1 + (0 .. wcslen(s1))), *(s2 + (0 .. wcslen(s2))); axiom wcscmp_zero{L}: - ∀ long *s1, long *s2; + ∀ wchar_t *s1, wchar_t *s2; wcscmp(s1, s2) ≡ 0 ⇔ wcslen(s1) ≡ wcslen(s2) ∧ (∀ ℤ i; 0 ≤ i ≤ wcslen(s1) ⇒ *(s1 + i) ≡ *(s2 + i)); @@ -543,11 +539,11 @@ axiomatic WcsCmp { */ /*@ axiomatic WcsNCmp { - logic ℤ wcsncmp{L}(long *s1, long *s2, ℤ n) + logic ℤ wcsncmp{L}(wchar_t *s1, wchar_t *s2, ℤ n) reads *(s1 + (0 .. n - 1)), *(s2 + (0 .. n - 1)); axiom wcsncmp_zero{L}: - ∀ long *s1, long *s2; + ∀ wchar_t *s1, wchar_t *s2; ∀ ℤ n; wcsncmp(s1, s2, n) ≡ 0 ⇔ (wcslen(s1) < n ∧ wcscmp(s1, s2) ≡ 0) ∨ @@ -557,14 +553,14 @@ axiomatic WcsNCmp { */ /*@ axiomatic WcsChr { - logic 𔹠wcschr{L}(long *wcs, ℤ wc) + logic 𔹠wcschr{L}(wchar_t *wcs, ℤ wc) reads *(wcs + (0 .. wcslen(wcs))); axiom wcschr_def{L}: - ∀ long *wcs; + ∀ wchar_t *wcs; ∀ ℤ wc; - wcschr(wcs, wc) ≢ (0 ≢ 0) ⇔ - (∃ ℤ i; 0 ≤ i ≤ wcslen(wcs) ∧ *(wcs + i) ≡ (long)((int)wc)); + wcschr(wcs, wc) ≡ \true ⇔ + (∃ ℤ i; 0 ≤ i ≤ wcslen(wcs) ∧ *(wcs + i) ≡ (wchar_t)wc); } */ @@ -589,20 +585,20 @@ predicate valid_read_nstring{L}(char *s, ℤ n) = predicate valid_string_or_null{L}(char *s) = s ≡ \null ∨ valid_string(s); */ /*@ -predicate valid_wstring{L}(long *s) = +predicate valid_wstring{L}(wchar_t *s) = 0 ≤ wcslen(s) ∧ \valid(s + (0 .. wcslen(s))); */ /*@ -predicate valid_read_wstring{L}(long *s) = +predicate valid_read_wstring{L}(wchar_t *s) = 0 ≤ wcslen(s) ∧ \valid_read(s + (0 .. wcslen(s))); */ /*@ -predicate valid_read_nwstring{L}(long *s, ℤ n) = +predicate valid_read_nwstring{L}(wchar_t *s, ℤ n) = (\valid_read(s + (0 .. n - 1)) ∧ \initialized(s + (0 .. n - 1))) ∨ valid_read_wstring(s); */ /*@ -predicate valid_wstring_or_null{L}(long *s) = +predicate valid_wstring_or_null{L}(wchar_t *s) = s ≡ \null ∨ valid_wstring(s); */ @@ -684,10 +680,10 @@ predicate valid_read_or_empty{L}(void *s, size_t n) = */ /*@ requires valid_s1: valid_read_or_empty(s1, n); requires valid_s2: valid_read_or_empty(s2, n); - requires s1: initialization: \initialized((char *)s1 + (0 .. n - 1)); - requires s2: initialization: \initialized((char *)s2 + (0 .. n - 1)); - requires s1: danglingness: non_escaping(s1, n); - requires s2: danglingness: non_escaping(s2, n); + requires initialization: s1: \initialized((char *)s1 + (0 .. n - 1)); + requires initialization: s2: \initialized((char *)s2 + (0 .. n - 1)); + requires danglingness: s1: non_escaping(s1, n); + requires danglingness: s2: non_escaping(s2, n); ensures logic_spec: \result ≡ @@ -710,12 +706,12 @@ int memcmp(void const *s1, void const *s2, size_t n); requires danglingness: non_escaping(s, n) ∨ - non_escaping(s, (size_t)((int)(memchr_off((char *)s, c, n) + 1))); + non_escaping(s, (size_t)(memchr_off((char *)s, c, n) + 1)); assigns \result; assigns \result \from s, c, *((unsigned char *)s + (0 .. n - 1)); behavior found: - assumes char_found: memchr((char *)s, c, n) ≢ (0 ≢ 0); + assumes char_found: memchr((char *)s, c, n) ≡ \true; ensures result_same_base: \base_addr(\result) ≡ \base_addr(\old(s)); ensures result_char: (int)*((char *)\result) ≡ \old(c); ensures @@ -726,7 +722,7 @@ int memcmp(void const *s1, void const *s2, size_t n); (unsigned char *)\result ≤ (unsigned char *)\old(s) + i; behavior not_found: - assumes char_not_found: memchr((char *)s, c, n) ≡ (0 ≢ 0); + assumes char_not_found: ¬(memchr((char *)s, c, n) ≡ \true); ensures result_null: \result ≡ \null; */ void *memchr(void const *s, int c, size_t n); @@ -781,7 +777,7 @@ void *memmove(void *dest, void const *src, size_t n); /*@ requires valid_s: valid_or_empty(s, n); ensures - acsl_c_equiv: memset((char *)\old(s), \old(c), \old(n)) ≢ (0 ≢ 0); + acsl_c_equiv: memset((char *)\old(s), \old(c), \old(n)) ≡ \true; ensures result_ptr: \result ≡ \old(s); assigns *((char *)s + (0 .. n - 1)), \result; assigns *((char *)s + (0 .. n - 1)) \from c; @@ -837,7 +833,7 @@ int strcoll(char const *s1, char const *s2); \from s, (indirect: *(s + (0 .. strlen{Old}(s)))), (indirect: c); behavior found: - assumes char_found: strchr(s, c) ≢ (0 ≢ 0); + assumes char_found: strchr(s, c) ≡ \true; ensures result_char: *\result ≡ (char)\old(c); ensures result_same_base: \base_addr(\result) ≡ \base_addr(\old(s)); ensures @@ -848,7 +844,7 @@ int strcoll(char const *s1, char const *s2); ∀ char *p; \old(s) ≤ p < \result ⇒ *p ≢ (char)\old(c); behavior not_found: - assumes char_not_found: strchr(s, c) ≡ (0 ≢ 0); + assumes char_not_found: ¬(strchr(s, c) ≡ \true); ensures result_null: \result ≡ \null; behavior default: @@ -872,13 +868,13 @@ char *strchrnul(char const *s, int c); assigns \result \from s, *(s + (0 ..)), c; behavior found: - assumes char_found: strchr(s, c) ≢ (0 ≢ 0); + assumes char_found: strchr(s, c) ≡ \true; ensures result_char: (int)*\result ≡ \old(c); ensures result_same_base: \base_addr(\result) ≡ \base_addr(\old(s)); ensures result_valid_string: valid_read_string(\result); behavior not_found: - assumes char_not_found: strchr(s, c) ≡ (0 ≢ 0); + assumes char_not_found: ¬(strchr(s, c) ≡ \true); ensures result_null: \result ≡ \null; behavior default: @@ -972,7 +968,7 @@ char *__fc_strtok_ptr; (valid_read_string(s) ∧ (∀ int i; 0 ≤ i < strlen(delim) ⇒ - strchr(s, *(delim + i)) ≡ (0 ≢ 0))); + ¬(strchr(s, *(delim + i)) ≡ \true))); ensures result_subset: \result ≡ \null ∨ \subset(\result, \old(s) + (0 ..)); @@ -1034,7 +1030,7 @@ char *strtok(char * restrict s, char const * restrict delim); (valid_read_string(s) ∧ (∀ int i; 0 ≤ i < strlen(delim) ⇒ - strchr(s, *(delim + i)) ≡ (0 ≢ 0))); + ¬(strchr(s, *(delim + i)) ≡ \true))); ensures result_subset: \result ≡ \null ∨ \subset(\result, \old(s) + (0 ..)); @@ -1051,7 +1047,7 @@ char *strtok(char * restrict s, char const * restrict delim); behavior resume_str: assumes s_null: s ≡ \null; requires not_first_call: *saveptr ≢ \null; - requires saveptr: initialization: \initialized(saveptr); + requires initialization: saveptr: \initialized(saveptr); ensures result_subset: \result ≡ \null ∨ \subset(\result, \old(*saveptr) + (0 ..)); @@ -1166,7 +1162,7 @@ char *stpcpy(char * restrict dest, char const * restrict src); ensures sum_of_lengths: strlen(\old(dest)) ≡ \old(strlen(dest) + strlen(src)); ensures - dest: initialization: + initialization: dest: \initialized(\old(dest) + (0 .. \old(strlen(dest) + strlen(src)))); ensures dest_null_terminated: @@ -1317,7 +1313,7 @@ char *strsignal(int signum); /*@ requires valid_memory_area: \valid((char *)s + (0 .. n - 1)); ensures - initialization: s_initialized: + s_initialized: initialization: \initialized((char *)\old(s) + (0 .. \old(n) - 1)); ensures zero_initialized: \subset(*((char *)\old(s) + (0 .. \old(n) - 1)), {0}); @@ -2801,7 +2797,7 @@ unsigned short *__fc_p_random48_counter = __fc_random48_counter; void srand48(long seed); /*@ requires - initialized_seed16v: initialization: \initialized(seed16v + (0 .. 2)); + initialization: initialized_seed16v: \initialized(seed16v + (0 .. 2)); ensures random48_initialized: __fc_random48_init ≡ 1; ensures result_counter: \result ≡ __fc_p_random48_counter; assigns __fc_random48_counter[0 .. 2], __fc_random48_init, \result; @@ -2829,7 +2825,7 @@ void lcong48(unsigned short param[7]); double drand48(void); /*@ requires - initialized_xsubi: initialization: \initialized(xsubi + (0 .. 2)); + initialization: initialized_xsubi: \initialized(xsubi + (0 .. 2)); ensures result_range: \is_finite(\result) ∧ 0.0 ≤ \result < 1.0; assigns __fc_random48_counter[0 .. 2], \result; assigns __fc_random48_counter[0 .. 2] @@ -2848,7 +2844,7 @@ double erand48(unsigned short xsubi[3]); long lrand48(void); /*@ requires - initialized_xsubi: initialization: \initialized(xsubi + (0 .. 2)); + initialization: initialized_xsubi: \initialized(xsubi + (0 .. 2)); ensures result_range: 0 ≤ \result < 2147483648; assigns __fc_random48_counter[0 .. 2], \result; assigns __fc_random48_counter[0 .. 2] @@ -2867,7 +2863,7 @@ long nrand48(unsigned short xsubi[3]); long mrand48(void); /*@ requires - initialized_xsubi: initialization: \initialized(xsubi + (0 .. 2)); + initialization: initialized_xsubi: \initialized(xsubi + (0 .. 2)); ensures result_range: -2147483648 ≤ \result < 2147483648; assigns __fc_random48_counter[0 .. 2], \result; assigns __fc_random48_counter[0 .. 2] @@ -3171,7 +3167,7 @@ int mblen(char const *s, size_t n); \from (indirect: s), *(s + (0 .. n - 1)), (indirect: n), __fc_mbtowc_state; */ -int mbtowc(long * restrict pwc, char const * restrict s, size_t n); +int mbtowc(wchar_t * restrict pwc, char const * restrict s, size_t n); /*@ ghost int __fc_wctomb_state; */ /*@ assigns \result, *(s + (0 ..)), __fc_wctomb_state; @@ -3179,7 +3175,7 @@ int mbtowc(long * restrict pwc, char const * restrict s, size_t n); assigns *(s + (0 ..)) \from wc, __fc_wctomb_state; assigns __fc_wctomb_state \from wc, __fc_wctomb_state; */ -int wctomb(char *s, long wc); +int wctomb(char *s, wchar_t wc); /*@ requires separation: \separated(pwcs, s); assigns \result, *(pwcs + (0 .. n - 1)); @@ -3188,7 +3184,7 @@ int wctomb(char *s, long wc); assigns *(pwcs + (0 .. n - 1)) \from (indirect: s), *(s + (0 .. n - 1)), (indirect: n); */ -size_t mbstowcs(long * restrict pwcs, char const * restrict s, size_t n); +size_t mbstowcs(wchar_t * restrict pwcs, char const * restrict s, size_t n); /*@ requires separation: \separated(s, pwcs); assigns \result, *(s + (0 .. n - 1)); @@ -3198,12 +3194,13 @@ size_t mbstowcs(long * restrict pwcs, char const * restrict s, size_t n); assigns *(s + (0 .. n - 1)) \from (indirect: pwcs), *(pwcs + (0 .. n - 1)), (indirect: n); */ -size_t wcstombs(char * restrict s, long const * restrict pwcs, size_t n); +size_t wcstombs(char * restrict s, wchar_t const * restrict pwcs, size_t n); /*@ requires valid_memptr: \valid(memptr); requires alignment_is_a_suitable_power_of_two: - alignment ≥ sizeof(void *) ∧ (alignment & alignment - 1) ≡ 0; + alignment ≥ sizeof(void *) ∧ + ((size_t)alignment & (size_t)alignment - 1) ≡ 0; assigns __fc_heap_status, \result; assigns __fc_heap_status \from (indirect: alignment), size, __fc_heap_status; diff --git a/tests/stl/oracle/stl_shared_ptr_mistake5.res.oracle b/tests/stl/oracle/stl_shared_ptr_mistake5.res.oracle index 93272875fe11dee726682a4633df56775edb13b3..7787be6ba39f85775f88784540c6d6a84729b522 100644 --- a/tests/stl/oracle/stl_shared_ptr_mistake5.res.oracle +++ b/tests/stl/oracle/stl_shared_ptr_mistake5.res.oracle @@ -52,6 +52,7 @@ struct piecewise_construct_t; struct piecewise_construct_t { }; +typedef long wchar_t; struct exception; struct bad_exception; struct nested_exception; @@ -303,7 +304,7 @@ axiomatic MemChr { ∀ char *s; ∀ ℤ c; ∀ ℤ n; - memchr(s, c, n) ≢ (0 ≢ 0) ⇔ + memchr(s, c, n) ≡ \true ⇔ (∃ int i; 0 ≤ i < n ∧ *(s + i) ≡ c); } @@ -317,7 +318,7 @@ axiomatic MemSet { ∀ char *s; ∀ ℤ c; ∀ ℤ n; - memset(s, c, n) ≢ (0 ≢ 0) ⇔ + memset(s, c, n) ≡ \true ⇔ (∀ ℤ i; 0 ≤ i < n ⇒ *(s + i) ≡ c); } @@ -330,33 +331,33 @@ axiomatic StrLen { axiom strlen_pos_or_null{L}: ∀ char *s; ∀ ℤ i; - 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ (char)0) ∧ - *(s + i) ≡ (char)0 ⇒ strlen(s) ≡ i; + 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ '\000') ∧ + *(s + i) ≡ '\000' ⇒ strlen(s) ≡ i; axiom strlen_neg{L}: ∀ char *s; - (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ (char)0) ⇒ strlen(s) < 0; + (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ '\000') ⇒ strlen(s) < 0; axiom strlen_before_null{L}: ∀ char *s; - ∀ ℤ i; 0 ≤ i < strlen(s) ⇒ *(s + i) ≢ (char)0; + ∀ ℤ i; 0 ≤ i < strlen(s) ⇒ *(s + i) ≢ '\000'; axiom strlen_at_null{L}: - ∀ char *s; 0 ≤ strlen(s) ⇒ *(s + strlen(s)) ≡ (char)0; + ∀ char *s; 0 ≤ strlen(s) ⇒ *(s + strlen(s)) ≡ '\000'; axiom strlen_not_zero{L}: ∀ char *s; ∀ ℤ i; - 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≢ (char)0 ⇒ i < strlen(s); + 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≢ '\000' ⇒ i < strlen(s); axiom strlen_zero{L}: ∀ char *s; ∀ ℤ i; - 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ (char)0 ⇒ i ≡ strlen(s); + 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ '\000' ⇒ i ≡ strlen(s); axiom strlen_sup{L}: ∀ char *s; - ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ (char)0 ⇒ 0 ≤ strlen(s) ≤ i; + ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ '\000' ⇒ 0 ≤ strlen(s) ≤ i; axiom strlen_shift{L}: ∀ char *s; @@ -364,14 +365,13 @@ axiomatic StrLen { axiom strlen_create{L}: ∀ char *s; - ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ (char)0 ⇒ 0 ≤ strlen(s) ≤ i; + ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ '\000' ⇒ 0 ≤ strlen(s) ≤ i; axiom strlen_create_shift{L}: ∀ char *s; ∀ ℤ i; ∀ ℤ k; - 0 ≤ k ≤ i ∧ *(s + i) ≡ (char)0 ⇒ - 0 ≤ strlen(s + k) ≤ i - k; + 0 ≤ k ≤ i ∧ *(s + i) ≡ '\000' ⇒ 0 ≤ strlen(s + k) ≤ i - k; axiom memcmp_strlen_left{L}: ∀ char *s1, char *s2; @@ -434,88 +434,84 @@ axiomatic StrChr { axiom strchr_def{L}: ∀ char *s; ∀ ℤ c; - strchr(s, c) ≢ (0 ≢ 0) ⇔ - (∃ ℤ i; 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ (char)((int)c)); + strchr(s, c) ≡ \true ⇔ + (∃ ℤ i; 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ (char)c); } */ /*@ axiomatic WMemChr { - logic 𔹠wmemchr{L}(long *s, long c, ℤ n) + logic 𔹠wmemchr{L}(wchar_t *s, wchar_t c, ℤ n) reads *(s + (0 .. n - 1)); - logic ℤ wmemchr_off{L}(long *s, long c, ℤ n) + logic ℤ wmemchr_off{L}(wchar_t *s, wchar_t c, ℤ n) reads *(s + (0 .. n - 1)); axiom wmemchr_def{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ long c; ∀ ℤ n; - wmemchr(s, c, n) ≢ (0 ≢ 0) ⇔ + wmemchr(s, c, n) ≡ \true ⇔ (∃ int i; 0 ≤ i < n ∧ *(s + i) ≡ c); } */ /*@ axiomatic WcsLen { - logic ℤ wcslen{L}(long *s) + logic ℤ wcslen{L}(wchar_t *s) reads *(s + (0 ..)); axiom wcslen_pos_or_null{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ ℤ i; - 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ (long)0) ∧ - *(s + i) ≡ (long)0 ⇒ wcslen(s) ≡ i; + 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ 0) ∧ + *(s + i) ≡ 0 ⇒ wcslen(s) ≡ i; axiom wcslen_neg{L}: - ∀ long *s; - (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ (long)0) ⇒ wcslen(s) < 0; + ∀ wchar_t *s; (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ 0) ⇒ wcslen(s) < 0; axiom wcslen_before_null{L}: - ∀ long *s; - ∀ int i; 0 ≤ i < wcslen(s) ⇒ *(s + i) ≢ (long)0; + ∀ wchar_t *s; + ∀ int i; 0 ≤ i < wcslen(s) ⇒ *(s + i) ≢ 0; axiom wcslen_at_null{L}: - ∀ long *s; 0 ≤ wcslen(s) ⇒ *(s + wcslen(s)) ≡ (long)0; + ∀ wchar_t *s; 0 ≤ wcslen(s) ⇒ *(s + wcslen(s)) ≡ 0; axiom wcslen_not_zero{L}: - ∀ long *s; - ∀ int i; - 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≢ (long)0 ⇒ i < wcslen(s); + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≢ 0 ⇒ i < wcslen(s); axiom wcslen_zero{L}: - ∀ long *s; - ∀ int i; - 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≡ (long)0 ⇒ i ≡ wcslen(s); + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≡ 0 ⇒ i ≡ wcslen(s); axiom wcslen_sup{L}: - ∀ long *s; - ∀ int i; 0 ≤ i ∧ *(s + i) ≡ (long)0 ⇒ 0 ≤ wcslen(s) ≤ i; + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ∧ *(s + i) ≡ 0 ⇒ 0 ≤ wcslen(s) ≤ i; axiom wcslen_shift{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ int i; 0 ≤ i ≤ wcslen(s) ⇒ wcslen(s + i) ≡ wcslen(s) - i; axiom wcslen_create{L}: - ∀ long *s; - ∀ int i; 0 ≤ i ∧ *(s + i) ≡ (long)0 ⇒ 0 ≤ wcslen(s) ≤ i; + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ∧ *(s + i) ≡ 0 ⇒ 0 ≤ wcslen(s) ≤ i; axiom wcslen_create_shift{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ int i; ∀ int k; - 0 ≤ k ≤ i ∧ *(s + i) ≡ (long)0 ⇒ - 0 ≤ wcslen(s + k) ≤ i - k; + 0 ≤ k ≤ i ∧ *(s + i) ≡ 0 ⇒ 0 ≤ wcslen(s + k) ≤ i - k; } */ /*@ axiomatic WcsCmp { - logic ℤ wcscmp{L}(long *s1, long *s2) + logic ℤ wcscmp{L}(wchar_t *s1, wchar_t *s2) reads *(s1 + (0 .. wcslen(s1))), *(s2 + (0 .. wcslen(s2))); axiom wcscmp_zero{L}: - ∀ long *s1, long *s2; + ∀ wchar_t *s1, wchar_t *s2; wcscmp(s1, s2) ≡ 0 ⇔ wcslen(s1) ≡ wcslen(s2) ∧ (∀ ℤ i; 0 ≤ i ≤ wcslen(s1) ⇒ *(s1 + i) ≡ *(s2 + i)); @@ -524,11 +520,11 @@ axiomatic WcsCmp { */ /*@ axiomatic WcsNCmp { - logic ℤ wcsncmp{L}(long *s1, long *s2, ℤ n) + logic ℤ wcsncmp{L}(wchar_t *s1, wchar_t *s2, ℤ n) reads *(s1 + (0 .. n - 1)), *(s2 + (0 .. n - 1)); axiom wcsncmp_zero{L}: - ∀ long *s1, long *s2; + ∀ wchar_t *s1, wchar_t *s2; ∀ ℤ n; wcsncmp(s1, s2, n) ≡ 0 ⇔ (wcslen(s1) < n ∧ wcscmp(s1, s2) ≡ 0) ∨ @@ -538,14 +534,14 @@ axiomatic WcsNCmp { */ /*@ axiomatic WcsChr { - logic 𔹠wcschr{L}(long *wcs, ℤ wc) + logic 𔹠wcschr{L}(wchar_t *wcs, ℤ wc) reads *(wcs + (0 .. wcslen(wcs))); axiom wcschr_def{L}: - ∀ long *wcs; + ∀ wchar_t *wcs; ∀ ℤ wc; - wcschr(wcs, wc) ≢ (0 ≢ 0) ⇔ - (∃ ℤ i; 0 ≤ i ≤ wcslen(wcs) ∧ *(wcs + i) ≡ (long)((int)wc)); + wcschr(wcs, wc) ≡ \true ⇔ + (∃ ℤ i; 0 ≤ i ≤ wcslen(wcs) ∧ *(wcs + i) ≡ (wchar_t)wc); } */ @@ -570,20 +566,20 @@ predicate valid_read_nstring{L}(char *s, ℤ n) = predicate valid_string_or_null{L}(char *s) = s ≡ \null ∨ valid_string(s); */ /*@ -predicate valid_wstring{L}(long *s) = +predicate valid_wstring{L}(wchar_t *s) = 0 ≤ wcslen(s) ∧ \valid(s + (0 .. wcslen(s))); */ /*@ -predicate valid_read_wstring{L}(long *s) = +predicate valid_read_wstring{L}(wchar_t *s) = 0 ≤ wcslen(s) ∧ \valid_read(s + (0 .. wcslen(s))); */ /*@ -predicate valid_read_nwstring{L}(long *s, ℤ n) = +predicate valid_read_nwstring{L}(wchar_t *s, ℤ n) = (\valid_read(s + (0 .. n - 1)) ∧ \initialized(s + (0 .. n - 1))) ∨ valid_read_wstring(s); */ /*@ -predicate valid_wstring_or_null{L}(long *s) = +predicate valid_wstring_or_null{L}(wchar_t *s) = s ≡ \null ∨ valid_wstring(s); */ @@ -665,10 +661,10 @@ predicate valid_read_or_empty{L}(void *s, size_t n) = */ /*@ requires valid_s1: valid_read_or_empty(s1, n); requires valid_s2: valid_read_or_empty(s2, n); - requires s1: initialization: \initialized((char *)s1 + (0 .. n - 1)); - requires s2: initialization: \initialized((char *)s2 + (0 .. n - 1)); - requires s1: danglingness: non_escaping(s1, n); - requires s2: danglingness: non_escaping(s2, n); + requires initialization: s1: \initialized((char *)s1 + (0 .. n - 1)); + requires initialization: s2: \initialized((char *)s2 + (0 .. n - 1)); + requires danglingness: s1: non_escaping(s1, n); + requires danglingness: s2: non_escaping(s2, n); ensures logic_spec: \result ≡ @@ -691,12 +687,12 @@ int memcmp(void const *s1, void const *s2, size_t n); requires danglingness: non_escaping(s, n) ∨ - non_escaping(s, (size_t)((int)(memchr_off((char *)s, c, n) + 1))); + non_escaping(s, (size_t)(memchr_off((char *)s, c, n) + 1)); assigns \result; assigns \result \from s, c, *((unsigned char *)s + (0 .. n - 1)); behavior found: - assumes char_found: memchr((char *)s, c, n) ≢ (0 ≢ 0); + assumes char_found: memchr((char *)s, c, n) ≡ \true; ensures result_same_base: \base_addr(\result) ≡ \base_addr(\old(s)); ensures result_char: (int)*((char *)\result) ≡ \old(c); ensures @@ -707,7 +703,7 @@ int memcmp(void const *s1, void const *s2, size_t n); (unsigned char *)\result ≤ (unsigned char *)\old(s) + i; behavior not_found: - assumes char_not_found: memchr((char *)s, c, n) ≡ (0 ≢ 0); + assumes char_not_found: ¬(memchr((char *)s, c, n) ≡ \true); ensures result_null: \result ≡ \null; */ void *memchr(void const *s, int c, size_t n); @@ -762,7 +758,7 @@ void *memmove(void *dest, void const *src, size_t n); /*@ requires valid_s: valid_or_empty(s, n); ensures - acsl_c_equiv: memset((char *)\old(s), \old(c), \old(n)) ≢ (0 ≢ 0); + acsl_c_equiv: memset((char *)\old(s), \old(c), \old(n)) ≡ \true; ensures result_ptr: \result ≡ \old(s); assigns *((char *)s + (0 .. n - 1)), \result; assigns *((char *)s + (0 .. n - 1)) \from c; @@ -818,7 +814,7 @@ int strcoll(char const *s1, char const *s2); \from s, (indirect: *(s + (0 .. strlen{Old}(s)))), (indirect: c); behavior found: - assumes char_found: strchr(s, c) ≢ (0 ≢ 0); + assumes char_found: strchr(s, c) ≡ \true; ensures result_char: *\result ≡ (char)\old(c); ensures result_same_base: \base_addr(\result) ≡ \base_addr(\old(s)); ensures @@ -829,7 +825,7 @@ int strcoll(char const *s1, char const *s2); ∀ char *p; \old(s) ≤ p < \result ⇒ *p ≢ (char)\old(c); behavior not_found: - assumes char_not_found: strchr(s, c) ≡ (0 ≢ 0); + assumes char_not_found: ¬(strchr(s, c) ≡ \true); ensures result_null: \result ≡ \null; behavior default: @@ -853,13 +849,13 @@ char *strchrnul(char const *s, int c); assigns \result \from s, *(s + (0 ..)), c; behavior found: - assumes char_found: strchr(s, c) ≢ (0 ≢ 0); + assumes char_found: strchr(s, c) ≡ \true; ensures result_char: (int)*\result ≡ \old(c); ensures result_same_base: \base_addr(\result) ≡ \base_addr(\old(s)); ensures result_valid_string: valid_read_string(\result); behavior not_found: - assumes char_not_found: strchr(s, c) ≡ (0 ≢ 0); + assumes char_not_found: ¬(strchr(s, c) ≡ \true); ensures result_null: \result ≡ \null; behavior default: @@ -953,7 +949,7 @@ char *__fc_strtok_ptr; (valid_read_string(s) ∧ (∀ int i; 0 ≤ i < strlen(delim) ⇒ - strchr(s, *(delim + i)) ≡ (0 ≢ 0))); + ¬(strchr(s, *(delim + i)) ≡ \true))); ensures result_subset: \result ≡ \null ∨ \subset(\result, \old(s) + (0 ..)); @@ -1015,7 +1011,7 @@ char *strtok(char * restrict s, char const * restrict delim); (valid_read_string(s) ∧ (∀ int i; 0 ≤ i < strlen(delim) ⇒ - strchr(s, *(delim + i)) ≡ (0 ≢ 0))); + ¬(strchr(s, *(delim + i)) ≡ \true))); ensures result_subset: \result ≡ \null ∨ \subset(\result, \old(s) + (0 ..)); @@ -1032,7 +1028,7 @@ char *strtok(char * restrict s, char const * restrict delim); behavior resume_str: assumes s_null: s ≡ \null; requires not_first_call: *saveptr ≢ \null; - requires saveptr: initialization: \initialized(saveptr); + requires initialization: saveptr: \initialized(saveptr); ensures result_subset: \result ≡ \null ∨ \subset(\result, \old(*saveptr) + (0 ..)); @@ -1147,7 +1143,7 @@ char *stpcpy(char * restrict dest, char const * restrict src); ensures sum_of_lengths: strlen(\old(dest)) ≡ \old(strlen(dest) + strlen(src)); ensures - dest: initialization: + initialization: dest: \initialized(\old(dest) + (0 .. \old(strlen(dest) + strlen(src)))); ensures dest_null_terminated: @@ -1298,7 +1294,7 @@ char *strsignal(int signum); /*@ requires valid_memory_area: \valid((char *)s + (0 .. n - 1)); ensures - initialization: s_initialized: + s_initialized: initialization: \initialized((char *)\old(s) + (0 .. \old(n) - 1)); ensures zero_initialized: \subset(*((char *)\old(s) + (0 .. \old(n) - 1)), {0}); @@ -2580,7 +2576,7 @@ unsigned short *__fc_p_random48_counter = __fc_random48_counter; void srand48(long seed); /*@ requires - initialized_seed16v: initialization: \initialized(seed16v + (0 .. 2)); + initialization: initialized_seed16v: \initialized(seed16v + (0 .. 2)); ensures random48_initialized: __fc_random48_init ≡ 1; ensures result_counter: \result ≡ __fc_p_random48_counter; assigns __fc_random48_counter[0 .. 2], __fc_random48_init, \result; @@ -2608,7 +2604,7 @@ void lcong48(unsigned short param[7]); double drand48(void); /*@ requires - initialized_xsubi: initialization: \initialized(xsubi + (0 .. 2)); + initialization: initialized_xsubi: \initialized(xsubi + (0 .. 2)); ensures result_range: \is_finite(\result) ∧ 0.0 ≤ \result < 1.0; assigns __fc_random48_counter[0 .. 2], \result; assigns __fc_random48_counter[0 .. 2] @@ -2627,7 +2623,7 @@ double erand48(unsigned short xsubi[3]); long lrand48(void); /*@ requires - initialized_xsubi: initialization: \initialized(xsubi + (0 .. 2)); + initialization: initialized_xsubi: \initialized(xsubi + (0 .. 2)); ensures result_range: 0 ≤ \result < 2147483648; assigns __fc_random48_counter[0 .. 2], \result; assigns __fc_random48_counter[0 .. 2] @@ -2646,7 +2642,7 @@ long nrand48(unsigned short xsubi[3]); long mrand48(void); /*@ requires - initialized_xsubi: initialization: \initialized(xsubi + (0 .. 2)); + initialization: initialized_xsubi: \initialized(xsubi + (0 .. 2)); ensures result_range: -2147483648 ≤ \result < 2147483648; assigns __fc_random48_counter[0 .. 2], \result; assigns __fc_random48_counter[0 .. 2] @@ -2950,7 +2946,7 @@ int mblen(char const *s, size_t n); \from (indirect: s), *(s + (0 .. n - 1)), (indirect: n), __fc_mbtowc_state; */ -int mbtowc(long * restrict pwc, char const * restrict s, size_t n); +int mbtowc(wchar_t * restrict pwc, char const * restrict s, size_t n); /*@ ghost int __fc_wctomb_state; */ /*@ assigns \result, *(s + (0 ..)), __fc_wctomb_state; @@ -2958,7 +2954,7 @@ int mbtowc(long * restrict pwc, char const * restrict s, size_t n); assigns *(s + (0 ..)) \from wc, __fc_wctomb_state; assigns __fc_wctomb_state \from wc, __fc_wctomb_state; */ -int wctomb(char *s, long wc); +int wctomb(char *s, wchar_t wc); /*@ requires separation: \separated(pwcs, s); assigns \result, *(pwcs + (0 .. n - 1)); @@ -2967,7 +2963,7 @@ int wctomb(char *s, long wc); assigns *(pwcs + (0 .. n - 1)) \from (indirect: s), *(s + (0 .. n - 1)), (indirect: n); */ -size_t mbstowcs(long * restrict pwcs, char const * restrict s, size_t n); +size_t mbstowcs(wchar_t * restrict pwcs, char const * restrict s, size_t n); /*@ requires separation: \separated(s, pwcs); assigns \result, *(s + (0 .. n - 1)); @@ -2977,12 +2973,13 @@ size_t mbstowcs(long * restrict pwcs, char const * restrict s, size_t n); assigns *(s + (0 .. n - 1)) \from (indirect: pwcs), *(pwcs + (0 .. n - 1)), (indirect: n); */ -size_t wcstombs(char * restrict s, long const * restrict pwcs, size_t n); +size_t wcstombs(char * restrict s, wchar_t const * restrict pwcs, size_t n); /*@ requires valid_memptr: \valid(memptr); requires alignment_is_a_suitable_power_of_two: - alignment ≥ sizeof(void *) ∧ (alignment & alignment - 1) ≡ 0; + alignment ≥ sizeof(void *) ∧ + ((size_t)alignment & (size_t)alignment - 1) ≡ 0; assigns __fc_heap_status, \result; assigns __fc_heap_status \from (indirect: alignment), size, __fc_heap_status; diff --git a/tests/stl/oracle/stl_shared_ptr_mistake6.res.oracle b/tests/stl/oracle/stl_shared_ptr_mistake6.res.oracle index 31e6f7e6cf06a2c6eda81e4715b264cadf34ece8..e86ef322294f9b0b67701a27aec44f440580f4f2 100644 --- a/tests/stl/oracle/stl_shared_ptr_mistake6.res.oracle +++ b/tests/stl/oracle/stl_shared_ptr_mistake6.res.oracle @@ -53,6 +53,7 @@ struct piecewise_construct_t; struct piecewise_construct_t { }; +typedef long wchar_t; struct exception; struct bad_exception; struct nested_exception; @@ -304,7 +305,7 @@ axiomatic MemChr { ∀ char *s; ∀ ℤ c; ∀ ℤ n; - memchr(s, c, n) ≢ (0 ≢ 0) ⇔ + memchr(s, c, n) ≡ \true ⇔ (∃ int i; 0 ≤ i < n ∧ *(s + i) ≡ c); } @@ -318,7 +319,7 @@ axiomatic MemSet { ∀ char *s; ∀ ℤ c; ∀ ℤ n; - memset(s, c, n) ≢ (0 ≢ 0) ⇔ + memset(s, c, n) ≡ \true ⇔ (∀ ℤ i; 0 ≤ i < n ⇒ *(s + i) ≡ c); } @@ -331,33 +332,33 @@ axiomatic StrLen { axiom strlen_pos_or_null{L}: ∀ char *s; ∀ ℤ i; - 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ (char)0) ∧ - *(s + i) ≡ (char)0 ⇒ strlen(s) ≡ i; + 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ '\000') ∧ + *(s + i) ≡ '\000' ⇒ strlen(s) ≡ i; axiom strlen_neg{L}: ∀ char *s; - (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ (char)0) ⇒ strlen(s) < 0; + (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ '\000') ⇒ strlen(s) < 0; axiom strlen_before_null{L}: ∀ char *s; - ∀ ℤ i; 0 ≤ i < strlen(s) ⇒ *(s + i) ≢ (char)0; + ∀ ℤ i; 0 ≤ i < strlen(s) ⇒ *(s + i) ≢ '\000'; axiom strlen_at_null{L}: - ∀ char *s; 0 ≤ strlen(s) ⇒ *(s + strlen(s)) ≡ (char)0; + ∀ char *s; 0 ≤ strlen(s) ⇒ *(s + strlen(s)) ≡ '\000'; axiom strlen_not_zero{L}: ∀ char *s; ∀ ℤ i; - 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≢ (char)0 ⇒ i < strlen(s); + 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≢ '\000' ⇒ i < strlen(s); axiom strlen_zero{L}: ∀ char *s; ∀ ℤ i; - 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ (char)0 ⇒ i ≡ strlen(s); + 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ '\000' ⇒ i ≡ strlen(s); axiom strlen_sup{L}: ∀ char *s; - ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ (char)0 ⇒ 0 ≤ strlen(s) ≤ i; + ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ '\000' ⇒ 0 ≤ strlen(s) ≤ i; axiom strlen_shift{L}: ∀ char *s; @@ -365,14 +366,13 @@ axiomatic StrLen { axiom strlen_create{L}: ∀ char *s; - ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ (char)0 ⇒ 0 ≤ strlen(s) ≤ i; + ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ '\000' ⇒ 0 ≤ strlen(s) ≤ i; axiom strlen_create_shift{L}: ∀ char *s; ∀ ℤ i; ∀ ℤ k; - 0 ≤ k ≤ i ∧ *(s + i) ≡ (char)0 ⇒ - 0 ≤ strlen(s + k) ≤ i - k; + 0 ≤ k ≤ i ∧ *(s + i) ≡ '\000' ⇒ 0 ≤ strlen(s + k) ≤ i - k; axiom memcmp_strlen_left{L}: ∀ char *s1, char *s2; @@ -435,88 +435,84 @@ axiomatic StrChr { axiom strchr_def{L}: ∀ char *s; ∀ ℤ c; - strchr(s, c) ≢ (0 ≢ 0) ⇔ - (∃ ℤ i; 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ (char)((int)c)); + strchr(s, c) ≡ \true ⇔ + (∃ ℤ i; 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ (char)c); } */ /*@ axiomatic WMemChr { - logic 𔹠wmemchr{L}(long *s, long c, ℤ n) + logic 𔹠wmemchr{L}(wchar_t *s, wchar_t c, ℤ n) reads *(s + (0 .. n - 1)); - logic ℤ wmemchr_off{L}(long *s, long c, ℤ n) + logic ℤ wmemchr_off{L}(wchar_t *s, wchar_t c, ℤ n) reads *(s + (0 .. n - 1)); axiom wmemchr_def{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ long c; ∀ ℤ n; - wmemchr(s, c, n) ≢ (0 ≢ 0) ⇔ + wmemchr(s, c, n) ≡ \true ⇔ (∃ int i; 0 ≤ i < n ∧ *(s + i) ≡ c); } */ /*@ axiomatic WcsLen { - logic ℤ wcslen{L}(long *s) + logic ℤ wcslen{L}(wchar_t *s) reads *(s + (0 ..)); axiom wcslen_pos_or_null{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ ℤ i; - 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ (long)0) ∧ - *(s + i) ≡ (long)0 ⇒ wcslen(s) ≡ i; + 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ 0) ∧ + *(s + i) ≡ 0 ⇒ wcslen(s) ≡ i; axiom wcslen_neg{L}: - ∀ long *s; - (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ (long)0) ⇒ wcslen(s) < 0; + ∀ wchar_t *s; (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ 0) ⇒ wcslen(s) < 0; axiom wcslen_before_null{L}: - ∀ long *s; - ∀ int i; 0 ≤ i < wcslen(s) ⇒ *(s + i) ≢ (long)0; + ∀ wchar_t *s; + ∀ int i; 0 ≤ i < wcslen(s) ⇒ *(s + i) ≢ 0; axiom wcslen_at_null{L}: - ∀ long *s; 0 ≤ wcslen(s) ⇒ *(s + wcslen(s)) ≡ (long)0; + ∀ wchar_t *s; 0 ≤ wcslen(s) ⇒ *(s + wcslen(s)) ≡ 0; axiom wcslen_not_zero{L}: - ∀ long *s; - ∀ int i; - 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≢ (long)0 ⇒ i < wcslen(s); + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≢ 0 ⇒ i < wcslen(s); axiom wcslen_zero{L}: - ∀ long *s; - ∀ int i; - 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≡ (long)0 ⇒ i ≡ wcslen(s); + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≡ 0 ⇒ i ≡ wcslen(s); axiom wcslen_sup{L}: - ∀ long *s; - ∀ int i; 0 ≤ i ∧ *(s + i) ≡ (long)0 ⇒ 0 ≤ wcslen(s) ≤ i; + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ∧ *(s + i) ≡ 0 ⇒ 0 ≤ wcslen(s) ≤ i; axiom wcslen_shift{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ int i; 0 ≤ i ≤ wcslen(s) ⇒ wcslen(s + i) ≡ wcslen(s) - i; axiom wcslen_create{L}: - ∀ long *s; - ∀ int i; 0 ≤ i ∧ *(s + i) ≡ (long)0 ⇒ 0 ≤ wcslen(s) ≤ i; + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ∧ *(s + i) ≡ 0 ⇒ 0 ≤ wcslen(s) ≤ i; axiom wcslen_create_shift{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ int i; ∀ int k; - 0 ≤ k ≤ i ∧ *(s + i) ≡ (long)0 ⇒ - 0 ≤ wcslen(s + k) ≤ i - k; + 0 ≤ k ≤ i ∧ *(s + i) ≡ 0 ⇒ 0 ≤ wcslen(s + k) ≤ i - k; } */ /*@ axiomatic WcsCmp { - logic ℤ wcscmp{L}(long *s1, long *s2) + logic ℤ wcscmp{L}(wchar_t *s1, wchar_t *s2) reads *(s1 + (0 .. wcslen(s1))), *(s2 + (0 .. wcslen(s2))); axiom wcscmp_zero{L}: - ∀ long *s1, long *s2; + ∀ wchar_t *s1, wchar_t *s2; wcscmp(s1, s2) ≡ 0 ⇔ wcslen(s1) ≡ wcslen(s2) ∧ (∀ ℤ i; 0 ≤ i ≤ wcslen(s1) ⇒ *(s1 + i) ≡ *(s2 + i)); @@ -525,11 +521,11 @@ axiomatic WcsCmp { */ /*@ axiomatic WcsNCmp { - logic ℤ wcsncmp{L}(long *s1, long *s2, ℤ n) + logic ℤ wcsncmp{L}(wchar_t *s1, wchar_t *s2, ℤ n) reads *(s1 + (0 .. n - 1)), *(s2 + (0 .. n - 1)); axiom wcsncmp_zero{L}: - ∀ long *s1, long *s2; + ∀ wchar_t *s1, wchar_t *s2; ∀ ℤ n; wcsncmp(s1, s2, n) ≡ 0 ⇔ (wcslen(s1) < n ∧ wcscmp(s1, s2) ≡ 0) ∨ @@ -539,14 +535,14 @@ axiomatic WcsNCmp { */ /*@ axiomatic WcsChr { - logic 𔹠wcschr{L}(long *wcs, ℤ wc) + logic 𔹠wcschr{L}(wchar_t *wcs, ℤ wc) reads *(wcs + (0 .. wcslen(wcs))); axiom wcschr_def{L}: - ∀ long *wcs; + ∀ wchar_t *wcs; ∀ ℤ wc; - wcschr(wcs, wc) ≢ (0 ≢ 0) ⇔ - (∃ ℤ i; 0 ≤ i ≤ wcslen(wcs) ∧ *(wcs + i) ≡ (long)((int)wc)); + wcschr(wcs, wc) ≡ \true ⇔ + (∃ ℤ i; 0 ≤ i ≤ wcslen(wcs) ∧ *(wcs + i) ≡ (wchar_t)wc); } */ @@ -571,20 +567,20 @@ predicate valid_read_nstring{L}(char *s, ℤ n) = predicate valid_string_or_null{L}(char *s) = s ≡ \null ∨ valid_string(s); */ /*@ -predicate valid_wstring{L}(long *s) = +predicate valid_wstring{L}(wchar_t *s) = 0 ≤ wcslen(s) ∧ \valid(s + (0 .. wcslen(s))); */ /*@ -predicate valid_read_wstring{L}(long *s) = +predicate valid_read_wstring{L}(wchar_t *s) = 0 ≤ wcslen(s) ∧ \valid_read(s + (0 .. wcslen(s))); */ /*@ -predicate valid_read_nwstring{L}(long *s, ℤ n) = +predicate valid_read_nwstring{L}(wchar_t *s, ℤ n) = (\valid_read(s + (0 .. n - 1)) ∧ \initialized(s + (0 .. n - 1))) ∨ valid_read_wstring(s); */ /*@ -predicate valid_wstring_or_null{L}(long *s) = +predicate valid_wstring_or_null{L}(wchar_t *s) = s ≡ \null ∨ valid_wstring(s); */ @@ -666,10 +662,10 @@ predicate valid_read_or_empty{L}(void *s, size_t n) = */ /*@ requires valid_s1: valid_read_or_empty(s1, n); requires valid_s2: valid_read_or_empty(s2, n); - requires s1: initialization: \initialized((char *)s1 + (0 .. n - 1)); - requires s2: initialization: \initialized((char *)s2 + (0 .. n - 1)); - requires s1: danglingness: non_escaping(s1, n); - requires s2: danglingness: non_escaping(s2, n); + requires initialization: s1: \initialized((char *)s1 + (0 .. n - 1)); + requires initialization: s2: \initialized((char *)s2 + (0 .. n - 1)); + requires danglingness: s1: non_escaping(s1, n); + requires danglingness: s2: non_escaping(s2, n); ensures logic_spec: \result ≡ @@ -692,12 +688,12 @@ int memcmp(void const *s1, void const *s2, size_t n); requires danglingness: non_escaping(s, n) ∨ - non_escaping(s, (size_t)((int)(memchr_off((char *)s, c, n) + 1))); + non_escaping(s, (size_t)(memchr_off((char *)s, c, n) + 1)); assigns \result; assigns \result \from s, c, *((unsigned char *)s + (0 .. n - 1)); behavior found: - assumes char_found: memchr((char *)s, c, n) ≢ (0 ≢ 0); + assumes char_found: memchr((char *)s, c, n) ≡ \true; ensures result_same_base: \base_addr(\result) ≡ \base_addr(\old(s)); ensures result_char: (int)*((char *)\result) ≡ \old(c); ensures @@ -708,7 +704,7 @@ int memcmp(void const *s1, void const *s2, size_t n); (unsigned char *)\result ≤ (unsigned char *)\old(s) + i; behavior not_found: - assumes char_not_found: memchr((char *)s, c, n) ≡ (0 ≢ 0); + assumes char_not_found: ¬(memchr((char *)s, c, n) ≡ \true); ensures result_null: \result ≡ \null; */ void *memchr(void const *s, int c, size_t n); @@ -763,7 +759,7 @@ void *memmove(void *dest, void const *src, size_t n); /*@ requires valid_s: valid_or_empty(s, n); ensures - acsl_c_equiv: memset((char *)\old(s), \old(c), \old(n)) ≢ (0 ≢ 0); + acsl_c_equiv: memset((char *)\old(s), \old(c), \old(n)) ≡ \true; ensures result_ptr: \result ≡ \old(s); assigns *((char *)s + (0 .. n - 1)), \result; assigns *((char *)s + (0 .. n - 1)) \from c; @@ -819,7 +815,7 @@ int strcoll(char const *s1, char const *s2); \from s, (indirect: *(s + (0 .. strlen{Old}(s)))), (indirect: c); behavior found: - assumes char_found: strchr(s, c) ≢ (0 ≢ 0); + assumes char_found: strchr(s, c) ≡ \true; ensures result_char: *\result ≡ (char)\old(c); ensures result_same_base: \base_addr(\result) ≡ \base_addr(\old(s)); ensures @@ -830,7 +826,7 @@ int strcoll(char const *s1, char const *s2); ∀ char *p; \old(s) ≤ p < \result ⇒ *p ≢ (char)\old(c); behavior not_found: - assumes char_not_found: strchr(s, c) ≡ (0 ≢ 0); + assumes char_not_found: ¬(strchr(s, c) ≡ \true); ensures result_null: \result ≡ \null; behavior default: @@ -854,13 +850,13 @@ char *strchrnul(char const *s, int c); assigns \result \from s, *(s + (0 ..)), c; behavior found: - assumes char_found: strchr(s, c) ≢ (0 ≢ 0); + assumes char_found: strchr(s, c) ≡ \true; ensures result_char: (int)*\result ≡ \old(c); ensures result_same_base: \base_addr(\result) ≡ \base_addr(\old(s)); ensures result_valid_string: valid_read_string(\result); behavior not_found: - assumes char_not_found: strchr(s, c) ≡ (0 ≢ 0); + assumes char_not_found: ¬(strchr(s, c) ≡ \true); ensures result_null: \result ≡ \null; behavior default: @@ -954,7 +950,7 @@ char *__fc_strtok_ptr; (valid_read_string(s) ∧ (∀ int i; 0 ≤ i < strlen(delim) ⇒ - strchr(s, *(delim + i)) ≡ (0 ≢ 0))); + ¬(strchr(s, *(delim + i)) ≡ \true))); ensures result_subset: \result ≡ \null ∨ \subset(\result, \old(s) + (0 ..)); @@ -1016,7 +1012,7 @@ char *strtok(char * restrict s, char const * restrict delim); (valid_read_string(s) ∧ (∀ int i; 0 ≤ i < strlen(delim) ⇒ - strchr(s, *(delim + i)) ≡ (0 ≢ 0))); + ¬(strchr(s, *(delim + i)) ≡ \true))); ensures result_subset: \result ≡ \null ∨ \subset(\result, \old(s) + (0 ..)); @@ -1033,7 +1029,7 @@ char *strtok(char * restrict s, char const * restrict delim); behavior resume_str: assumes s_null: s ≡ \null; requires not_first_call: *saveptr ≢ \null; - requires saveptr: initialization: \initialized(saveptr); + requires initialization: saveptr: \initialized(saveptr); ensures result_subset: \result ≡ \null ∨ \subset(\result, \old(*saveptr) + (0 ..)); @@ -1148,7 +1144,7 @@ char *stpcpy(char * restrict dest, char const * restrict src); ensures sum_of_lengths: strlen(\old(dest)) ≡ \old(strlen(dest) + strlen(src)); ensures - dest: initialization: + initialization: dest: \initialized(\old(dest) + (0 .. \old(strlen(dest) + strlen(src)))); ensures dest_null_terminated: @@ -1299,7 +1295,7 @@ char *strsignal(int signum); /*@ requires valid_memory_area: \valid((char *)s + (0 .. n - 1)); ensures - initialization: s_initialized: + s_initialized: initialization: \initialized((char *)\old(s) + (0 .. \old(n) - 1)); ensures zero_initialized: \subset(*((char *)\old(s) + (0 .. \old(n) - 1)), {0}); @@ -2586,7 +2582,7 @@ unsigned short *__fc_p_random48_counter = __fc_random48_counter; void srand48(long seed); /*@ requires - initialized_seed16v: initialization: \initialized(seed16v + (0 .. 2)); + initialization: initialized_seed16v: \initialized(seed16v + (0 .. 2)); ensures random48_initialized: __fc_random48_init ≡ 1; ensures result_counter: \result ≡ __fc_p_random48_counter; assigns __fc_random48_counter[0 .. 2], __fc_random48_init, \result; @@ -2614,7 +2610,7 @@ void lcong48(unsigned short param[7]); double drand48(void); /*@ requires - initialized_xsubi: initialization: \initialized(xsubi + (0 .. 2)); + initialization: initialized_xsubi: \initialized(xsubi + (0 .. 2)); ensures result_range: \is_finite(\result) ∧ 0.0 ≤ \result < 1.0; assigns __fc_random48_counter[0 .. 2], \result; assigns __fc_random48_counter[0 .. 2] @@ -2633,7 +2629,7 @@ double erand48(unsigned short xsubi[3]); long lrand48(void); /*@ requires - initialized_xsubi: initialization: \initialized(xsubi + (0 .. 2)); + initialization: initialized_xsubi: \initialized(xsubi + (0 .. 2)); ensures result_range: 0 ≤ \result < 2147483648; assigns __fc_random48_counter[0 .. 2], \result; assigns __fc_random48_counter[0 .. 2] @@ -2652,7 +2648,7 @@ long nrand48(unsigned short xsubi[3]); long mrand48(void); /*@ requires - initialized_xsubi: initialization: \initialized(xsubi + (0 .. 2)); + initialization: initialized_xsubi: \initialized(xsubi + (0 .. 2)); ensures result_range: -2147483648 ≤ \result < 2147483648; assigns __fc_random48_counter[0 .. 2], \result; assigns __fc_random48_counter[0 .. 2] @@ -2956,7 +2952,7 @@ int mblen(char const *s, size_t n); \from (indirect: s), *(s + (0 .. n - 1)), (indirect: n), __fc_mbtowc_state; */ -int mbtowc(long * restrict pwc, char const * restrict s, size_t n); +int mbtowc(wchar_t * restrict pwc, char const * restrict s, size_t n); /*@ ghost int __fc_wctomb_state; */ /*@ assigns \result, *(s + (0 ..)), __fc_wctomb_state; @@ -2964,7 +2960,7 @@ int mbtowc(long * restrict pwc, char const * restrict s, size_t n); assigns *(s + (0 ..)) \from wc, __fc_wctomb_state; assigns __fc_wctomb_state \from wc, __fc_wctomb_state; */ -int wctomb(char *s, long wc); +int wctomb(char *s, wchar_t wc); /*@ requires separation: \separated(pwcs, s); assigns \result, *(pwcs + (0 .. n - 1)); @@ -2973,7 +2969,7 @@ int wctomb(char *s, long wc); assigns *(pwcs + (0 .. n - 1)) \from (indirect: s), *(s + (0 .. n - 1)), (indirect: n); */ -size_t mbstowcs(long * restrict pwcs, char const * restrict s, size_t n); +size_t mbstowcs(wchar_t * restrict pwcs, char const * restrict s, size_t n); /*@ requires separation: \separated(s, pwcs); assigns \result, *(s + (0 .. n - 1)); @@ -2983,12 +2979,13 @@ size_t mbstowcs(long * restrict pwcs, char const * restrict s, size_t n); assigns *(s + (0 .. n - 1)) \from (indirect: pwcs), *(pwcs + (0 .. n - 1)), (indirect: n); */ -size_t wcstombs(char * restrict s, long const * restrict pwcs, size_t n); +size_t wcstombs(char * restrict s, wchar_t const * restrict pwcs, size_t n); /*@ requires valid_memptr: \valid(memptr); requires alignment_is_a_suitable_power_of_two: - alignment ≥ sizeof(void *) ∧ (alignment & alignment - 1) ≡ 0; + alignment ≥ sizeof(void *) ∧ + ((size_t)alignment & (size_t)alignment - 1) ≡ 0; assigns __fc_heap_status, \result; assigns __fc_heap_status \from (indirect: alignment), size, __fc_heap_status; diff --git a/tests/stl/oracle/stl_system_error.res.oracle b/tests/stl/oracle/stl_system_error.res.oracle index 0edccd4ed5e3fa45d6746965895d992e839f8f08..27e8e63f101cc88d7d2714d1c8ca1db1f7599704 100644 --- a/tests/stl/oracle/stl_system_error.res.oracle +++ b/tests/stl/oracle/stl_system_error.res.oracle @@ -41,6 +41,7 @@ struct integral_constant<bool,1>; struct integral_constant<bool,1> { }; +typedef long wchar_t; struct exception; struct bad_exception; struct nested_exception; @@ -104,7 +105,7 @@ struct tm { int tm_isdst ; }; typedef char char_type; -typedef long char_type; +typedef wchar_t char_type; struct __shared_ref_base; struct piecewise_construct_t; struct piecewise_construct_t { @@ -266,7 +267,7 @@ axiomatic MemChr { ∀ char *s; ∀ ℤ c; ∀ ℤ n; - memchr(s, c, n) ≢ (0 ≢ 0) ⇔ + memchr(s, c, n) ≡ \true ⇔ (∃ int i; 0 ≤ i < n ∧ *(s + i) ≡ c); } @@ -280,7 +281,7 @@ axiomatic MemSet { ∀ char *s; ∀ ℤ c; ∀ ℤ n; - memset(s, c, n) ≢ (0 ≢ 0) ⇔ + memset(s, c, n) ≡ \true ⇔ (∀ ℤ i; 0 ≤ i < n ⇒ *(s + i) ≡ c); } @@ -293,33 +294,33 @@ axiomatic StrLen { axiom strlen_pos_or_null{L}: ∀ char *s; ∀ ℤ i; - 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ (char)0) ∧ - *(s + i) ≡ (char)0 ⇒ strlen(s) ≡ i; + 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ '\000') ∧ + *(s + i) ≡ '\000' ⇒ strlen(s) ≡ i; axiom strlen_neg{L}: ∀ char *s; - (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ (char)0) ⇒ strlen(s) < 0; + (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ '\000') ⇒ strlen(s) < 0; axiom strlen_before_null{L}: ∀ char *s; - ∀ ℤ i; 0 ≤ i < strlen(s) ⇒ *(s + i) ≢ (char)0; + ∀ ℤ i; 0 ≤ i < strlen(s) ⇒ *(s + i) ≢ '\000'; axiom strlen_at_null{L}: - ∀ char *s; 0 ≤ strlen(s) ⇒ *(s + strlen(s)) ≡ (char)0; + ∀ char *s; 0 ≤ strlen(s) ⇒ *(s + strlen(s)) ≡ '\000'; axiom strlen_not_zero{L}: ∀ char *s; ∀ ℤ i; - 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≢ (char)0 ⇒ i < strlen(s); + 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≢ '\000' ⇒ i < strlen(s); axiom strlen_zero{L}: ∀ char *s; ∀ ℤ i; - 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ (char)0 ⇒ i ≡ strlen(s); + 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ '\000' ⇒ i ≡ strlen(s); axiom strlen_sup{L}: ∀ char *s; - ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ (char)0 ⇒ 0 ≤ strlen(s) ≤ i; + ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ '\000' ⇒ 0 ≤ strlen(s) ≤ i; axiom strlen_shift{L}: ∀ char *s; @@ -327,14 +328,13 @@ axiomatic StrLen { axiom strlen_create{L}: ∀ char *s; - ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ (char)0 ⇒ 0 ≤ strlen(s) ≤ i; + ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ '\000' ⇒ 0 ≤ strlen(s) ≤ i; axiom strlen_create_shift{L}: ∀ char *s; ∀ ℤ i; ∀ ℤ k; - 0 ≤ k ≤ i ∧ *(s + i) ≡ (char)0 ⇒ - 0 ≤ strlen(s + k) ≤ i - k; + 0 ≤ k ≤ i ∧ *(s + i) ≡ '\000' ⇒ 0 ≤ strlen(s + k) ≤ i - k; axiom memcmp_strlen_left{L}: ∀ char *s1, char *s2; @@ -397,88 +397,84 @@ axiomatic StrChr { axiom strchr_def{L}: ∀ char *s; ∀ ℤ c; - strchr(s, c) ≢ (0 ≢ 0) ⇔ - (∃ ℤ i; 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ (char)((int)c)); + strchr(s, c) ≡ \true ⇔ + (∃ ℤ i; 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ (char)c); } */ /*@ axiomatic WMemChr { - logic 𔹠wmemchr{L}(long *s, long c, ℤ n) + logic 𔹠wmemchr{L}(wchar_t *s, wchar_t c, ℤ n) reads *(s + (0 .. n - 1)); - logic ℤ wmemchr_off{L}(long *s, long c, ℤ n) + logic ℤ wmemchr_off{L}(wchar_t *s, wchar_t c, ℤ n) reads *(s + (0 .. n - 1)); axiom wmemchr_def{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ long c; ∀ ℤ n; - wmemchr(s, c, n) ≢ (0 ≢ 0) ⇔ + wmemchr(s, c, n) ≡ \true ⇔ (∃ int i; 0 ≤ i < n ∧ *(s + i) ≡ c); } */ /*@ axiomatic WcsLen { - logic ℤ wcslen{L}(long *s) + logic ℤ wcslen{L}(wchar_t *s) reads *(s + (0 ..)); axiom wcslen_pos_or_null{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ ℤ i; - 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ (long)0) ∧ - *(s + i) ≡ (long)0 ⇒ wcslen(s) ≡ i; + 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ 0) ∧ + *(s + i) ≡ 0 ⇒ wcslen(s) ≡ i; axiom wcslen_neg{L}: - ∀ long *s; - (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ (long)0) ⇒ wcslen(s) < 0; + ∀ wchar_t *s; (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ 0) ⇒ wcslen(s) < 0; axiom wcslen_before_null{L}: - ∀ long *s; - ∀ int i; 0 ≤ i < wcslen(s) ⇒ *(s + i) ≢ (long)0; + ∀ wchar_t *s; + ∀ int i; 0 ≤ i < wcslen(s) ⇒ *(s + i) ≢ 0; axiom wcslen_at_null{L}: - ∀ long *s; 0 ≤ wcslen(s) ⇒ *(s + wcslen(s)) ≡ (long)0; + ∀ wchar_t *s; 0 ≤ wcslen(s) ⇒ *(s + wcslen(s)) ≡ 0; axiom wcslen_not_zero{L}: - ∀ long *s; - ∀ int i; - 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≢ (long)0 ⇒ i < wcslen(s); + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≢ 0 ⇒ i < wcslen(s); axiom wcslen_zero{L}: - ∀ long *s; - ∀ int i; - 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≡ (long)0 ⇒ i ≡ wcslen(s); + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≡ 0 ⇒ i ≡ wcslen(s); axiom wcslen_sup{L}: - ∀ long *s; - ∀ int i; 0 ≤ i ∧ *(s + i) ≡ (long)0 ⇒ 0 ≤ wcslen(s) ≤ i; + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ∧ *(s + i) ≡ 0 ⇒ 0 ≤ wcslen(s) ≤ i; axiom wcslen_shift{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ int i; 0 ≤ i ≤ wcslen(s) ⇒ wcslen(s + i) ≡ wcslen(s) - i; axiom wcslen_create{L}: - ∀ long *s; - ∀ int i; 0 ≤ i ∧ *(s + i) ≡ (long)0 ⇒ 0 ≤ wcslen(s) ≤ i; + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ∧ *(s + i) ≡ 0 ⇒ 0 ≤ wcslen(s) ≤ i; axiom wcslen_create_shift{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ int i; ∀ int k; - 0 ≤ k ≤ i ∧ *(s + i) ≡ (long)0 ⇒ - 0 ≤ wcslen(s + k) ≤ i - k; + 0 ≤ k ≤ i ∧ *(s + i) ≡ 0 ⇒ 0 ≤ wcslen(s + k) ≤ i - k; } */ /*@ axiomatic WcsCmp { - logic ℤ wcscmp{L}(long *s1, long *s2) + logic ℤ wcscmp{L}(wchar_t *s1, wchar_t *s2) reads *(s1 + (0 .. wcslen(s1))), *(s2 + (0 .. wcslen(s2))); axiom wcscmp_zero{L}: - ∀ long *s1, long *s2; + ∀ wchar_t *s1, wchar_t *s2; wcscmp(s1, s2) ≡ 0 ⇔ wcslen(s1) ≡ wcslen(s2) ∧ (∀ ℤ i; 0 ≤ i ≤ wcslen(s1) ⇒ *(s1 + i) ≡ *(s2 + i)); @@ -487,11 +483,11 @@ axiomatic WcsCmp { */ /*@ axiomatic WcsNCmp { - logic ℤ wcsncmp{L}(long *s1, long *s2, ℤ n) + logic ℤ wcsncmp{L}(wchar_t *s1, wchar_t *s2, ℤ n) reads *(s1 + (0 .. n - 1)), *(s2 + (0 .. n - 1)); axiom wcsncmp_zero{L}: - ∀ long *s1, long *s2; + ∀ wchar_t *s1, wchar_t *s2; ∀ ℤ n; wcsncmp(s1, s2, n) ≡ 0 ⇔ (wcslen(s1) < n ∧ wcscmp(s1, s2) ≡ 0) ∨ @@ -501,14 +497,14 @@ axiomatic WcsNCmp { */ /*@ axiomatic WcsChr { - logic 𔹠wcschr{L}(long *wcs, ℤ wc) + logic 𔹠wcschr{L}(wchar_t *wcs, ℤ wc) reads *(wcs + (0 .. wcslen(wcs))); axiom wcschr_def{L}: - ∀ long *wcs; + ∀ wchar_t *wcs; ∀ ℤ wc; - wcschr(wcs, wc) ≢ (0 ≢ 0) ⇔ - (∃ ℤ i; 0 ≤ i ≤ wcslen(wcs) ∧ *(wcs + i) ≡ (long)((int)wc)); + wcschr(wcs, wc) ≡ \true ⇔ + (∃ ℤ i; 0 ≤ i ≤ wcslen(wcs) ∧ *(wcs + i) ≡ (wchar_t)wc); } */ @@ -533,20 +529,20 @@ predicate valid_read_nstring{L}(char *s, ℤ n) = predicate valid_string_or_null{L}(char *s) = s ≡ \null ∨ valid_string(s); */ /*@ -predicate valid_wstring{L}(long *s) = +predicate valid_wstring{L}(wchar_t *s) = 0 ≤ wcslen(s) ∧ \valid(s + (0 .. wcslen(s))); */ /*@ -predicate valid_read_wstring{L}(long *s) = +predicate valid_read_wstring{L}(wchar_t *s) = 0 ≤ wcslen(s) ∧ \valid_read(s + (0 .. wcslen(s))); */ /*@ -predicate valid_read_nwstring{L}(long *s, ℤ n) = +predicate valid_read_nwstring{L}(wchar_t *s, ℤ n) = (\valid_read(s + (0 .. n - 1)) ∧ \initialized(s + (0 .. n - 1))) ∨ valid_read_wstring(s); */ /*@ -predicate valid_wstring_or_null{L}(long *s) = +predicate valid_wstring_or_null{L}(wchar_t *s) = s ≡ \null ∨ valid_wstring(s); */ /*@ ghost int __fc_heap_status; */ @@ -580,10 +576,10 @@ predicate valid_read_or_empty{L}(void *s, size_t n) = */ /*@ requires valid_s1: valid_read_or_empty(s1, n); requires valid_s2: valid_read_or_empty(s2, n); - requires s1: initialization: \initialized((char *)s1 + (0 .. n - 1)); - requires s2: initialization: \initialized((char *)s2 + (0 .. n - 1)); - requires s1: danglingness: non_escaping(s1, n); - requires s2: danglingness: non_escaping(s2, n); + requires initialization: s1: \initialized((char *)s1 + (0 .. n - 1)); + requires initialization: s2: \initialized((char *)s2 + (0 .. n - 1)); + requires danglingness: s1: non_escaping(s1, n); + requires danglingness: s2: non_escaping(s2, n); ensures logic_spec: \result ≡ @@ -606,12 +602,12 @@ int memcmp(void const *s1, void const *s2, size_t n); requires danglingness: non_escaping(s, n) ∨ - non_escaping(s, (size_t)((int)(memchr_off((char *)s, c, n) + 1))); + non_escaping(s, (size_t)(memchr_off((char *)s, c, n) + 1)); assigns \result; assigns \result \from s, c, *((unsigned char *)s + (0 .. n - 1)); behavior found: - assumes char_found: memchr((char *)s, c, n) ≢ (0 ≢ 0); + assumes char_found: memchr((char *)s, c, n) ≡ \true; ensures result_same_base: \base_addr(\result) ≡ \base_addr(\old(s)); ensures result_char: (int)*((char *)\result) ≡ \old(c); ensures @@ -622,7 +618,7 @@ int memcmp(void const *s1, void const *s2, size_t n); (unsigned char *)\result ≤ (unsigned char *)\old(s) + i; behavior not_found: - assumes char_not_found: memchr((char *)s, c, n) ≡ (0 ≢ 0); + assumes char_not_found: ¬(memchr((char *)s, c, n) ≡ \true); ensures result_null: \result ≡ \null; */ void *memchr(void const *s, int c, size_t n); @@ -677,7 +673,7 @@ void *memmove(void *dest, void const *src, size_t n); /*@ requires valid_s: valid_or_empty(s, n); ensures - acsl_c_equiv: memset((char *)\old(s), \old(c), \old(n)) ≢ (0 ≢ 0); + acsl_c_equiv: memset((char *)\old(s), \old(c), \old(n)) ≡ \true; ensures result_ptr: \result ≡ \old(s); assigns *((char *)s + (0 .. n - 1)), \result; assigns *((char *)s + (0 .. n - 1)) \from c; @@ -733,7 +729,7 @@ int strcoll(char const *s1, char const *s2); \from s, (indirect: *(s + (0 .. strlen{Old}(s)))), (indirect: c); behavior found: - assumes char_found: strchr(s, c) ≢ (0 ≢ 0); + assumes char_found: strchr(s, c) ≡ \true; ensures result_char: *\result ≡ (char)\old(c); ensures result_same_base: \base_addr(\result) ≡ \base_addr(\old(s)); ensures @@ -744,7 +740,7 @@ int strcoll(char const *s1, char const *s2); ∀ char *p; \old(s) ≤ p < \result ⇒ *p ≢ (char)\old(c); behavior not_found: - assumes char_not_found: strchr(s, c) ≡ (0 ≢ 0); + assumes char_not_found: ¬(strchr(s, c) ≡ \true); ensures result_null: \result ≡ \null; behavior default: @@ -768,13 +764,13 @@ char *strchrnul(char const *s, int c); assigns \result \from s, *(s + (0 ..)), c; behavior found: - assumes char_found: strchr(s, c) ≢ (0 ≢ 0); + assumes char_found: strchr(s, c) ≡ \true; ensures result_char: (int)*\result ≡ \old(c); ensures result_same_base: \base_addr(\result) ≡ \base_addr(\old(s)); ensures result_valid_string: valid_read_string(\result); behavior not_found: - assumes char_not_found: strchr(s, c) ≡ (0 ≢ 0); + assumes char_not_found: ¬(strchr(s, c) ≡ \true); ensures result_null: \result ≡ \null; behavior default: @@ -868,7 +864,7 @@ char *__fc_strtok_ptr; (valid_read_string(s) ∧ (∀ int i; 0 ≤ i < strlen(delim) ⇒ - strchr(s, *(delim + i)) ≡ (0 ≢ 0))); + ¬(strchr(s, *(delim + i)) ≡ \true))); ensures result_subset: \result ≡ \null ∨ \subset(\result, \old(s) + (0 ..)); @@ -930,7 +926,7 @@ char *strtok(char * restrict s, char const * restrict delim); (valid_read_string(s) ∧ (∀ int i; 0 ≤ i < strlen(delim) ⇒ - strchr(s, *(delim + i)) ≡ (0 ≢ 0))); + ¬(strchr(s, *(delim + i)) ≡ \true))); ensures result_subset: \result ≡ \null ∨ \subset(\result, \old(s) + (0 ..)); @@ -947,7 +943,7 @@ char *strtok(char * restrict s, char const * restrict delim); behavior resume_str: assumes s_null: s ≡ \null; requires not_first_call: *saveptr ≢ \null; - requires saveptr: initialization: \initialized(saveptr); + requires initialization: saveptr: \initialized(saveptr); ensures result_subset: \result ≡ \null ∨ \subset(\result, \old(*saveptr) + (0 ..)); @@ -1062,7 +1058,7 @@ char *stpcpy(char * restrict dest, char const * restrict src); ensures sum_of_lengths: strlen(\old(dest)) ≡ \old(strlen(dest) + strlen(src)); ensures - dest: initialization: + initialization: dest: \initialized(\old(dest) + (0 .. \old(strlen(dest) + strlen(src)))); ensures dest_null_terminated: @@ -1213,7 +1209,7 @@ char *strsignal(int signum); /*@ requires valid_memory_area: \valid((char *)s + (0 .. n - 1)); ensures - initialization: s_initialized: + s_initialized: initialization: \initialized((char *)\old(s) + (0 .. \old(n) - 1)); ensures zero_initialized: \subset(*((char *)\old(s) + (0 .. \old(n) - 1)), {0}); @@ -1602,7 +1598,7 @@ void (*signal(int sig, void (*func)(int )))(int ); int raise(int sig); /*@ requires valid_set: \valid(set); - ensures set: initialization: \initialized(\old(set)); + ensures initialization: set: \initialized(\old(set)); ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; assigns *set, \result; assigns *set \from \nothing; @@ -1611,7 +1607,7 @@ int raise(int sig); int sigemptyset(sigset_t *set); /*@ requires valid_set: \valid(set); - ensures set: initialization: \initialized(\old(set)); + ensures initialization: set: \initialized(\old(set)); ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; assigns *set, \result; assigns *set \from \nothing; @@ -1620,7 +1616,7 @@ int sigemptyset(sigset_t *set); int sigfillset(sigset_t *set); /*@ requires valid_set: \valid(set); - requires set: initialization: \initialized(set); + requires initialization: set: \initialized(set); ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; assigns *set, \result; assigns *set \from (indirect: signum); @@ -1629,7 +1625,7 @@ int sigfillset(sigset_t *set); int sigaddset(sigset_t *set, int signum); /*@ requires valid_set: \valid(set); - requires set: initialization: \initialized(set); + requires initialization: set: \initialized(set); ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; assigns *set, \result; assigns *set \from (indirect: signum); @@ -1638,7 +1634,7 @@ int sigaddset(sigset_t *set, int signum); int sigdelset(sigset_t *set, int signum); /*@ requires valid_read_set: \valid_read(set); - requires set: initialization: \initialized(set); + requires initialization: set: \initialized(set); ensures result_found_not_found_or_error: \result ≡ 0 ∨ \result ≡ 1 ∨ \result ≡ -1; @@ -1652,7 +1648,7 @@ struct sigaction *__fc_p_sigaction = __fc_sigaction; /*@ requires valid_signal: 0 ≤ signum ≤ 64; requires valid_oldact_or_null: oldact ≡ \null ∨ \valid(oldact); requires valid_read_act_or_null: act ≡ \null ∨ \valid_read(act); - requires separated_acts: separation: \separated(act, oldact); + requires separation: separated_acts: \separated(act, oldact); ensures act_changed: \old(act) ≡ \null ∨ @@ -1727,7 +1723,7 @@ time_t mktime(struct tm *timeptr); behavior not_null: assumes timer_non_null: timer ≢ \null; requires valid_timer: \valid(timer); - ensures timer: initialization: \initialized(\old(timer)); + ensures initialization: timer: \initialized(\old(timer)); assigns *timer, \result; assigns *timer \from __fc_time; assigns \result \from __fc_time; @@ -1740,7 +1736,7 @@ time_t time(time_t *timer); char __fc_ctime[26]; char * const __fc_p_ctime = __fc_ctime; /*@ requires valid_timeptr: \valid_read(timeptr); - requires init_timeptr: initialization: \initialized(timeptr); + requires initialization: init_timeptr: \initialized(timeptr); ensures result_points_to_ctime: \result ≡ __fc_p_ctime; ensures result_valid_string: valid_read_string(__fc_p_ctime); assigns __fc_ctime[0 .. 25], \result; @@ -1752,7 +1748,7 @@ char * const __fc_p_ctime = __fc_ctime; char *asctime(struct tm const *timeptr); /*@ requires valid_timer: \valid_read(timer); - requires init_timer: initialization: \initialized(timer); + requires initialization: init_timer: \initialized(timer); ensures result_points_to_ctime: \result ≡ __fc_p_ctime; ensures result_valid_string: valid_read_string(__fc_p_ctime); assigns __fc_ctime[0 .. 25], \result; @@ -1850,7 +1846,7 @@ axiomatic nanosleep_predicates { /*@ ghost int volatile __fc_interrupted; */ /*@ requires valid_request: \valid_read(rqtp); requires - initialized_request: initialization: + initialization: initialized_request: \initialized(&rqtp->tv_sec) ∧ \initialized(&rqtp->tv_nsec); requires valid_nanosecs: 0 ≤ rqtp->tv_nsec < 1000000000; requires valid_remaining_or_null: rmtp ≡ \null ∨ \valid(rmtp); @@ -1880,7 +1876,7 @@ axiomatic nanosleep_predicates { assumes no_einval: valid_clock_id(clock_id); ensures result_interrupted: \result ≡ 4; ensures - interrupted_remaining: initialization: + initialization: interrupted_remaining: \old(rmtp) ≢ \null ⇒ \initialized(&\old(rmtp)->tv_sec) ∧ \initialized(&\old(rmtp)->tv_nsec); @@ -1946,7 +1942,7 @@ struct tm *gmtime_r(time_t const * restrict timer, /*@ requires valid_timer: \valid_read(timep); requires valid_result: \valid(result); ensures - initialization: result_null_or_initialized: + result_null_or_initialized: initialization: (\result ≡ \old(result) ∧ \initialized(\old(result))) ∨ \result ≡ \null; ensures @@ -1961,13 +1957,13 @@ struct tm *localtime_r(time_t const * restrict timep, /*@ requires valid_request: \valid_read(rqtp); requires - initialized_request: initialization: + initialization: initialized_request: \initialized(&rqtp->tv_sec) ∧ \initialized(&rqtp->tv_nsec); requires valid_nanosecs: 0 ≤ rqtp->tv_nsec < 1000000000; requires valid_remaining_or_null: rmtp ≡ \null ∨ \valid(rmtp); ensures result_elapsed_or_interrupted: \result ≡ 0 ∨ \result ≡ -1; ensures - interrupted_remaining: initialization: + initialization: interrupted_remaining: \old(rmtp) ≢ \null ∧ \result ≡ -1 ⇒ \initialized(&\old(rmtp)->tv_sec) ∧ \initialized(&\old(rmtp)->tv_nsec); @@ -2005,19 +2001,19 @@ void tzset(void); \from *(src + (0 .. n - 1)), (indirect: src), (indirect: n); assigns \result \from dest; */ -long *wmemmove(long *dest, long const *src, size_t n); +wchar_t *wmemmove(wchar_t *dest, wchar_t const *src, size_t n); /*@ requires valid_wcs: \valid(wcs + (0 .. n - 1)); ensures result_ptr: \result ≡ \old(wcs); ensures - wcs: initialization: \initialized(\old(wcs) + (0 .. \old(n) - 1)); + initialization: wcs: \initialized(\old(wcs) + (0 .. \old(n) - 1)); ensures contents_equal_wc: \subset(*(\old(wcs) + (0 .. \old(n) - 1)), \old(wc)); assigns *(wcs + (0 .. n - 1)), \result; assigns *(wcs + (0 .. n - 1)) \from wc, (indirect: n); assigns \result \from wcs; */ -long *wmemset(long *wcs, long wc, size_t n); +wchar_t *wmemset(wchar_t *wcs, wchar_t wc, size_t n); /*@ requires valid_wstring_src: valid_read_wstring(src); requires valid_wstring_dest: valid_wstring(dest); @@ -2036,7 +2032,7 @@ long *wmemset(long *wcs, long wc, size_t n); (indirect: src); assigns \result \from dest; */ -long *wcscat(long * restrict dest, long const * restrict src); +wchar_t *wcscat(wchar_t * restrict dest, wchar_t const * restrict src); /*@ requires valid_wstring_src: valid_read_wstring(wcs); ensures @@ -2045,7 +2041,7 @@ long *wcscat(long * restrict dest, long const * restrict src); assigns \result; assigns \result \from wcs, (indirect: *(wcs + (0 ..))), (indirect: wc); */ -long *wcschr(long const *wcs, long wc); +wchar_t *wcschr(wchar_t const *wcs, wchar_t wc); /*@ requires valid_wstring_s1: valid_read_wstring(s1); requires valid_wstring_s2: valid_read_wstring(s2); @@ -2053,7 +2049,7 @@ long *wcschr(long const *wcs, long wc); assigns \result \from (indirect: *(s1 + (0 ..))), (indirect: *(s2 + (0 ..))); */ -int wcscmp(long const *s1, long const *s2); +int wcscmp(wchar_t const *s1, wchar_t const *s2); /*@ requires valid_wstring_src: valid_read_wstring(src); requires room_wstring: \valid(dest + (0 .. wcslen(src))); @@ -2066,7 +2062,7 @@ int wcscmp(long const *s1, long const *s2); \from *(src + (0 .. wcslen{Old}(src))), (indirect: src); assigns \result \from dest; */ -long *wcscpy(long * restrict dest, long const * restrict src); +wchar_t *wcscpy(wchar_t * restrict dest, wchar_t const * restrict src); /*@ requires valid_wstring_wcs: valid_read_wstring(wcs); requires valid_wstring_accept: valid_read_wstring(accept); @@ -2074,7 +2070,7 @@ long *wcscpy(long * restrict dest, long const * restrict src); assigns \result \from (indirect: *(wcs + (0 ..))), (indirect: *(accept + (0 ..))); */ -size_t wcscspn(long const *wcs, long const *accept); +size_t wcscspn(wchar_t const *wcs, wchar_t const *accept); /*@ requires valid_nwstring_src: valid_read_nwstring(src, n); requires valid_wstring_dest: valid_wstring(dest); @@ -2094,12 +2090,13 @@ size_t wcscspn(long const *wcs, long const *accept); \from (indirect: *(dest + (0 ..))), (indirect: *(src + (0 .. n - 1))), (indirect: n); */ -size_t wcslcat(long * restrict dest, long const * restrict src, size_t n); +size_t wcslcat(wchar_t * restrict dest, wchar_t const * restrict src, + size_t n); /*@ requires valid_wstring_src: valid_read_wstring(src); requires room_nwstring: \valid(dest + (0 .. n)); requires - src: dest: separation: + separation: dest: src: \separated(dest + (0 .. n - 1), src + (0 .. n - 1)); assigns *(dest + (0 .. n - 1)), \result; assigns *(dest + (0 .. n - 1)) @@ -2108,14 +2105,14 @@ size_t wcslcat(long * restrict dest, long const * restrict src, size_t n); \from (indirect: *(dest + (0 .. n - 1))), (indirect: dest), (indirect: *(src + (0 .. n - 1))), (indirect: src), (indirect: n); */ -size_t wcslcpy(long *dest, long const *src, size_t n); +size_t wcslcpy(wchar_t *dest, wchar_t const *src, size_t n); /*@ requires valid_string_s: valid_read_wstring(s); ensures result_is_length: \result ≡ wcslen(\old(s)); assigns \result; assigns \result \from (indirect: *(s + (0 .. wcslen{Old}(s)))); */ -size_t wcslen(long const *s); +size_t wcslen(wchar_t const *s); /*@ requires valid_nwstring_src: valid_read_nwstring(src, n); requires valid_wstring_dest: valid_wstring(dest); @@ -2134,7 +2131,8 @@ size_t wcslen(long const *s); (indirect: src), (indirect: n); assigns \result \from dest; */ -long *wcsncat(long * restrict dest, long const * restrict src, size_t n); +wchar_t *wcsncat(wchar_t * restrict dest, wchar_t const * restrict src, + size_t n); /*@ requires valid_wstring_s1: valid_read_wstring(s1); requires valid_wstring_s2: valid_read_wstring(s2); @@ -2143,12 +2141,12 @@ long *wcsncat(long * restrict dest, long const * restrict src, size_t n); \from (indirect: *(s1 + (0 .. n - 1))), (indirect: *(s2 + (0 .. n - 1))), (indirect: n); */ -int wcsncmp(long const *s1, long const *s2, size_t n); +int wcsncmp(wchar_t const *s1, wchar_t const *s2, size_t n); /*@ requires valid_wstring_src: valid_read_wstring(src); requires room_nwstring: \valid(dest + (0 .. n - 1)); requires - src: dest: separation: + separation: dest: src: \separated(dest + (0 .. n - 1), src + (0 .. n - 1)); ensures result_ptr: \result ≡ \old(dest); ensures initialization: \initialized(\old(dest) + (0 .. \old(n) - 1)); @@ -2157,7 +2155,8 @@ int wcsncmp(long const *s1, long const *s2, size_t n); \from *(src + (0 .. n - 1)), (indirect: src), (indirect: n); assigns \result \from dest; */ -long *wcsncpy(long * restrict dest, long const * restrict src, size_t n); +wchar_t *wcsncpy(wchar_t * restrict dest, wchar_t const * restrict src, + size_t n); /*@ requires valid_wstring_wcs: valid_read_wstring(wcs); requires valid_wstring_accept: valid_read_wstring(accept); @@ -2168,7 +2167,7 @@ long *wcsncpy(long * restrict dest, long const * restrict src, size_t n); assigns \result \from wcs, (indirect: *(wcs + (0 ..))), (indirect: *(accept + (0 ..))); */ -long *wcspbrk(long const *wcs, long const *accept); +wchar_t *wcspbrk(wchar_t const *wcs, wchar_t const *accept); /*@ requires valid_wstring_wcs: valid_read_wstring(wcs); ensures @@ -2178,7 +2177,7 @@ long *wcspbrk(long const *wcs, long const *accept); assigns \result \from wcs, (indirect: *(wcs + (0 .. wcslen{Old}(wcs)))), (indirect: wc); */ -long *wcsrchr(long const *wcs, long wc); +wchar_t *wcsrchr(wchar_t const *wcs, wchar_t wc); /*@ requires valid_wstring_wcs: valid_read_wstring(wcs); requires valid_wstring_accept: valid_read_wstring(accept); @@ -2187,7 +2186,7 @@ long *wcsrchr(long const *wcs, long wc); \from (indirect: *(wcs + (0 .. wcslen{Old}(wcs)))), (indirect: *(accept + (0 .. wcslen{Old}(accept)))); */ -size_t wcsspn(long const *wcs, long const *accept); +size_t wcsspn(wchar_t const *wcs, wchar_t const *accept); /*@ requires valid_wstring_haystack: valid_read_wstring(haystack); requires valid_wstring_needle: valid_read_wstring(needle); @@ -2199,7 +2198,7 @@ size_t wcsspn(long const *wcs, long const *accept); \from haystack, (indirect: *(haystack + (0 ..))), (indirect: *(needle + (0 ..))); */ -long *wcsstr(long const *haystack, long const *needle); +wchar_t *wcsstr(wchar_t const *haystack, wchar_t const *needle); /*@ requires room_nwstring: \valid(ws + (0 .. n - 1)); requires valid_stream: \valid(stream); @@ -2211,10 +2210,10 @@ long *wcsstr(long const *haystack, long const *needle); assigns *(ws + (0 .. n - 1)) \from (indirect: n), (indirect: *stream); assigns \result \from ws, (indirect: n), (indirect: *stream); */ -long *fgetws(long * restrict ws, int n, FILE * restrict stream); +wchar_t *fgetws(wchar_t * restrict ws, int n, FILE * restrict stream); /*@ axiomatic wformat_length { - logic ℤ wformat_length{L}(long *format) ; + logic ℤ wformat_length{L}(wchar_t *format) ; } @@ -2225,7 +2224,7 @@ long *fgetws(long * restrict ws, int n, FILE * restrict stream); assigns \result \from (indirect: *(ws1 + (0 ..))), (indirect: *(ws2 + (0 ..))); */ -int wcscasecmp(long const *ws1, long const *ws2); +int wcscasecmp(wchar_t const *ws1, wchar_t const *ws2); struct _frama_c_rtti_name_info_node _frama_c_rtti_name_info; diff --git a/tests/stl/oracle/stl_typeinfo.res.oracle b/tests/stl/oracle/stl_typeinfo.res.oracle index 32844fea1e0495bce92c9ec67e770ef9132f377b..cb9575f6bac93915b3070303f9dcfb6ae9950c90 100644 --- a/tests/stl/oracle/stl_typeinfo.res.oracle +++ b/tests/stl/oracle/stl_typeinfo.res.oracle @@ -33,6 +33,7 @@ struct _frama_c_rtti_name_info_node { }; typedef unsigned int size_t; typedef size_t size_t; +typedef long wchar_t; struct exception; struct bad_exception; struct nested_exception; @@ -124,7 +125,7 @@ axiomatic MemChr { ∀ char *s; ∀ ℤ c; ∀ ℤ n; - memchr(s, c, n) ≢ (0 ≢ 0) ⇔ + memchr(s, c, n) ≡ \true ⇔ (∃ int i; 0 ≤ i < n ∧ *(s + i) ≡ c); } @@ -138,7 +139,7 @@ axiomatic MemSet { ∀ char *s; ∀ ℤ c; ∀ ℤ n; - memset(s, c, n) ≢ (0 ≢ 0) ⇔ + memset(s, c, n) ≡ \true ⇔ (∀ ℤ i; 0 ≤ i < n ⇒ *(s + i) ≡ c); } @@ -151,33 +152,33 @@ axiomatic StrLen { axiom strlen_pos_or_null{L}: ∀ char *s; ∀ ℤ i; - 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ (char)0) ∧ - *(s + i) ≡ (char)0 ⇒ strlen(s) ≡ i; + 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ '\000') ∧ + *(s + i) ≡ '\000' ⇒ strlen(s) ≡ i; axiom strlen_neg{L}: ∀ char *s; - (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ (char)0) ⇒ strlen(s) < 0; + (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ '\000') ⇒ strlen(s) < 0; axiom strlen_before_null{L}: ∀ char *s; - ∀ ℤ i; 0 ≤ i < strlen(s) ⇒ *(s + i) ≢ (char)0; + ∀ ℤ i; 0 ≤ i < strlen(s) ⇒ *(s + i) ≢ '\000'; axiom strlen_at_null{L}: - ∀ char *s; 0 ≤ strlen(s) ⇒ *(s + strlen(s)) ≡ (char)0; + ∀ char *s; 0 ≤ strlen(s) ⇒ *(s + strlen(s)) ≡ '\000'; axiom strlen_not_zero{L}: ∀ char *s; ∀ ℤ i; - 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≢ (char)0 ⇒ i < strlen(s); + 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≢ '\000' ⇒ i < strlen(s); axiom strlen_zero{L}: ∀ char *s; ∀ ℤ i; - 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ (char)0 ⇒ i ≡ strlen(s); + 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ '\000' ⇒ i ≡ strlen(s); axiom strlen_sup{L}: ∀ char *s; - ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ (char)0 ⇒ 0 ≤ strlen(s) ≤ i; + ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ '\000' ⇒ 0 ≤ strlen(s) ≤ i; axiom strlen_shift{L}: ∀ char *s; @@ -185,14 +186,13 @@ axiomatic StrLen { axiom strlen_create{L}: ∀ char *s; - ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ (char)0 ⇒ 0 ≤ strlen(s) ≤ i; + ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ '\000' ⇒ 0 ≤ strlen(s) ≤ i; axiom strlen_create_shift{L}: ∀ char *s; ∀ ℤ i; ∀ ℤ k; - 0 ≤ k ≤ i ∧ *(s + i) ≡ (char)0 ⇒ - 0 ≤ strlen(s + k) ≤ i - k; + 0 ≤ k ≤ i ∧ *(s + i) ≡ '\000' ⇒ 0 ≤ strlen(s + k) ≤ i - k; axiom memcmp_strlen_left{L}: ∀ char *s1, char *s2; @@ -255,88 +255,84 @@ axiomatic StrChr { axiom strchr_def{L}: ∀ char *s; ∀ ℤ c; - strchr(s, c) ≢ (0 ≢ 0) ⇔ - (∃ ℤ i; 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ (char)((int)c)); + strchr(s, c) ≡ \true ⇔ + (∃ ℤ i; 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ (char)c); } */ /*@ axiomatic WMemChr { - logic 𔹠wmemchr{L}(long *s, long c, ℤ n) + logic 𔹠wmemchr{L}(wchar_t *s, wchar_t c, ℤ n) reads *(s + (0 .. n - 1)); - logic ℤ wmemchr_off{L}(long *s, long c, ℤ n) + logic ℤ wmemchr_off{L}(wchar_t *s, wchar_t c, ℤ n) reads *(s + (0 .. n - 1)); axiom wmemchr_def{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ long c; ∀ ℤ n; - wmemchr(s, c, n) ≢ (0 ≢ 0) ⇔ + wmemchr(s, c, n) ≡ \true ⇔ (∃ int i; 0 ≤ i < n ∧ *(s + i) ≡ c); } */ /*@ axiomatic WcsLen { - logic ℤ wcslen{L}(long *s) + logic ℤ wcslen{L}(wchar_t *s) reads *(s + (0 ..)); axiom wcslen_pos_or_null{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ ℤ i; - 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ (long)0) ∧ - *(s + i) ≡ (long)0 ⇒ wcslen(s) ≡ i; + 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ 0) ∧ + *(s + i) ≡ 0 ⇒ wcslen(s) ≡ i; axiom wcslen_neg{L}: - ∀ long *s; - (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ (long)0) ⇒ wcslen(s) < 0; + ∀ wchar_t *s; (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ 0) ⇒ wcslen(s) < 0; axiom wcslen_before_null{L}: - ∀ long *s; - ∀ int i; 0 ≤ i < wcslen(s) ⇒ *(s + i) ≢ (long)0; + ∀ wchar_t *s; + ∀ int i; 0 ≤ i < wcslen(s) ⇒ *(s + i) ≢ 0; axiom wcslen_at_null{L}: - ∀ long *s; 0 ≤ wcslen(s) ⇒ *(s + wcslen(s)) ≡ (long)0; + ∀ wchar_t *s; 0 ≤ wcslen(s) ⇒ *(s + wcslen(s)) ≡ 0; axiom wcslen_not_zero{L}: - ∀ long *s; - ∀ int i; - 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≢ (long)0 ⇒ i < wcslen(s); + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≢ 0 ⇒ i < wcslen(s); axiom wcslen_zero{L}: - ∀ long *s; - ∀ int i; - 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≡ (long)0 ⇒ i ≡ wcslen(s); + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≡ 0 ⇒ i ≡ wcslen(s); axiom wcslen_sup{L}: - ∀ long *s; - ∀ int i; 0 ≤ i ∧ *(s + i) ≡ (long)0 ⇒ 0 ≤ wcslen(s) ≤ i; + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ∧ *(s + i) ≡ 0 ⇒ 0 ≤ wcslen(s) ≤ i; axiom wcslen_shift{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ int i; 0 ≤ i ≤ wcslen(s) ⇒ wcslen(s + i) ≡ wcslen(s) - i; axiom wcslen_create{L}: - ∀ long *s; - ∀ int i; 0 ≤ i ∧ *(s + i) ≡ (long)0 ⇒ 0 ≤ wcslen(s) ≤ i; + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ∧ *(s + i) ≡ 0 ⇒ 0 ≤ wcslen(s) ≤ i; axiom wcslen_create_shift{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ int i; ∀ int k; - 0 ≤ k ≤ i ∧ *(s + i) ≡ (long)0 ⇒ - 0 ≤ wcslen(s + k) ≤ i - k; + 0 ≤ k ≤ i ∧ *(s + i) ≡ 0 ⇒ 0 ≤ wcslen(s + k) ≤ i - k; } */ /*@ axiomatic WcsCmp { - logic ℤ wcscmp{L}(long *s1, long *s2) + logic ℤ wcscmp{L}(wchar_t *s1, wchar_t *s2) reads *(s1 + (0 .. wcslen(s1))), *(s2 + (0 .. wcslen(s2))); axiom wcscmp_zero{L}: - ∀ long *s1, long *s2; + ∀ wchar_t *s1, wchar_t *s2; wcscmp(s1, s2) ≡ 0 ⇔ wcslen(s1) ≡ wcslen(s2) ∧ (∀ ℤ i; 0 ≤ i ≤ wcslen(s1) ⇒ *(s1 + i) ≡ *(s2 + i)); @@ -345,11 +341,11 @@ axiomatic WcsCmp { */ /*@ axiomatic WcsNCmp { - logic ℤ wcsncmp{L}(long *s1, long *s2, ℤ n) + logic ℤ wcsncmp{L}(wchar_t *s1, wchar_t *s2, ℤ n) reads *(s1 + (0 .. n - 1)), *(s2 + (0 .. n - 1)); axiom wcsncmp_zero{L}: - ∀ long *s1, long *s2; + ∀ wchar_t *s1, wchar_t *s2; ∀ ℤ n; wcsncmp(s1, s2, n) ≡ 0 ⇔ (wcslen(s1) < n ∧ wcscmp(s1, s2) ≡ 0) ∨ @@ -359,14 +355,14 @@ axiomatic WcsNCmp { */ /*@ axiomatic WcsChr { - logic 𔹠wcschr{L}(long *wcs, ℤ wc) + logic 𔹠wcschr{L}(wchar_t *wcs, ℤ wc) reads *(wcs + (0 .. wcslen(wcs))); axiom wcschr_def{L}: - ∀ long *wcs; + ∀ wchar_t *wcs; ∀ ℤ wc; - wcschr(wcs, wc) ≢ (0 ≢ 0) ⇔ - (∃ ℤ i; 0 ≤ i ≤ wcslen(wcs) ∧ *(wcs + i) ≡ (long)((int)wc)); + wcschr(wcs, wc) ≡ \true ⇔ + (∃ ℤ i; 0 ≤ i ≤ wcslen(wcs) ∧ *(wcs + i) ≡ (wchar_t)wc); } */ @@ -391,20 +387,20 @@ predicate valid_read_nstring{L}(char *s, ℤ n) = predicate valid_string_or_null{L}(char *s) = s ≡ \null ∨ valid_string(s); */ /*@ -predicate valid_wstring{L}(long *s) = +predicate valid_wstring{L}(wchar_t *s) = 0 ≤ wcslen(s) ∧ \valid(s + (0 .. wcslen(s))); */ /*@ -predicate valid_read_wstring{L}(long *s) = +predicate valid_read_wstring{L}(wchar_t *s) = 0 ≤ wcslen(s) ∧ \valid_read(s + (0 .. wcslen(s))); */ /*@ -predicate valid_read_nwstring{L}(long *s, ℤ n) = +predicate valid_read_nwstring{L}(wchar_t *s, ℤ n) = (\valid_read(s + (0 .. n - 1)) ∧ \initialized(s + (0 .. n - 1))) ∨ valid_read_wstring(s); */ /*@ -predicate valid_wstring_or_null{L}(long *s) = +predicate valid_wstring_or_null{L}(wchar_t *s) = s ≡ \null ∨ valid_wstring(s); */ /*@ ghost int __fc_heap_status; */ @@ -438,10 +434,10 @@ predicate valid_read_or_empty{L}(void *s, size_t n) = */ /*@ requires valid_s1: valid_read_or_empty(s1, n); requires valid_s2: valid_read_or_empty(s2, n); - requires s1: initialization: \initialized((char *)s1 + (0 .. n - 1)); - requires s2: initialization: \initialized((char *)s2 + (0 .. n - 1)); - requires s1: danglingness: non_escaping(s1, n); - requires s2: danglingness: non_escaping(s2, n); + requires initialization: s1: \initialized((char *)s1 + (0 .. n - 1)); + requires initialization: s2: \initialized((char *)s2 + (0 .. n - 1)); + requires danglingness: s1: non_escaping(s1, n); + requires danglingness: s2: non_escaping(s2, n); ensures logic_spec: \result ≡ @@ -464,12 +460,12 @@ int memcmp(void const *s1, void const *s2, size_t n); requires danglingness: non_escaping(s, n) ∨ - non_escaping(s, (size_t)((int)(memchr_off((char *)s, c, n) + 1))); + non_escaping(s, (size_t)(memchr_off((char *)s, c, n) + 1)); assigns \result; assigns \result \from s, c, *((unsigned char *)s + (0 .. n - 1)); behavior found: - assumes char_found: memchr((char *)s, c, n) ≢ (0 ≢ 0); + assumes char_found: memchr((char *)s, c, n) ≡ \true; ensures result_same_base: \base_addr(\result) ≡ \base_addr(\old(s)); ensures result_char: (int)*((char *)\result) ≡ \old(c); ensures @@ -480,7 +476,7 @@ int memcmp(void const *s1, void const *s2, size_t n); (unsigned char *)\result ≤ (unsigned char *)\old(s) + i; behavior not_found: - assumes char_not_found: memchr((char *)s, c, n) ≡ (0 ≢ 0); + assumes char_not_found: ¬(memchr((char *)s, c, n) ≡ \true); ensures result_null: \result ≡ \null; */ void *memchr(void const *s, int c, size_t n); @@ -535,7 +531,7 @@ void *memmove(void *dest, void const *src, size_t n); /*@ requires valid_s: valid_or_empty(s, n); ensures - acsl_c_equiv: memset((char *)\old(s), \old(c), \old(n)) ≢ (0 ≢ 0); + acsl_c_equiv: memset((char *)\old(s), \old(c), \old(n)) ≡ \true; ensures result_ptr: \result ≡ \old(s); assigns *((char *)s + (0 .. n - 1)), \result; assigns *((char *)s + (0 .. n - 1)) \from c; @@ -591,7 +587,7 @@ int strcoll(char const *s1, char const *s2); \from s, (indirect: *(s + (0 .. strlen{Old}(s)))), (indirect: c); behavior found: - assumes char_found: strchr(s, c) ≢ (0 ≢ 0); + assumes char_found: strchr(s, c) ≡ \true; ensures result_char: *\result ≡ (char)\old(c); ensures result_same_base: \base_addr(\result) ≡ \base_addr(\old(s)); ensures @@ -602,7 +598,7 @@ int strcoll(char const *s1, char const *s2); ∀ char *p; \old(s) ≤ p < \result ⇒ *p ≢ (char)\old(c); behavior not_found: - assumes char_not_found: strchr(s, c) ≡ (0 ≢ 0); + assumes char_not_found: ¬(strchr(s, c) ≡ \true); ensures result_null: \result ≡ \null; behavior default: @@ -626,13 +622,13 @@ char *strchrnul(char const *s, int c); assigns \result \from s, *(s + (0 ..)), c; behavior found: - assumes char_found: strchr(s, c) ≢ (0 ≢ 0); + assumes char_found: strchr(s, c) ≡ \true; ensures result_char: (int)*\result ≡ \old(c); ensures result_same_base: \base_addr(\result) ≡ \base_addr(\old(s)); ensures result_valid_string: valid_read_string(\result); behavior not_found: - assumes char_not_found: strchr(s, c) ≡ (0 ≢ 0); + assumes char_not_found: ¬(strchr(s, c) ≡ \true); ensures result_null: \result ≡ \null; behavior default: @@ -726,7 +722,7 @@ char *__fc_strtok_ptr; (valid_read_string(s) ∧ (∀ int i; 0 ≤ i < strlen(delim) ⇒ - strchr(s, *(delim + i)) ≡ (0 ≢ 0))); + ¬(strchr(s, *(delim + i)) ≡ \true))); ensures result_subset: \result ≡ \null ∨ \subset(\result, \old(s) + (0 ..)); @@ -788,7 +784,7 @@ char *strtok(char * restrict s, char const * restrict delim); (valid_read_string(s) ∧ (∀ int i; 0 ≤ i < strlen(delim) ⇒ - strchr(s, *(delim + i)) ≡ (0 ≢ 0))); + ¬(strchr(s, *(delim + i)) ≡ \true))); ensures result_subset: \result ≡ \null ∨ \subset(\result, \old(s) + (0 ..)); @@ -805,7 +801,7 @@ char *strtok(char * restrict s, char const * restrict delim); behavior resume_str: assumes s_null: s ≡ \null; requires not_first_call: *saveptr ≢ \null; - requires saveptr: initialization: \initialized(saveptr); + requires initialization: saveptr: \initialized(saveptr); ensures result_subset: \result ≡ \null ∨ \subset(\result, \old(*saveptr) + (0 ..)); @@ -920,7 +916,7 @@ char *stpcpy(char * restrict dest, char const * restrict src); ensures sum_of_lengths: strlen(\old(dest)) ≡ \old(strlen(dest) + strlen(src)); ensures - dest: initialization: + initialization: dest: \initialized(\old(dest) + (0 .. \old(strlen(dest) + strlen(src)))); ensures dest_null_terminated: @@ -1071,7 +1067,7 @@ char *strsignal(int signum); /*@ requires valid_memory_area: \valid((char *)s + (0 .. n - 1)); ensures - initialization: s_initialized: + s_initialized: initialization: \initialized((char *)\old(s) + (0 .. \old(n) - 1)); ensures zero_initialized: \subset(*((char *)\old(s) + (0 .. \old(n) - 1)), {0}); diff --git a/tests/stl/oracle/stl_unique_ptr.res.oracle b/tests/stl/oracle/stl_unique_ptr.res.oracle index 95faad0de16d86e2147be464c15c06285ab3bd87..b5c6d61ca3ee000c47007bb4fdb8206fa9c6cf0b 100644 --- a/tests/stl/oracle/stl_unique_ptr.res.oracle +++ b/tests/stl/oracle/stl_unique_ptr.res.oracle @@ -372,6 +372,7 @@ struct piecewise_construct_t; struct piecewise_construct_t { }; +typedef long wchar_t; struct exception; struct bad_exception; struct nested_exception; @@ -847,7 +848,7 @@ axiomatic MemChr { ∀ char *s; ∀ ℤ c; ∀ ℤ n; - memchr(s, c, n) ≢ (0 ≢ 0) ⇔ + memchr(s, c, n) ≡ \true ⇔ (∃ int i; 0 ≤ i < n ∧ *(s + i) ≡ c); } @@ -861,7 +862,7 @@ axiomatic MemSet { ∀ char *s; ∀ ℤ c; ∀ ℤ n; - memset(s, c, n) ≢ (0 ≢ 0) ⇔ + memset(s, c, n) ≡ \true ⇔ (∀ ℤ i; 0 ≤ i < n ⇒ *(s + i) ≡ c); } @@ -874,33 +875,33 @@ axiomatic StrLen { axiom strlen_pos_or_null{L}: ∀ char *s; ∀ ℤ i; - 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ (char)0) ∧ - *(s + i) ≡ (char)0 ⇒ strlen(s) ≡ i; + 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ '\000') ∧ + *(s + i) ≡ '\000' ⇒ strlen(s) ≡ i; axiom strlen_neg{L}: ∀ char *s; - (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ (char)0) ⇒ strlen(s) < 0; + (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ '\000') ⇒ strlen(s) < 0; axiom strlen_before_null{L}: ∀ char *s; - ∀ ℤ i; 0 ≤ i < strlen(s) ⇒ *(s + i) ≢ (char)0; + ∀ ℤ i; 0 ≤ i < strlen(s) ⇒ *(s + i) ≢ '\000'; axiom strlen_at_null{L}: - ∀ char *s; 0 ≤ strlen(s) ⇒ *(s + strlen(s)) ≡ (char)0; + ∀ char *s; 0 ≤ strlen(s) ⇒ *(s + strlen(s)) ≡ '\000'; axiom strlen_not_zero{L}: ∀ char *s; ∀ ℤ i; - 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≢ (char)0 ⇒ i < strlen(s); + 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≢ '\000' ⇒ i < strlen(s); axiom strlen_zero{L}: ∀ char *s; ∀ ℤ i; - 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ (char)0 ⇒ i ≡ strlen(s); + 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ '\000' ⇒ i ≡ strlen(s); axiom strlen_sup{L}: ∀ char *s; - ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ (char)0 ⇒ 0 ≤ strlen(s) ≤ i; + ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ '\000' ⇒ 0 ≤ strlen(s) ≤ i; axiom strlen_shift{L}: ∀ char *s; @@ -908,14 +909,13 @@ axiomatic StrLen { axiom strlen_create{L}: ∀ char *s; - ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ (char)0 ⇒ 0 ≤ strlen(s) ≤ i; + ∀ ℤ i; 0 ≤ i ∧ *(s + i) ≡ '\000' ⇒ 0 ≤ strlen(s) ≤ i; axiom strlen_create_shift{L}: ∀ char *s; ∀ ℤ i; ∀ ℤ k; - 0 ≤ k ≤ i ∧ *(s + i) ≡ (char)0 ⇒ - 0 ≤ strlen(s + k) ≤ i - k; + 0 ≤ k ≤ i ∧ *(s + i) ≡ '\000' ⇒ 0 ≤ strlen(s + k) ≤ i - k; axiom memcmp_strlen_left{L}: ∀ char *s1, char *s2; @@ -978,88 +978,84 @@ axiomatic StrChr { axiom strchr_def{L}: ∀ char *s; ∀ ℤ c; - strchr(s, c) ≢ (0 ≢ 0) ⇔ - (∃ ℤ i; 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ (char)((int)c)); + strchr(s, c) ≡ \true ⇔ + (∃ ℤ i; 0 ≤ i ≤ strlen(s) ∧ *(s + i) ≡ (char)c); } */ /*@ axiomatic WMemChr { - logic 𔹠wmemchr{L}(long *s, long c, ℤ n) + logic 𔹠wmemchr{L}(wchar_t *s, wchar_t c, ℤ n) reads *(s + (0 .. n - 1)); - logic ℤ wmemchr_off{L}(long *s, long c, ℤ n) + logic ℤ wmemchr_off{L}(wchar_t *s, wchar_t c, ℤ n) reads *(s + (0 .. n - 1)); axiom wmemchr_def{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ long c; ∀ ℤ n; - wmemchr(s, c, n) ≢ (0 ≢ 0) ⇔ + wmemchr(s, c, n) ≡ \true ⇔ (∃ int i; 0 ≤ i < n ∧ *(s + i) ≡ c); } */ /*@ axiomatic WcsLen { - logic ℤ wcslen{L}(long *s) + logic ℤ wcslen{L}(wchar_t *s) reads *(s + (0 ..)); axiom wcslen_pos_or_null{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ ℤ i; - 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ (long)0) ∧ - *(s + i) ≡ (long)0 ⇒ wcslen(s) ≡ i; + 0 ≤ i ∧ (∀ ℤ j; 0 ≤ j < i ⇒ *(s + j) ≢ 0) ∧ + *(s + i) ≡ 0 ⇒ wcslen(s) ≡ i; axiom wcslen_neg{L}: - ∀ long *s; - (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ (long)0) ⇒ wcslen(s) < 0; + ∀ wchar_t *s; (∀ ℤ i; 0 ≤ i ⇒ *(s + i) ≢ 0) ⇒ wcslen(s) < 0; axiom wcslen_before_null{L}: - ∀ long *s; - ∀ int i; 0 ≤ i < wcslen(s) ⇒ *(s + i) ≢ (long)0; + ∀ wchar_t *s; + ∀ int i; 0 ≤ i < wcslen(s) ⇒ *(s + i) ≢ 0; axiom wcslen_at_null{L}: - ∀ long *s; 0 ≤ wcslen(s) ⇒ *(s + wcslen(s)) ≡ (long)0; + ∀ wchar_t *s; 0 ≤ wcslen(s) ⇒ *(s + wcslen(s)) ≡ 0; axiom wcslen_not_zero{L}: - ∀ long *s; - ∀ int i; - 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≢ (long)0 ⇒ i < wcslen(s); + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≢ 0 ⇒ i < wcslen(s); axiom wcslen_zero{L}: - ∀ long *s; - ∀ int i; - 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≡ (long)0 ⇒ i ≡ wcslen(s); + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ≤ wcslen(s) ∧ *(s + i) ≡ 0 ⇒ i ≡ wcslen(s); axiom wcslen_sup{L}: - ∀ long *s; - ∀ int i; 0 ≤ i ∧ *(s + i) ≡ (long)0 ⇒ 0 ≤ wcslen(s) ≤ i; + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ∧ *(s + i) ≡ 0 ⇒ 0 ≤ wcslen(s) ≤ i; axiom wcslen_shift{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ int i; 0 ≤ i ≤ wcslen(s) ⇒ wcslen(s + i) ≡ wcslen(s) - i; axiom wcslen_create{L}: - ∀ long *s; - ∀ int i; 0 ≤ i ∧ *(s + i) ≡ (long)0 ⇒ 0 ≤ wcslen(s) ≤ i; + ∀ wchar_t *s; + ∀ int i; 0 ≤ i ∧ *(s + i) ≡ 0 ⇒ 0 ≤ wcslen(s) ≤ i; axiom wcslen_create_shift{L}: - ∀ long *s; + ∀ wchar_t *s; ∀ int i; ∀ int k; - 0 ≤ k ≤ i ∧ *(s + i) ≡ (long)0 ⇒ - 0 ≤ wcslen(s + k) ≤ i - k; + 0 ≤ k ≤ i ∧ *(s + i) ≡ 0 ⇒ 0 ≤ wcslen(s + k) ≤ i - k; } */ /*@ axiomatic WcsCmp { - logic ℤ wcscmp{L}(long *s1, long *s2) + logic ℤ wcscmp{L}(wchar_t *s1, wchar_t *s2) reads *(s1 + (0 .. wcslen(s1))), *(s2 + (0 .. wcslen(s2))); axiom wcscmp_zero{L}: - ∀ long *s1, long *s2; + ∀ wchar_t *s1, wchar_t *s2; wcscmp(s1, s2) ≡ 0 ⇔ wcslen(s1) ≡ wcslen(s2) ∧ (∀ ℤ i; 0 ≤ i ≤ wcslen(s1) ⇒ *(s1 + i) ≡ *(s2 + i)); @@ -1068,11 +1064,11 @@ axiomatic WcsCmp { */ /*@ axiomatic WcsNCmp { - logic ℤ wcsncmp{L}(long *s1, long *s2, ℤ n) + logic ℤ wcsncmp{L}(wchar_t *s1, wchar_t *s2, ℤ n) reads *(s1 + (0 .. n - 1)), *(s2 + (0 .. n - 1)); axiom wcsncmp_zero{L}: - ∀ long *s1, long *s2; + ∀ wchar_t *s1, wchar_t *s2; ∀ ℤ n; wcsncmp(s1, s2, n) ≡ 0 ⇔ (wcslen(s1) < n ∧ wcscmp(s1, s2) ≡ 0) ∨ @@ -1082,14 +1078,14 @@ axiomatic WcsNCmp { */ /*@ axiomatic WcsChr { - logic 𔹠wcschr{L}(long *wcs, ℤ wc) + logic 𔹠wcschr{L}(wchar_t *wcs, ℤ wc) reads *(wcs + (0 .. wcslen(wcs))); axiom wcschr_def{L}: - ∀ long *wcs; + ∀ wchar_t *wcs; ∀ ℤ wc; - wcschr(wcs, wc) ≢ (0 ≢ 0) ⇔ - (∃ ℤ i; 0 ≤ i ≤ wcslen(wcs) ∧ *(wcs + i) ≡ (long)((int)wc)); + wcschr(wcs, wc) ≡ \true ⇔ + (∃ ℤ i; 0 ≤ i ≤ wcslen(wcs) ∧ *(wcs + i) ≡ (wchar_t)wc); } */ @@ -1114,20 +1110,20 @@ predicate valid_read_nstring{L}(char *s, ℤ n) = predicate valid_string_or_null{L}(char *s) = s ≡ \null ∨ valid_string(s); */ /*@ -predicate valid_wstring{L}(long *s) = +predicate valid_wstring{L}(wchar_t *s) = 0 ≤ wcslen(s) ∧ \valid(s + (0 .. wcslen(s))); */ /*@ -predicate valid_read_wstring{L}(long *s) = +predicate valid_read_wstring{L}(wchar_t *s) = 0 ≤ wcslen(s) ∧ \valid_read(s + (0 .. wcslen(s))); */ /*@ -predicate valid_read_nwstring{L}(long *s, ℤ n) = +predicate valid_read_nwstring{L}(wchar_t *s, ℤ n) = (\valid_read(s + (0 .. n - 1)) ∧ \initialized(s + (0 .. n - 1))) ∨ valid_read_wstring(s); */ /*@ -predicate valid_wstring_or_null{L}(long *s) = +predicate valid_wstring_or_null{L}(wchar_t *s) = s ≡ \null ∨ valid_wstring(s); */ /*@ ghost int __fc_heap_status; */ @@ -1162,10 +1158,10 @@ predicate valid_read_or_empty{L}(void *s, size_t n) = */ /*@ requires valid_s1: valid_read_or_empty(s1, n); requires valid_s2: valid_read_or_empty(s2, n); - requires s1: initialization: \initialized((char *)s1 + (0 .. n - 1)); - requires s2: initialization: \initialized((char *)s2 + (0 .. n - 1)); - requires s1: danglingness: non_escaping(s1, n); - requires s2: danglingness: non_escaping(s2, n); + requires initialization: s1: \initialized((char *)s1 + (0 .. n - 1)); + requires initialization: s2: \initialized((char *)s2 + (0 .. n - 1)); + requires danglingness: s1: non_escaping(s1, n); + requires danglingness: s2: non_escaping(s2, n); ensures logic_spec: \result ≡ @@ -1188,12 +1184,12 @@ int memcmp(void const *s1, void const *s2, size_t n); requires danglingness: non_escaping(s, n) ∨ - non_escaping(s, (size_t)((int)(memchr_off((char *)s, c, n) + 1))); + non_escaping(s, (size_t)(memchr_off((char *)s, c, n) + 1)); assigns \result; assigns \result \from s, c, *((unsigned char *)s + (0 .. n - 1)); behavior found: - assumes char_found: memchr((char *)s, c, n) ≢ (0 ≢ 0); + assumes char_found: memchr((char *)s, c, n) ≡ \true; ensures result_same_base: \base_addr(\result) ≡ \base_addr(\old(s)); ensures result_char: (int)*((char *)\result) ≡ \old(c); ensures @@ -1204,7 +1200,7 @@ int memcmp(void const *s1, void const *s2, size_t n); (unsigned char *)\result ≤ (unsigned char *)\old(s) + i; behavior not_found: - assumes char_not_found: memchr((char *)s, c, n) ≡ (0 ≢ 0); + assumes char_not_found: ¬(memchr((char *)s, c, n) ≡ \true); ensures result_null: \result ≡ \null; */ void *memchr(void const *s, int c, size_t n); @@ -1259,7 +1255,7 @@ void *memmove(void *dest, void const *src, size_t n); /*@ requires valid_s: valid_or_empty(s, n); ensures - acsl_c_equiv: memset((char *)\old(s), \old(c), \old(n)) ≢ (0 ≢ 0); + acsl_c_equiv: memset((char *)\old(s), \old(c), \old(n)) ≡ \true; ensures result_ptr: \result ≡ \old(s); assigns *((char *)s + (0 .. n - 1)), \result; assigns *((char *)s + (0 .. n - 1)) \from c; @@ -1315,7 +1311,7 @@ int strcoll(char const *s1, char const *s2); \from s, (indirect: *(s + (0 .. strlen{Old}(s)))), (indirect: c); behavior found: - assumes char_found: strchr(s, c) ≢ (0 ≢ 0); + assumes char_found: strchr(s, c) ≡ \true; ensures result_char: *\result ≡ (char)\old(c); ensures result_same_base: \base_addr(\result) ≡ \base_addr(\old(s)); ensures @@ -1326,7 +1322,7 @@ int strcoll(char const *s1, char const *s2); ∀ char *p; \old(s) ≤ p < \result ⇒ *p ≢ (char)\old(c); behavior not_found: - assumes char_not_found: strchr(s, c) ≡ (0 ≢ 0); + assumes char_not_found: ¬(strchr(s, c) ≡ \true); ensures result_null: \result ≡ \null; behavior default: @@ -1350,13 +1346,13 @@ char *strchrnul(char const *s, int c); assigns \result \from s, *(s + (0 ..)), c; behavior found: - assumes char_found: strchr(s, c) ≢ (0 ≢ 0); + assumes char_found: strchr(s, c) ≡ \true; ensures result_char: (int)*\result ≡ \old(c); ensures result_same_base: \base_addr(\result) ≡ \base_addr(\old(s)); ensures result_valid_string: valid_read_string(\result); behavior not_found: - assumes char_not_found: strchr(s, c) ≡ (0 ≢ 0); + assumes char_not_found: ¬(strchr(s, c) ≡ \true); ensures result_null: \result ≡ \null; behavior default: @@ -1450,7 +1446,7 @@ char *__fc_strtok_ptr; (valid_read_string(s) ∧ (∀ int i; 0 ≤ i < strlen(delim) ⇒ - strchr(s, *(delim + i)) ≡ (0 ≢ 0))); + ¬(strchr(s, *(delim + i)) ≡ \true))); ensures result_subset: \result ≡ \null ∨ \subset(\result, \old(s) + (0 ..)); @@ -1512,7 +1508,7 @@ char *strtok(char * restrict s, char const * restrict delim); (valid_read_string(s) ∧ (∀ int i; 0 ≤ i < strlen(delim) ⇒ - strchr(s, *(delim + i)) ≡ (0 ≢ 0))); + ¬(strchr(s, *(delim + i)) ≡ \true))); ensures result_subset: \result ≡ \null ∨ \subset(\result, \old(s) + (0 ..)); @@ -1529,7 +1525,7 @@ char *strtok(char * restrict s, char const * restrict delim); behavior resume_str: assumes s_null: s ≡ \null; requires not_first_call: *saveptr ≢ \null; - requires saveptr: initialization: \initialized(saveptr); + requires initialization: saveptr: \initialized(saveptr); ensures result_subset: \result ≡ \null ∨ \subset(\result, \old(*saveptr) + (0 ..)); @@ -1644,7 +1640,7 @@ char *stpcpy(char * restrict dest, char const * restrict src); ensures sum_of_lengths: strlen(\old(dest)) ≡ \old(strlen(dest) + strlen(src)); ensures - dest: initialization: + initialization: dest: \initialized(\old(dest) + (0 .. \old(strlen(dest) + strlen(src)))); ensures dest_null_terminated: @@ -1795,7 +1791,7 @@ char *strsignal(int signum); /*@ requires valid_memory_area: \valid((char *)s + (0 .. n - 1)); ensures - initialization: s_initialized: + s_initialized: initialization: \initialized((char *)\old(s) + (0 .. \old(n) - 1)); ensures zero_initialized: \subset(*((char *)\old(s) + (0 .. \old(n) - 1)), {0});