From: Coccinelle Date: Thu, 17 Mar 2011 13:09:14 +0000 (+0100) Subject: Coccinelle release 0.2.5-rc7. X-Git-Url: https://git.hcoop.net/bpt/coccinelle.git/commitdiff_plain/4dfbc1c2559051afaa06fbd7f7be19276d24bf44 Coccinelle release 0.2.5-rc7. ** Language: - Make a very small attempt to parse C++ code, amounting to accepting identifiers containing ::, tilde, and template invocations. Use the option -c++. This is not likely to be very useful in practice. - Added metavariable metavariable type. - Add disjunctions on identifiers in some contexts - Pretend that & indicates a pointer in -c++ mode - Support for new ** Features: - support transformations on variables (only) in declarations that declare multiple variables - allow #endif XXX in C code - relax_include_path now applied to non local includes too, in which case it tries to find a unique file with a suffix of the provided name. this is useful for directories that are intended to be symbolic links. - support matching and removing #undef - support for iteration in ocaml, requires use of -no_show_diff - calls to likely and unlikely propagate test expression status to their arguments - reuse typedefs and macros from complete parsing when reparsing the transformed code - optimization for an if branch that is just { ... } - spatch -control_flow_to_file file.c generates a file file.dot ** Bugfix: - improved parsing of expressions to allow ... to the right of operators in more places - Fix check_config for Python 2.7 on Fedora 14 (Reported-by: Michael Stefaniuc) - Check for ocamlfind in configure (Reported-by: Paul E. McKenney) - Postpone use of ocamlfind at runtime to report fewer errors - Add support for Python 2.4 binding with the provided pycaml library --- diff --git a/changes.txt b/changes.txt index b8dfee8..011dd85 100644 --- a/changes.txt +++ b/changes.txt @@ -22,6 +22,7 @@ - Added metavariable metavariable type. - Add disjunctions on identifiers in some contexts - Pretend that & indicates a pointer in -c++ mode +- Support for new ** Features: - support transformations on variables (only) in declarations that declare @@ -37,6 +38,7 @@ - reuse typedefs and macros from complete parsing when reparsing the transformed code - optimization for an if branch that is just { ... } +- spatch -control_flow_to_file file.c generates a file file.dot ** Bugfix: - improved parsing of expressions to allow ... to the right of operators in diff --git a/docs/manual/main_grammar.pdf b/docs/manual/main_grammar.pdf index f415fd4..fa23684 100644 Binary files a/docs/manual/main_grammar.pdf and b/docs/manual/main_grammar.pdf differ diff --git a/docs/manual/manual.pdf b/docs/manual/manual.pdf index 2753c4e..76d44bb 100644 Binary files a/docs/manual/manual.pdf and b/docs/manual/manual.pdf differ diff --git a/docs/manual/options.pdf b/docs/manual/options.pdf index 4b9da5e..bd235e7 100644 Binary files a/docs/manual/options.pdf and b/docs/manual/options.pdf differ diff --git a/docs/manual/spatch_options.tex b/docs/manual/spatch_options.tex index 8247ed2..09fe72e 100644 --- a/docs/manual/spatch_options.tex +++ b/docs/manual/spatch_options.tex @@ -132,6 +132,13 @@ $\langle$file$\rangle$:$\langle$function$\rangle$}{ Print a control-flow graph for all of the functions in a file or for a specific function in a file. This requires {\tt dot} (http://www.graphviz.org/) and {\tt gv}.} +\rare{-control\_flow\_to\_file $\langle$file$\rangle$, + -control\_flow\_to\_file + $\langle$file$\rangle$:$\langle$function$\rangle$}{ Like -control\_flow + but just puts the dot output in a file in the {\em current} directory. + For PATH/file.c, this produces file:xxx.dot for each (selected) function + xxx in PATH/file.c.} + \rare{-type\_c $\langle$file$\rangle$}{ Parse a C file and pretty-print a version including type information.} diff --git a/engine/cocci_vs_c.ml b/engine/cocci_vs_c.ml index 468db18..fa0e1fe 100644 --- a/engine/cocci_vs_c.ml +++ b/engine/cocci_vs_c.ml @@ -503,7 +503,7 @@ let one_initialisation_to_affectation x = match var with | Some (name, iniopt) -> (match iniopt with - | Some (iini, (B.InitExpr e, ii_empty2)) -> + | B.ValInit (iini, (B.InitExpr e, ii_empty2)) -> let local = match local with Ast_c.NotLocalDecl -> Ast_c.NotLocalVar @@ -1361,6 +1361,7 @@ let rec (expression: (A.expression, Ast_c.expression) matcher) = | _, ((B.StatementExpr _,_),_) | _, ((B.Constructor _,_),_) | _, ((B.New _,_),_) + | _, ((B.Delete _,_),_) -> fail @@ -1790,7 +1791,7 @@ and onedecl = fun allminus decla (declb, iiptvirgb, iistob) -> *) | A.TyDecl (tya0, ptvirga), - ({B.v_namei = Some (nameidb, None); + ({B.v_namei = Some (nameidb, B.NoInit); B.v_type = typb0; B.v_storage = (B.StoTypedef, inl); B.v_local = local; @@ -1854,7 +1855,7 @@ and onedecl = fun allminus decla (declb, iiptvirgb, iistob) -> return ( (A.TyDecl (tya0, ptvirga)) +> A.rewrap decla, - (({B.v_namei = Some (nameidb, None); + (({B.v_namei = Some (nameidb, B.NoInit); B.v_type = typb0; B.v_storage = (B.StoTypedef, inl); B.v_local = local; @@ -1883,7 +1884,7 @@ and onedecl = fun allminus decla (declb, iiptvirgb, iistob) -> return ( (A.TyDecl (tya0, ptvirga)) +> A.rewrap decla, - (({B.v_namei = Some (nameidb, None); + (({B.v_namei = Some (nameidb, B.NoInit); B.v_type = typb0; B.v_storage = (B.StoTypedef, inl); B.v_local = local; @@ -1915,7 +1916,7 @@ and onedecl = fun allminus decla (declb, iiptvirgb, iistob) -> (* could handle iso here but handled in standard.iso *) | A.UnInit (stoa, typa, ida, ptvirga), - ({B.v_namei = Some (nameidb, None); + ({B.v_namei = Some (nameidb, B.NoInit); B.v_type = typb; B.v_storage = stob; B.v_local = local; @@ -1929,7 +1930,7 @@ and onedecl = fun allminus decla (declb, iiptvirgb, iistob) -> (fun stoa (stob, iistob) -> return ( (A.UnInit (stoa, typa, ida, ptvirga)) +> A.rewrap decla, - (({B.v_namei = Some (nameidb, None); + (({B.v_namei = Some (nameidb, B.NoInit); B.v_type = typb; B.v_storage = stob; B.v_local = local; @@ -1940,7 +1941,7 @@ and onedecl = fun allminus decla (declb, iiptvirgb, iistob) -> ))))) | A.Init (stoa, typa, ida, eqa, inia, ptvirga), - ({B.v_namei = Some(nameidb, Some (iieqb, inib)); + ({B.v_namei = Some(nameidb, B.ValInit (iieqb, inib)); B.v_type = typb; B.v_storage = stob; B.v_local = local; @@ -1957,7 +1958,7 @@ and onedecl = fun allminus decla (declb, iiptvirgb, iistob) -> initialiser inia inib >>= (fun inia inib -> return ( (A.Init (stoa, typa, ida, eqa, inia, ptvirga)) +> A.rewrap decla, - (({B.v_namei = Some(nameidb, Some (iieqb, inib)); + (({B.v_namei = Some(nameidb, B.ValInit (iieqb, inib)); B.v_type = typb; B.v_storage = stob; B.v_local = local; @@ -1967,6 +1968,16 @@ and onedecl = fun allminus decla (declb, iiptvirgb, iistob) -> iiptvirgb,iistob) ))))))) + | A.Init (stoa, typa, ida, eqa, inia, ptvirga), + ({B.v_namei = Some(nameidb, B.ConstrInit _); + B.v_type = typb; + B.v_storage = stob; + B.v_local = local; + B.v_attr = attrs; + B.v_type_bis = typbbis; + },iivirg) + -> fail (* C++ constructor declaration not supported in SmPL *) + (* do iso-by-absence here ? allow typedecl and var ? *) | A.TyDecl (typa, ptvirga), ({B.v_namei = None; B.v_type = typb; @@ -1994,7 +2005,7 @@ and onedecl = fun allminus decla (declb, iiptvirgb, iistob) -> | A.Typedef (stoa, typa, ida, ptvirga), - ({B.v_namei = Some (nameidb, None); + ({B.v_namei = Some (nameidb, B.NoInit); B.v_type = typb; B.v_storage = (B.StoTypedef,inline); B.v_local = local; @@ -2047,7 +2058,7 @@ and onedecl = fun allminus decla (declb, iiptvirgb, iistob) -> ) >>= (fun ida nameidb -> return ( (A.Typedef (stoa, typa, ida, ptvirga)) +> A.rewrap decla, - (({B.v_namei = Some (nameidb, None); + (({B.v_namei = Some (nameidb, B.NoInit); B.v_type = typb; B.v_storage = (B.StoTypedef,inline); B.v_local = local; @@ -2403,7 +2414,7 @@ and (struct_field: (A.declaration, B.field) matcher) = fun fa fb -> let iisto = [] in let stob = B.NoSto, false in let fake_var = - ({B.v_namei = Some (nameidb, None); + ({B.v_namei = Some (nameidb, B.NoInit); B.v_type = typb; B.v_storage = stob; B.v_local = Ast_c.NotLocalDecl; @@ -2418,7 +2429,7 @@ and (struct_field: (A.declaration, B.field) matcher) = fun fa fb -> (fun fa (var,iiptvirgb,iisto) -> match fake_var with - | ({B.v_namei = Some (nameidb, None); + | ({B.v_namei = Some (nameidb, B.NoInit); B.v_type = typb; B.v_storage = stob; }, iivirg) -> diff --git a/globals/config.ml.in b/globals/config.ml.in index 13d843a..148728e 100644 --- a/globals/config.ml.in +++ b/globals/config.ml.in @@ -1,4 +1,4 @@ -let version = "0.2.5-rc6" +let version = "0.2.5-rc7" let path = try (Sys.getenv "COCCINELLE_HOME") diff --git a/parsing_c/ast_c.ml b/parsing_c/ast_c.ml index 431d107..c4d7254 100644 --- a/parsing_c/ast_c.ml +++ b/parsing_c/ast_c.ml @@ -337,10 +337,11 @@ and expression = (expressionbis * exp_info ref (* semantic: *)) wrap3 (* for C++: *) | New of argument + | Delete of expression (* cppext: IfdefExpr TODO *) - (* cppext: normmally just expression *) + (* cppext: normally just expression *) and argument = (expression, weird_argument) Common.either and weird_argument = | ArgType of parameterType @@ -516,7 +517,7 @@ and declaration = | MacroDecl of (string * argument wrap2 list) wrap (* fakestart *) and onedecl = - { v_namei: (name * (info (* = *) * initialiser) option) option; + { v_namei: (name * v_init) option; v_type: fullType; (* semantic: set in type annotated and used in cocci_vs_c * when we transform some initialisation into affectation @@ -526,6 +527,9 @@ and declaration = v_local: local_decl; (* cocci: *) v_attr: attribute list; (* gccext: *) } + and v_init = + NoInit | ValInit of info * initialiser + | ConstrInit of argument wrap2 (* , *) list wrap and storage = storagebis * bool (* gccext: inline or not *) and storagebis = NoSto | StoTypedef | Sto of storageClass and storageClass = Auto | Static | Register | Extern diff --git a/parsing_c/lexer_c.mll b/parsing_c/lexer_c.mll index a45e120..fbad367 100644 --- a/parsing_c/lexer_c.mll +++ b/parsing_c/lexer_c.mll @@ -170,7 +170,8 @@ let keyword_table = Common.hash_of_list [ ] let cpp_keyword_table = Common.hash_of_list [ - "new", (fun ii -> Tnew ii) ] + "new", (fun ii -> Tnew ii); + "delete",(fun ii -> Tdelete ii) ] let error_radix s = ("numeric " ^ s ^ " constant contains digits beyond the radix:") @@ -685,6 +686,7 @@ rule token = parse TIdent (s, info) } | (letter | '$') (letter | digit | '$') * + ('<' (letter | '$' | '~') (letter | digit | '$' | '~') * '>') ? ("::~" (letter | '$') (letter | digit | '$') * ('<' (letter | '$' | '~') (letter | digit | '$' | '~') * '>') ?) + @@ -700,7 +702,23 @@ rule token = parse raise (Lexical "~ and :: not allowed in C identifiers, try -c++ option") } + | ((letter | '$') (letter | digit | '$') *) + ('<' (letter | '$' | '~') (letter | digit | '$' | '~') * '>') + + { + if !Flag.c_plus_plus + then + begin + let info = tokinfo lexbuf in + let s = tok lexbuf in + TypedefIdent (s, info) + end + else raise (Lexical "<> detected, try -c++ option") + } + + | (((letter | '$') (letter | digit | '$') *) as first) + ('<' (letter | '$' | '~') (letter | digit | '$' | '~') * '>') ? "::" (((letter | '$') (letter | digit | '$') *) as second) ('<' (letter | '$' | '~') (letter | digit | '$' | '~') * '>') ? ("::" ((letter | '$') (letter | digit | '$') *) @@ -721,6 +739,24 @@ rule token = parse (Lexical "~ and :: not allowed in C identifiers, try -c++ option") } + | "::" ((letter | '$') (letter | digit | '$') *) + ('<' (letter | '$' | '~') (letter | digit | '$' | '~') * '>') ? + ("::" ((letter | '$') (letter | digit | '$') *) + ('<' (letter | '$' | '~') (letter | digit | '$' | '~') * '>') ?) * + + { + if !Flag.c_plus_plus + then + begin + let info = tokinfo lexbuf in + let s = tok lexbuf in + TIdent (s, info) + end + else + raise + (Lexical "~ and :: not allowed in C identifiers, try -c++ option") + } + (* ----------------------------------------------------------------------- *) (* C constant *) diff --git a/parsing_c/parser_c.mly b/parsing_c/parser_c.mly index 75dde11..54e22c3 100644 --- a/parsing_c/parser_c.mly +++ b/parsing_c/parser_c.mly @@ -436,7 +436,7 @@ let mk_string_wrap (s,info) = (s, [info]) Tstruct Tunion Tenum Tbreak Telse Tswitch Tcase Tcontinue Tfor Tdo Tif Twhile Treturn Tgoto Tdefault - Tsizeof Tnew + Tsizeof Tnew Tdelete TOParCplusplusInit /*(* C99 *)*/ %token @@ -738,15 +738,38 @@ unary_expr: | Tsizeof unary_expr { mk_e(SizeOfExpr ($2)) [$1] } | Tsizeof topar2 type_name tcpar2 { mk_e(SizeOfType ($3)) [$1;$2;$4] } | Tnew new_argument { mk_e(New $2) [$1] } + | Tdelete cast_expr { mk_e(Delete $2) [$1] } new_argument: - | postfix_expr { Left $1 } - | decl_spec - { let ((returnType,hasreg), iihasreg) = fixDeclSpecForParam $1 in + | TIdent TOPar argument_list_ne TCPar + { let fn = mk_e(Ident (RegularName (mk_string_wrap $1))) [] in + Left (mk_e(FunCall (fn, $3)) [$2;$4]) } + | TIdent TOPar TCPar + { let fn = mk_e(Ident (RegularName (mk_string_wrap $1))) [] in + Left(mk_e(FunCall (fn, [])) [$2;$3]) } + | TypedefIdent TOPar argument_list_ne TCPar + { let fn = mk_e(Ident (RegularName (mk_string_wrap $1))) [] in + Left (mk_e(FunCall (fn, $3)) [$2;$4]) } + | TypedefIdent TOPar TCPar + { let fn = mk_e(Ident (RegularName (mk_string_wrap $1))) [] in + Left (mk_e(FunCall (fn, [])) [$2;$3]) } + | type_spec + { let ty = addTypeD ($1,nullDecl) in + let ((returnType,hasreg), iihasreg) = fixDeclSpecForParam ty in Right (ArgType { p_namei = None; p_type = returnType; p_register = hasreg, iihasreg; } ) } + | new_argument TOCro expr TCCro + { + match $1 with + Left(e) -> Left(mk_e(ArrayAccess (e, $3)) [$2;$4]) + | Right(ArgType(ty)) -> (* lots of hacks to make the right type *) + let fty = mk_ty (Array (Some $3, ty.Ast_c.p_type)) [$2;$4] in + let pty = { ty with p_type = fty } in + Right(ArgType pty) + | _ -> raise Impossible + } unary_op: | TAnd { GetRef, $1 } @@ -778,6 +801,7 @@ postfix_expr: | topar2 type_name tcpar2 TOBrace initialize_list gcc_comma_opt TCBrace { mk_e(Constructor ($2, List.rev $5)) ([$1;$3;$4;$7] ++ $6) } + primary_expr: | identifier_cpp { mk_e(Ident ($1)) [] } | TInt @@ -1298,14 +1322,9 @@ decl2: DeclList ( ($2 +> List.map (fun ((((name,f),attrs), ini), iivirg) -> let s = str_of_name name in - let iniopt = - match ini with - | None -> None - | Some (ini, iini) -> Some (iini, ini) - in if fst (unwrap storage) =*= StoTypedef then LP.add_typedef s; - {v_namei = Some (name, iniopt); + {v_namei = Some (name, ini); v_type = f returnType; v_storage = unwrap storage; v_local = local; @@ -1370,9 +1389,11 @@ decl_spec: decl_spec2 { dt "declspec" (); $1 } /*(* declarators (right part of type and variable) *)*/ /*(*-----------------------------------------------------------------------*)*/ init_declarator2: - | declaratori { ($1, None) } - | declaratori teq initialize { ($1, Some ($3, $2)) } - + | declaratori { ($1, NoInit) } + | declaratori teq initialize { ($1, ValInit($2, $3)) } + /* C++ only */ + | declaratori TOParCplusplusInit argument_list TCPar + { ($1, ConstrInit($3,[$2;$4])) } /*(*----------------------------*)*/ diff --git a/parsing_c/parsing_hacks.ml b/parsing_c/parsing_hacks.ml index 835fa8c..f9019e8 100644 --- a/parsing_c/parsing_hacks.ml +++ b/parsing_c/parsing_hacks.ml @@ -81,12 +81,13 @@ let is_known_typdef = * because it would compute msg_typedef at compile time when * the flag debug_typedef is always false *) -let msg_typedef s = +let msg_typedef s n = incr Stat.nTypedefInfer; msg_gen (!Flag_parsing_c.debug_typedef) is_known_typdef (fun s -> - pr2_cpp ("TYPEDEF: promoting: " ^ s) + (*pr2_cpp (Printf.sprintf "TYPEDEF: promoting(%d): %s" n s)*) + pr2_cpp (Printf.sprintf "TYPEDEF: promoting: %s" s) ) s @@ -1643,6 +1644,16 @@ let lookahead2 ~pass next before = match (next, before) with + (* c++ hacks *) + (* yy xx( and in function *) + | TOPar i1::_, TIdent(s,i2)::TypedefIdent _::_ + when !Flag.c_plus_plus && (LP.current_context () = (LP.InFunction)) -> + pr2_cpp("constructed_object: " ^s); + TOParCplusplusInit i1 + | TypedefIdent(s,i)::TOPar i1::_,_ + when !Flag.c_plus_plus && (LP.current_context () = (LP.InFunction)) -> + TIdent(s,i) + (*-------------------------------------------------------------*) (* typedef inference, parse_typedef_fix3 *) (*-------------------------------------------------------------*) @@ -1663,7 +1674,7 @@ let lookahead2 ~pass next before = LP.disable_typedef(); - msg_typedef s; LP.add_typedef_root s; + msg_typedef s 1; LP.add_typedef_root s; TypedefIdent (s, i1) (* xx yy *) @@ -1672,7 +1683,7 @@ let lookahead2 ~pass next before = -> (* && not_annot s2 BUT lead to false positive*) - msg_typedef s; LP.add_typedef_root s; + msg_typedef s 2; LP.add_typedef_root s; TypedefIdent (s, i1) @@ -1680,7 +1691,7 @@ let lookahead2 ~pass next before = | (TIdent (s, i1)::Tinline i2::_ , _) when not_struct_enum before && ok_typedef s -> - msg_typedef s; LP.add_typedef_root s; + msg_typedef s 3; LP.add_typedef_root s; TypedefIdent (s, i1) @@ -1689,7 +1700,7 @@ let lookahead2 ~pass next before = when not_struct_enum before && (LP.current_context() =*= LP.InParameter) && ok_typedef s -> - msg_typedef s; LP.add_typedef_root s; + msg_typedef s 4; LP.add_typedef_root s; TypedefIdent (s, i1) (* xx* [,)] *) @@ -1699,7 +1710,7 @@ let lookahead2 ~pass next before = (* && !LP._lexer_hint = Some LP.ParameterDeclaration *) && ok_typedef s -> - msg_typedef s; LP.add_typedef_root s; + msg_typedef s 5; LP.add_typedef_root s; TypedefIdent (s, i1) @@ -1710,7 +1721,7 @@ let lookahead2 ~pass next before = (* && !LP._lexer_hint = Some LP.ParameterDeclaration *) && ok_typedef s -> - msg_typedef s; LP.add_typedef_root s; + msg_typedef s 6; LP.add_typedef_root s; TypedefIdent (s, i1) @@ -1722,7 +1733,7 @@ let lookahead2 ~pass next before = && ok_typedef s -> - msg_typedef s; LP.add_typedef_root s; + msg_typedef s 7; LP.add_typedef_root s; TypedefIdent (s, i1) (* xx const *) @@ -1732,7 +1743,7 @@ let lookahead2 ~pass next before = (* && !LP._lexer_hint = Some LP.ParameterDeclaration *) -> - msg_typedef s; LP.add_typedef_root s; + msg_typedef s 8; LP.add_typedef_root s; TypedefIdent (s, i1) @@ -1743,14 +1754,14 @@ let lookahead2 ~pass next before = -> (* && !LP._lexer_hint = Some LP.ParameterDeclaration *) - msg_typedef s; LP.add_typedef_root s; + msg_typedef s 9; LP.add_typedef_root s; TypedefIdent (s, i1) (* ( const xx) *) | (TIdent (s, i1)::TCPar _::_, (Tconst _ | Tvolatile _|Trestrict _)::TOPar _::_) when ok_typedef s -> - msg_typedef s; LP.add_typedef_root s; + msg_typedef s 10; LP.add_typedef_root s; TypedefIdent (s, i1) @@ -1760,7 +1771,7 @@ let lookahead2 ~pass next before = when not_struct_enum before && ok_typedef s -> - msg_typedef s; LP.add_typedef_root s; + msg_typedef s 11; LP.add_typedef_root s; TypedefIdent (s, i1) (* [(,] xx [ AND parameterdeclaration *) @@ -1768,7 +1779,7 @@ let lookahead2 ~pass next before = when (LP.current_context() =*= LP.InParameter) && ok_typedef s -> - msg_typedef s; LP.add_typedef_root s; + msg_typedef s 12; LP.add_typedef_root s; TypedefIdent (s, i1) (*------------------------------------------------------------*) @@ -1781,7 +1792,7 @@ let lookahead2 ~pass next before = (Tregister _|Tstatic _ |Tvolatile _|Tconst _|Trestrict _)::_) when pointer ptr && ok_typedef s -> - msg_typedef s; LP.add_typedef_root s; + msg_typedef s 13; LP.add_typedef_root s; TypedefIdent (s, i1) (* TODO xx * yy ; AND in start of compound element *) @@ -1793,7 +1804,7 @@ let lookahead2 ~pass next before = && pointer ptr && ok_typedef s -> - msg_typedef s; LP.add_typedef_root s; + msg_typedef s 14; LP.add_typedef_root s; TypedefIdent (s, i1) @@ -1804,7 +1815,7 @@ let lookahead2 ~pass next before = when not_struct_enum before && pointer ptr && (LP.is_top_or_struct (LP.current_context ())) -> - msg_typedef s; LP.add_typedef_root s; + msg_typedef s 15; LP.add_typedef_root s; TypedefIdent (s, i1) (* xx * yy , AND in Toplevel *) @@ -1813,7 +1824,7 @@ let lookahead2 ~pass next before = && ok_typedef s && pointer ptr -> - msg_typedef s; LP.add_typedef_root s; + msg_typedef s 16; LP.add_typedef_root s; TypedefIdent (s, i1) (* xx * yy ( AND in Toplevel *) @@ -1822,7 +1833,7 @@ let lookahead2 ~pass next before = && (LP.is_top_or_struct (LP.current_context ())) && ok_typedef s && pointer ptr -> - msg_typedef s; LP.add_typedef_root s; + msg_typedef s 17; LP.add_typedef_root s; TypedefIdent (s, i1) (* xx * yy [ *) @@ -1832,7 +1843,7 @@ let lookahead2 ~pass next before = (LP.is_top_or_struct (LP.current_context ())) && ok_typedef s && pointer ptr -> - msg_typedef s; LP.add_typedef_root s; + msg_typedef s 18; LP.add_typedef_root s; TypedefIdent (s, i1) (* u16: 10; in struct *) @@ -1840,7 +1851,7 @@ let lookahead2 ~pass next before = when (LP.is_top_or_struct (LP.current_context ())) && ok_typedef s -> - msg_typedef s; LP.add_typedef_root s; + msg_typedef s 19; LP.add_typedef_root s; TypedefIdent (s, i1) @@ -1853,7 +1864,7 @@ let lookahead2 ~pass next before = (take_safe 1 !passed_tok <> [Tenum])) && !LP._lexer_hint = Some LP.Toplevel -> - msg_typedef s; LP.add_typedef_root s; + msg_typedef s 20; LP.add_typedef_root s; TypedefIdent s *) @@ -1862,7 +1873,7 @@ let lookahead2 ~pass next before = when not_struct_enum before && ok_typedef s && pointer ptr -> - msg_typedef s; LP.add_typedef_root s; + msg_typedef s 21; LP.add_typedef_root s; TypedefIdent (s, i1) @@ -1871,7 +1882,7 @@ let lookahead2 ~pass next before = when not_struct_enum before && (LP.current_context () =*= LP.InParameter) && ok_typedef s && pointer ptr -> - msg_typedef s; LP.add_typedef_root s; + msg_typedef s 22; LP.add_typedef_root s; TypedefIdent (s, i1) @@ -1880,7 +1891,7 @@ let lookahead2 ~pass next before = (TOBrace _| TPtVirg _)::_) when not_struct_enum before && ok_typedef s & pointer ptr -> - msg_typedef s; LP.add_typedef_root s; + msg_typedef s 23; LP.add_typedef_root s; msg_maybe_dangereous_typedef s; TypedefIdent (s, i1) @@ -1890,7 +1901,7 @@ let lookahead2 ~pass next before = (TOBrace _| TPtVirg _)::_) when ok_typedef s && pointer ptr -> - msg_typedef s; LP.add_typedef_root s; + msg_typedef s 24; LP.add_typedef_root s; TypedefIdent (s, i1) @@ -1900,7 +1911,7 @@ let lookahead2 ~pass next before = (* struct user_info_t sometimes *) && ok_typedef s && pointer ptr -> - msg_typedef s; LP.add_typedef_root s; + msg_typedef s 25; LP.add_typedef_root s; TypedefIdent (s, i1) (* xx ** yy *) (* wrong ? *) @@ -1909,7 +1920,7 @@ let lookahead2 ~pass next before = (* && !LP._lexer_hint = Some LP.ParameterDeclaration *) && ok_typedef s -> - msg_typedef s; LP.add_typedef_root s; + msg_typedef s 26; LP.add_typedef_root s; TypedefIdent (s, i1) (* xx *** yy *) @@ -1918,7 +1929,7 @@ let lookahead2 ~pass next before = && ok_typedef s (* && !LP._lexer_hint = Some LP.ParameterDeclaration *) -> - msg_typedef s; LP.add_typedef_root s; + msg_typedef s 27; LP.add_typedef_root s; TypedefIdent (s, i1) (* xx ** ) *) @@ -1927,7 +1938,7 @@ let lookahead2 ~pass next before = (* && !LP._lexer_hint = Some LP.ParameterDeclaration *) && ok_typedef s -> - msg_typedef s; LP.add_typedef_root s; + msg_typedef s 28; LP.add_typedef_root s; TypedefIdent (s, i1) @@ -1947,7 +1958,7 @@ let lookahead2 ~pass next before = && ok_typedef s -> - msg_typedef s; LP.add_typedef_root s; + msg_typedef s 29; LP.add_typedef_root s; (*TOPar info*) TypedefIdent (s, i1) @@ -1960,7 +1971,7 @@ let lookahead2 ~pass next before = when not (TH.is_stuff_taking_parenthized x) && ok_typedef s -> - msg_typedef s; LP.add_typedef_root s; + msg_typedef s 30; LP.add_typedef_root s; (* TOPar info *) TypedefIdent (s, i1) *) @@ -1969,7 +1980,7 @@ let lookahead2 ~pass next before = (TOPar info)::(TEq _ |TEqEq _)::_) when ok_typedef s -> - msg_typedef s; LP.add_typedef_root s; + msg_typedef s 31; LP.add_typedef_root s; (* TOPar info *) TypedefIdent (s, i1) @@ -1978,7 +1989,7 @@ let lookahead2 ~pass next before = | (TIdent (s, i1)::ptr::TCPar _::TIdent (s2, i2)::_ , (TOPar info)::_) when ok_typedef s && pointer ptr -> - msg_typedef s; LP.add_typedef_root s; + msg_typedef s 32; LP.add_typedef_root s; (*TOPar info*) TypedefIdent (s,i1) @@ -1988,7 +1999,7 @@ let lookahead2 ~pass next before = when (*s ==~ regexp_typedef && *) not (TH.is_stuff_taking_parenthized x) && ok_typedef s -> - msg_typedef s; LP.add_typedef_root s; + msg_typedef s 33; LP.add_typedef_root s; TypedefIdent (s, i1) @@ -2005,7 +2016,7 @@ let lookahead2 ~pass next before = when not_struct_enum before && ok_typedef s -> - msg_typedef s; LP.add_typedef_root s; + msg_typedef s 34; LP.add_typedef_root s; TypedefIdent (s, i1) (* x* ( *y )(params), function pointer 2 *) @@ -2013,7 +2024,7 @@ let lookahead2 ~pass next before = when not_struct_enum before && ok_typedef s -> - msg_typedef s; LP.add_typedef_root s; + msg_typedef s 35; LP.add_typedef_root s; TypedefIdent (s, i1) diff --git a/parsing_c/pretty_print_c.ml b/parsing_c/pretty_print_c.ml index 80e8eea..66060d3 100644 --- a/parsing_c/pretty_print_c.ml +++ b/parsing_c/pretty_print_c.ml @@ -145,7 +145,8 @@ let mk_pretty_printers | ParenExpr (e), [i1;i2] -> pr_elem i1; pp_expression e; pr_elem i2; - | New (t), [i1] -> pr_elem i1; pp_argument t + | New (t), [i1] -> pr_elem i1; pp_argument t + | Delete(t), [i1] -> pr_elem i1; pp_expression t | (Ident (_) | Constant _ | FunCall (_,_) | CondExpr (_,_,_) | Sequence (_,_) @@ -154,7 +155,7 @@ let mk_pretty_printers | ArrayAccess (_,_) | RecordAccess (_,_) | RecordPtAccess (_,_) | SizeOfExpr (_) | SizeOfType (_) | Cast (_,_) | StatementExpr (_) | Constructor _ - | ParenExpr (_) | New (_)),_ -> raise Impossible + | ParenExpr (_) | New (_) | Delete (_)),_ -> raise Impossible ); if !Flag_parsing_c.pretty_print_type_info @@ -860,9 +861,12 @@ let mk_pretty_printers pp_type_with_ident (Some (s, iis)) (Some (storage, iisto)) returnType attrs; - iniopt +> do_option (fun (iini, init) -> - pr_elem iini; - pp_init init); + (match iniopt with + Ast_c.NoInit -> () + | Ast_c.ValInit(iini,init) -> pr_elem iini; pp_init init + | Ast_c.ConstrInit((init,[lp;rp])) -> + pr_elem lp; pp_arg_list init; pr_elem rp + | Ast_c.ConstrInit _ -> raise Impossible) | None -> pp_type returnType ); @@ -879,9 +883,12 @@ let mk_pretty_printers iivirg +> List.iter pr_elem; pp_type_with_ident_rest (Some (s, iis)) returnType attrs; - iniopt +> do_option (fun (iini, init) -> - pr_elem iini; pp_init init - ); + (match iniopt with + Ast_c.NoInit -> () + | Ast_c.ValInit(iini,init) -> pr_elem iini; pp_init init + | Ast_c.ConstrInit((init,[lp;rp])) -> + pr_elem lp; pp_arg_list init; pr_elem rp + | Ast_c.ConstrInit _ -> raise Impossible); | x -> raise Impossible diff --git a/parsing_c/test_parsing_c.ml b/parsing_c/test_parsing_c.ml index fc0e980..9150a8a 100644 --- a/parsing_c/test_parsing_c.ml +++ b/parsing_c/test_parsing_c.ml @@ -138,16 +138,18 @@ let local_test_cfg launchgv file = program +> List.iter (fun (e,_) -> let toprocess = match specific_func, e with - | None, _ -> true + | None, Ast_c.Definition (defbis,_) -> + Some (Ast_c.str_of_name (defbis.Ast_c.f_name)) | Some s, Ast_c.Definition (defbis,_) -> - s =$= Ast_c.str_of_name (defbis.Ast_c.f_name) - | _, _ -> false + let nm = Ast_c.str_of_name (defbis.Ast_c.f_name) in + if s =$= nm then Some nm else None + | _, _ -> None in - if toprocess - then - (* old: Flow_to_ast.test !Flag.show_flow def *) - (try + match toprocess with + None -> () + | Some fn -> (* old: Flow_to_ast.test !Flag.show_flow def *) + try let flow = Ast_to_flow.ast_to_control_flow e in flow +> do_option (fun flow -> Ast_to_flow.deadcode_detection flow; @@ -161,12 +163,16 @@ let local_test_cfg launchgv file = *) flow in - let filename = Filename.temp_file "output" ".dot" in + let filename = + if launchgv + then Filename.temp_file "output" ".dot" + else + let fl = Filename.chop_extension (Filename.basename file) in + fl^":"^fn^".dot" in Ograph_extended.print_ograph_mutable flow' (filename) launchgv ) with Ast_to_flow.Error (x) -> Ast_to_flow.report_error x ) - ) let test_cfg = local_test_cfg true diff --git a/parsing_c/token_helpers.ml b/parsing_c/token_helpers.ml index 492c5cd..a8ecfa3 100644 --- a/parsing_c/token_helpers.ml +++ b/parsing_c/token_helpers.ml @@ -359,6 +359,8 @@ let info_of_tok = function | Tinline (i) -> i | Ttypeof (i) -> i | Tnew (i) -> i + | Tdelete (i) -> i + | TOParCplusplusInit (i) -> i | EOF (i) -> i @@ -510,10 +512,12 @@ let visitor_info_of_tok f = function | Tsizeof (i) -> Tsizeof (f i) | Tasm (i) -> Tasm (f i) | Tattribute (i) -> Tattribute (f i) - | TattributeNoarg (i) -> TattributeNoarg (f i) + | TattributeNoarg (i) -> TattributeNoarg (f i) | Tinline (i) -> Tinline (f i) | Ttypeof (i) -> Ttypeof (f i) | Tnew (i) -> Tnew (f i) + | Tdelete (i) -> Tdelete (f i) + | TOParCplusplusInit (i) -> TOParCplusplusInit (f i) | EOF (i) -> EOF (f i) diff --git a/parsing_c/type_annoter_c.ml b/parsing_c/type_annoter_c.ml index b52b593..010f2ab 100644 --- a/parsing_c/type_annoter_c.ml +++ b/parsing_c/type_annoter_c.ml @@ -945,6 +945,11 @@ let annotater_expr_visitor_subpart = (fun (k,bigf) expr -> pr2_once "Type annotater:not handling New"; Type_c.noTypeHere (* TODO *) + | Delete e -> + k expr; + pr2_once "Type annotater:not handling Delete"; + Type_c.noTypeHere (* TODO *) + in Ast_c.set_type_expr expr ty @@ -1085,9 +1090,13 @@ let rec visit_toplevel ~just_add_in_env ~depth elem = if need_annotate_body then begin (* int x = sizeof(x) is legal so need process ini *) - iniopt +> Common.do_option (fun (info, ini) -> - Visitor_c.vk_ini bigf ini - ); + match iniopt with + Ast_c.NoInit -> () + | Ast_c.ValInit(iini,init) -> Visitor_c.vk_ini bigf init + | Ast_c.ConstrInit((args,_)) -> + args +> List.iter (fun (e,ii) -> + Visitor_c.vk_argument bigf e + ) end ); ); diff --git a/parsing_c/visitor_c.ml b/parsing_c/visitor_c.ml index b8f16dd..867b18e 100644 --- a/parsing_c/visitor_c.ml +++ b/parsing_c/visitor_c.ml @@ -330,7 +330,8 @@ let rec vk_expr = fun bigf expr -> | ParenExpr (e) -> exprf e - | New t -> vk_argument bigf t + | New t -> vk_argument bigf t + | Delete e -> vk_expr bigf e in exprf expr @@ -519,10 +520,10 @@ and vk_onedecl = fun bigf onedecl -> attrs +> List.iter (vk_attribute bigf); var +> Common.do_option (fun (name, iniopt) -> vk_name bigf name; - iniopt +> Common.do_option (fun (info, ini) -> - iif [info]; - vk_ini bigf ini; - ); + (match iniopt with + Ast_c.NoInit -> () + | Ast_c.ValInit(iini,init) -> iif [iini]; vk_ini bigf init + | Ast_c.ConstrInit((init,ii)) -> iif ii; vk_argument_list bigf init) ) in f (k, bigf) onedecl @@ -1058,6 +1059,7 @@ let rec vk_expr_s = fun bigf expr -> | ParenExpr (e) -> ParenExpr (exprf e) | New t -> New (vk_argument_s bigf t) + | Delete e -> Delete (vk_expr_s bigf e) in (e', typ'), (iif ii) @@ -1298,10 +1300,15 @@ and vk_decl_s = fun bigf d -> {v_namei = (var +> map_option (fun (name, iniopt) -> vk_name_s bigf name, - iniopt +> map_option (fun (info, init) -> - vk_info_s bigf info, - vk_ini_s bigf init - ))); + (match iniopt with + Ast_c.NoInit -> iniopt + | Ast_c.ValInit(iini,init) -> + Ast_c.ValInit(vk_info_s bigf iini,vk_ini_s bigf init) + | Ast_c.ConstrInit((init,ii)) -> + let init = + init +> List.map (fun (e,ii) -> vk_argument_s bigf e, iif ii) in + Ast_c.ConstrInit((init, List.map (vk_info_s bigf) ii))) + )); v_type = vk_type_s bigf t; (* !!! dont go in semantic related stuff !!! *) v_type_bis = tbis;