From a0f238a3d270edd7042d9852d43e3ec5b9602af2 Mon Sep 17 00:00:00 2001 From: Bernhard Schommer Date: Tue, 17 Oct 2017 12:54:13 +0200 Subject: Check recursively for const for modifiable lvalues (#32) Check recursively for const for modifiable lvalues According to 6.3.2.1 a modifiable lvalue is an lvalue that does have a const-qualified type, and if it is a union or structure it does not have any member, including any member of all contained strutures or union, with a const-qualified type. The new check for modifiable lvalue additionally checks this now instead of only testing for toplevel const. Bug 22420 --- cparser/Cutil.ml | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'cparser/Cutil.ml') diff --git a/cparser/Cutil.ml b/cparser/Cutil.ml index 586b4a92..9bc11141 100644 --- a/cparser/Cutil.ml +++ b/cparser/Cutil.ml @@ -179,7 +179,7 @@ let rec attributes_of_type env t = | TUnion(s, a) -> let ci = Env.find_union env s in add_attributes ci.ci_attr a | TEnum(s, a) -> - let ei = Env.find_enum env s in add_attributes ei.ei_attr a + let ei = Env.find_enum env s in add_attributes ei.ei_attr a (* Changing the attributes of a type (at top-level) *) (* Same hack as above for array types. *) @@ -937,10 +937,23 @@ let rec is_lvalue e = whose type is not const, neither an array type, nor a function type, nor an incomplete type. *) +let rec is_const_type env ty = + List.mem AConst (attributes_of_type env ty) || + begin match unroll env ty with + | TStruct(s, a) -> + let ci = Env.find_struct env s in + List.exists (fun m -> is_const_type env m.fld_typ) ci.ci_members + | TUnion(s, a) -> + let ci = Env.find_union env s in + List.exists (fun m -> is_const_type env m.fld_typ) ci.ci_members + | _ -> + false + end + let is_modifiable_lvalue env e = is_lvalue e - && not (List.mem AConst (attributes_of_type env e.etyp)) && not (incomplete_type env e.etyp) + && not (is_const_type env e.etyp) && begin match unroll env e.etyp with | TFun _ | TArray _ -> false | _ -> true -- cgit