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)

Reply via email to