Currently, it is possible to say expression *x; to have x match any pointer-typed expression. It could also be useful to say eg expression struct * x; to have it match any expression of type pointer to any sort of struct. Another option would be just struct *x;, but that would suggest there should be just *x;, which could be a bit too concise.
julia On Mon, 11 Oct 2010, Julia Lawall wrote: > A patch is below that makes the following semantic patch modify any > structure-typed expression: > > @r@ > identifier x; > struct x *a; > @@ > > -a > +f(a,12) > > julia > > diff -u -p a/parsing_cocci/type_cocci.ml b/parsing_cocci/type_cocci.ml > --- a/parsing_cocci/type_cocci.ml 2010-09-27 22:21:44.000000000 +0200 > +++ b/parsing_cocci/type_cocci.ml 2010-10-11 23:14:02.000000000 +0200 > @@ -27,6 +27,8 @@ type inherited = bool (* true if inherit > type keep_binding = Unitary (* need no info *) > | Nonunitary (* need an env entry *) | Saved (* need a witness *) > > +type meta_name = string * string (*Ast_cocci.meta_name*) > + > type typeC = > ConstVol of const_vol * typeC > | BaseType of baseType > @@ -35,11 +37,15 @@ type typeC = > | FunctionPointer of typeC (* only return type *) > | Array of typeC (* drop size info *) > | EnumName of bool (* true if a metaId *) * string > - | StructUnionName of structUnion * bool (* true if a metaId *) * string > + | StructUnionName of structUnion * name > | TypeName of string > - | MetaType of (string * string) * keep_binding * inherited > + | MetaType of meta_name * keep_binding * inherited > | Unknown (* for metavariables of type expression *^* *) > > +and name = > + Name of string > + | MV of meta_name * keep_binding * inherited > + > and tagged_string = string > > and baseType = VoidType | CharType | ShortType | IntType | DoubleType > @@ -64,7 +70,8 @@ let rec type2c = function > | FunctionPointer(ty) -> (type2c ty) ^ "(*)(...)" > | Array(ty) -> (type2c ty) ^ "[] " > | EnumName(mv,name) -> "enum " ^ name ^ " " > - | StructUnionName(kind,mv,name) -> (structUnion kind) ^ name ^ " " > + | StructUnionName(kind,MV ((_,name),_,_)) -> (structUnion kind) ^ name ^ " > " > + | StructUnionName(kind,Name name) -> (structUnion kind) ^ name ^ " " > | TypeName(name) -> name ^ " " > | MetaType((rule,name),keep,inherited) -> name ^ " " > (* > diff -u -p a/parsing_cocci/type_cocci.mli b/parsing_cocci/type_cocci.mli > --- a/parsing_cocci/type_cocci.mli 2010-09-27 22:21:44.000000000 +0200 > +++ b/parsing_cocci/type_cocci.mli 2010-10-11 23:14:01.000000000 +0200 > @@ -26,6 +26,8 @@ type inherited = bool (* true if inherit > type keep_binding = Unitary (* need no info *) > | Nonunitary (* need an env entry *) | Saved (* need a witness *) > > +type meta_name = string * string (*Ast_cocci.meta_name*) > + > type typeC = > ConstVol of const_vol * typeC > | BaseType of baseType > @@ -34,11 +36,15 @@ type typeC = > | FunctionPointer of typeC (* only return type *) > | Array of typeC (* drop size info *) > | EnumName of bool (* true if a metaId *) * string > - | StructUnionName of structUnion * bool (* true if type metavar *) * string > + | StructUnionName of structUnion * name > | TypeName of string > - | MetaType of (string * string) * keep_binding * inherited > + | MetaType of meta_name * keep_binding * inherited > | Unknown (* for metavariables of type expression *^* *) > > +and name = > + Name of string > + | MV of meta_name * keep_binding * inherited > + > and tagged_string = string > > and baseType = VoidType | CharType | ShortType | IntType | DoubleType > diff -u -p a/parsing_cocci/ast0_cocci.ml b/parsing_cocci/ast0_cocci.ml > --- a/parsing_cocci/ast0_cocci.ml 2010-09-27 22:21:44.000000000 +0200 > +++ b/parsing_cocci/ast0_cocci.ml 2010-10-11 23:14:01.000000000 +0200 > @@ -23,6 +23,7 @@ > > > module Ast = Ast_cocci > +module TC = Type_cocci > > (* --------------------------------------------------------------------- *) > (* Modified code *) > @@ -68,7 +69,7 @@ and 'a wrap = > info : info; > index : int ref; > mcodekind : mcodekind ref; > - exp_ty : Type_cocci.typeC option ref; (* only for expressions *) > + exp_ty : TC.typeC option ref; (* only for expressions *) > bef_aft : dots_bef_aft; (* only for statements *) > true_if_arg : bool; (* true if "arg_exp", only for exprs *) > true_if_test : bool; (* true if "test position", only for exprs *) > @@ -142,7 +143,7 @@ and base_expression = > | TypeExp of typeC (* type name used as an expression, only in args > *) > | MetaErr of Ast.meta_name mcode * constraints * pure > | MetaExpr of Ast.meta_name mcode * constraints * > - Type_cocci.typeC list option * Ast.form * pure > + TC.typeC list option * Ast.form * pure > | MetaExprList of Ast.meta_name mcode (* only in arg lists *) * > listlen * pure > | EComma of string mcode (* only in arg lists *) > @@ -557,81 +558,85 @@ let undots d = > > let rec ast0_type_to_type ty = > match unwrap ty with > - ConstVol(cv,ty) -> Type_cocci.ConstVol(const_vol cv,ast0_type_to_type ty) > + ConstVol(cv,ty) -> TC.ConstVol(const_vol cv,ast0_type_to_type ty) > | BaseType(bty,strings) -> > - Type_cocci.BaseType(baseType bty) > + TC.BaseType(baseType bty) > | Signed(sgn,None) -> > - Type_cocci.SignedT(sign sgn,None) > + TC.SignedT(sign sgn,None) > | Signed(sgn,Some ty) -> > let bty = ast0_type_to_type ty in > - Type_cocci.SignedT(sign sgn,Some bty) > - | Pointer(ty,_) -> Type_cocci.Pointer(ast0_type_to_type ty) > + TC.SignedT(sign sgn,Some bty) > + | Pointer(ty,_) -> TC.Pointer(ast0_type_to_type ty) > | FunctionPointer(ty,_,_,_,_,params,_) -> > - Type_cocci.FunctionPointer(ast0_type_to_type ty) > + TC.FunctionPointer(ast0_type_to_type ty) > | FunctionType _ -> failwith "not supported" > - | Array(ety,_,_,_) -> Type_cocci.Array(ast0_type_to_type ety) > + | Array(ety,_,_,_) -> TC.Array(ast0_type_to_type ety) > | EnumName(su,Some tag) -> > (match unwrap tag with > Id(tag) -> > - Type_cocci.EnumName(false,unwrap_mcode tag) > + TC.EnumName(false,unwrap_mcode tag) > | MetaId(tag,_,_) -> > (Printf.printf > "warning: enum with a metavariable name detected.\n"; > Printf.printf > "For type checking assuming the name of the metavariable is the > name of the type\n"; > let (rule,tag) = unwrap_mcode tag in > - Type_cocci.EnumName(true,rule^tag)) > + TC.EnumName(true,rule^tag)) > | _ -> failwith "unexpected enum type name") > | EnumName(su,None) -> failwith "nameless enum - what to do???" > | EnumDef(ty,_,_,_) -> ast0_type_to_type ty > | StructUnionName(su,Some tag) -> > (match unwrap tag with > Id(tag) -> > - Type_cocci.StructUnionName(structUnion su,false,unwrap_mcode tag) > - | MetaId(tag,_,_) -> > + TC.StructUnionName(structUnion su,TC.Name(unwrap_mcode tag)) > + | MetaId(tag,Ast.IdNoConstraint,_) -> > (Common.pr2 > "warning: struct/union with a metavariable name detected.\n"; > Common.pr2 > "For type checking assuming the name of the metavariable is the > name of the type\n"; > - let (rule,tag) = unwrap_mcode tag in > - Type_cocci.StructUnionName(structUnion su,true,rule^tag)) > + TC.StructUnionName(structUnion su, > + TC.MV(unwrap_mcode tag,TC.Unitary,false))) > + | MetaId(tag,_,_) -> > + (* would have to duplicate the type in type_cocci.ml? > + perhaps polymorphism would help? *) > + failwith "constraints not supported on struct type name" > | _ -> failwith "unexpected struct/union type name") > | StructUnionName(su,None) -> failwith "nameless structure - what to do???" > | StructUnionDef(ty,_,_,_) -> ast0_type_to_type ty > - | TypeName(name) -> Type_cocci.TypeName(unwrap_mcode name) > + | TypeName(name) -> TC.TypeName(unwrap_mcode name) > | MetaType(name,_) -> > - Type_cocci.MetaType(unwrap_mcode name,Type_cocci.Unitary,false) > + TC.MetaType(unwrap_mcode name,TC.Unitary,false) > | DisjType(_,types,_,_) -> > Common.pr2_once > "disjtype not supported in smpl type inference, assuming unknown"; > - Type_cocci.Unknown > + TC.Unknown > | OptType(ty) | UniqueType(ty) -> > ast0_type_to_type ty > > and baseType = function > - Ast.VoidType -> Type_cocci.VoidType > - | Ast.CharType -> Type_cocci.CharType > - | Ast.ShortType -> Type_cocci.ShortType > - | Ast.IntType -> Type_cocci.IntType > - | Ast.DoubleType -> Type_cocci.DoubleType > - | Ast.FloatType -> Type_cocci.FloatType > - | Ast.LongType -> Type_cocci.LongType > - | Ast.LongLongType -> Type_cocci.LongLongType > + Ast.VoidType -> TC.VoidType > + | Ast.CharType -> TC.CharType > + | Ast.ShortType -> TC.ShortType > + | Ast.IntType -> TC.IntType > + | Ast.DoubleType -> TC.DoubleType > + | Ast.FloatType -> TC.FloatType > + | Ast.LongType -> TC.LongType > + | Ast.LongLongType -> TC.LongLongType > > and structUnion t = > match unwrap_mcode t with > - Ast.Struct -> Type_cocci.Struct > - | Ast.Union -> Type_cocci.Union > + Ast.Struct -> TC.Struct > + | Ast.Union -> TC.Union > > and sign t = > match unwrap_mcode t with > - Ast.Signed -> Type_cocci.Signed > - | Ast.Unsigned -> Type_cocci.Unsigned > + Ast.Signed -> TC.Signed > + | Ast.Unsigned -> TC.Unsigned > > and const_vol t = > match unwrap_mcode t with > - Ast.Const -> Type_cocci.Const > - | Ast.Volatile -> Type_cocci.Volatile > + Ast.Const -> TC.Const > + | Ast.Volatile -> TC.Volatile > > (* --------------------------------------------------------------------- *) > (* this function is a rather minimal attempt. the problem is that > information > @@ -646,16 +651,16 @@ exception TyConv > > let rec reverse_type ty = > match ty with > - Type_cocci.ConstVol(cv,ty) -> > + TC.ConstVol(cv,ty) -> > ConstVol(reverse_const_vol cv,context_wrap(reverse_type ty)) > - | Type_cocci.BaseType(bty) -> > + | TC.BaseType(bty) -> > BaseType(reverse_baseType bty,[(* not used *)]) > - | Type_cocci.SignedT(sgn,None) -> Signed(reverse_sign sgn,None) > - | Type_cocci.SignedT(sgn,Some bty) -> > + | TC.SignedT(sgn,None) -> Signed(reverse_sign sgn,None) > + | TC.SignedT(sgn,Some bty) -> > Signed(reverse_sign sgn,Some (context_wrap(reverse_type ty))) > - | Type_cocci.Pointer(ty) -> > + | TC.Pointer(ty) -> > Pointer(context_wrap(reverse_type ty),make_mcode "*") > - | Type_cocci.EnumName(mv,tag) -> > + | TC.EnumName(mv,tag) -> > if mv > then > (* not right... *) > @@ -666,52 +671,49 @@ let rec reverse_type ty = > Impure)))) > else > EnumName(make_mcode "enum",Some(context_wrap(Id(make_mcode tag)))) > - | Type_cocci.StructUnionName(su,mv,tag) -> > - if mv > - then > - (* not right... *) > - let rule = "" in > - StructUnionName > - (reverse_structUnion su, > - Some(context_wrap(MetaId(make_mcode (rule,tag),Ast.IdNoConstraint, > - Impure)))) > - else > - StructUnionName > - (reverse_structUnion su, > - Some (context_wrap(Id(make_mcode tag)))) > - | Type_cocci.TypeName(name) -> TypeName(make_mcode name) > - | Type_cocci.MetaType(name,_,_) -> > + | TC.StructUnionName(su,TC.MV(name,_,_)) -> > + (* not right?... *) > + StructUnionName > + (reverse_structUnion su, > + Some(context_wrap(MetaId(make_mcode name,Ast.IdNoConstraint, > + Impure(*not really right*))))) > + | TC.StructUnionName(su,TC.Name tag) -> > + StructUnionName > + (reverse_structUnion su, > + Some (context_wrap(Id(make_mcode tag)))) > + | TC.TypeName(name) -> TypeName(make_mcode name) > + | TC.MetaType(name,_,_) -> > MetaType(make_mcode name,Impure(*not really right*)) > | _ -> raise TyConv > > and reverse_baseType = function > - Type_cocci.VoidType -> Ast.VoidType > - | Type_cocci.CharType -> Ast.CharType > - | Type_cocci.BoolType -> Ast.IntType > - | Type_cocci.ShortType -> Ast.ShortType > - | Type_cocci.IntType -> Ast.IntType > - | Type_cocci.DoubleType -> Ast.DoubleType > - | Type_cocci.FloatType -> Ast.FloatType > - | Type_cocci.LongType -> Ast.LongType > - | Type_cocci.LongLongType -> Ast.LongLongType > + TC.VoidType -> Ast.VoidType > + | TC.CharType -> Ast.CharType > + | TC.BoolType -> Ast.IntType > + | TC.ShortType -> Ast.ShortType > + | TC.IntType -> Ast.IntType > + | TC.DoubleType -> Ast.DoubleType > + | TC.FloatType -> Ast.FloatType > + | TC.LongType -> Ast.LongType > + | TC.LongLongType -> Ast.LongLongType > > and reverse_structUnion t = > make_mcode > (match t with > - Type_cocci.Struct -> Ast.Struct > - | Type_cocci.Union -> Ast.Union) > + TC.Struct -> Ast.Struct > + | TC.Union -> Ast.Union) > > and reverse_sign t = > make_mcode > (match t with > - Type_cocci.Signed -> Ast.Signed > - | Type_cocci.Unsigned -> Ast.Unsigned) > + TC.Signed -> Ast.Signed > + | TC.Unsigned -> Ast.Unsigned) > > and reverse_const_vol t = > make_mcode > (match t with > - Type_cocci.Const -> Ast.Const > - | Type_cocci.Volatile -> Ast.Volatile) > + TC.Const -> Ast.Const > + | TC.Volatile -> Ast.Volatile) > > (* --------------------------------------------------------------------- *) > > diff -u -p a/parsing_cocci/type_infer.ml b/parsing_cocci/type_infer.ml > --- a/parsing_cocci/type_infer.ml 2010-09-27 22:21:44.000000000 +0200 > +++ b/parsing_cocci/type_infer.ml 2010-10-11 23:14:02.000000000 +0200 > @@ -217,7 +217,7 @@ let rec propagate_types env = > | Ast0.RecordAccess(exp,pt,field) -> > (match strip_cv (Ast0.get_type exp) with > None -> None > - | Some (T.StructUnionName(_,_,_)) -> None > + | Some (T.StructUnionName(_,_)) -> None > | Some (T.TypeName(_)) -> None > | Some (T.MetaType(_,_,_)) -> None > | Some x -> err exp x "non-structure type in field ref") > @@ -229,7 +229,7 @@ let rec propagate_types env = > | Some (T.Unknown) -> None > | Some (T.MetaType(_,_,_)) -> None > | Some (T.TypeName(_)) -> None > - | Some (T.StructUnionName(_,_,_)) -> None > + | Some (T.StructUnionName(_,_)) -> None > | Some x -> > err exp (T.Pointer(t)) > "non-structure pointer type in field ref" > diff -u -p a/parsing_cocci/get_constants2.ml b/parsing_cocci/get_constants2.ml > --- a/parsing_cocci/get_constants2.ml 2010-09-27 22:21:44.000000000 +0200 > +++ b/parsing_cocci/get_constants2.ml 2010-10-11 23:14:01.000000000 +0200 > @@ -294,7 +294,7 @@ let do_get_constants constants keywords > inherited tyname > | TC.TypeName(s) -> constants s > | TC.EnumName(false,s) -> constants s > - | TC.StructUnionName(_,false,s) -> constants s > + | TC.StructUnionName(_,TC.Name s) -> constants s > | ty -> res in > > (* no point to do anything special for records because glimpse is > diff -u -p a/engine/cocci_vs_c.ml b/engine/cocci_vs_c.ml > --- a/engine/cocci_vs_c.ml 2010-09-27 22:21:43.000000000 +0200 > +++ b/engine/cocci_vs_c.ml 2010-10-11 23:14:01.000000000 +0200 > @@ -3298,11 +3298,22 @@ and compatible_type a (b,local) = > | Type_cocci.Array a, (qub, (B.Array (eopt, b),ii)) -> > (* no size info for cocci *) > loop (a,b) > - | Type_cocci.StructUnionName (sua, _, sa), > + | Type_cocci.StructUnionName (sua, Type_cocci.Name sa), > (qub, (B.StructUnionName (sub, sb),ii)) -> > if equal_structUnion_type_cocci sua sub && sa =$= sb > then ok > else fail > + | Type_cocci.StructUnionName (sua, Type_cocci.MV (ida,keep,inherited)), > + (qub, (B.StructUnionName (sub, sb),ii)) -> > + if equal_structUnion_type_cocci sua sub > + then > + (* degenerate version of MetaId, no transformation possible *) > + let (ib1, ib2) = tuple_of_list2 ii in > + let max_min _ = Lib_parsing_c.lin_col_by_pos [ib2] in > + let mida = A.make_mcode ida in > + X.envf keep inherited (mida, B.MetaIdVal (sb,[]), max_min) > + (fun () -> ok) > + else fail > | Type_cocci.EnumName (_, sa), > (qub, (B.EnumName (sb),ii)) -> > if sa =$= sb > diff -u -p a/parsing_cocci/check_meta.ml b/parsing_cocci/check_meta.ml > --- a/parsing_cocci/check_meta.ml 2010-09-27 22:21:44.000000000 +0200 > +++ b/parsing_cocci/check_meta.ml 2010-10-11 23:14:01.000000000 +0200 > @@ -183,6 +183,7 @@ and get_type_name = function > Type_cocci.ConstVol(_,ty) | Type_cocci.SignedT(_,Some ty) > | Type_cocci.Pointer(ty) > | Type_cocci.FunctionPointer(ty) | Type_cocci.Array(ty) -> get_type_name ty > + | Type_cocci.StructUnionName(_,Type_cocci.MV(nm,_,_)) -> Some nm > | Type_cocci.MetaType(nm,_,_) -> Some nm > | _ -> None > > _______________________________________________ Cocci mailing list [email protected] http://lists.diku.dk/mailman/listinfo/cocci (Web access from inside DIKUs LAN only)
