diff options
author | Pascal Rigaux <pixel@mandriva.com> | 2004-08-12 01:04:59 +0000 |
---|---|---|
committer | Pascal Rigaux <pixel@mandriva.com> | 2004-08-12 01:04:59 +0000 |
commit | 7952c6294c573fcd9328399b08d6d79dd28e605d (patch) | |
tree | b192da8368104829f027d7bdf77c1d080dd59878 | |
parent | ab10315e01cd4962d35c9fce53a667df409372f7 (diff) | |
download | perl_checker-7952c6294c573fcd9328399b08d6d79dd28e605d.tar perl_checker-7952c6294c573fcd9328399b08d6d79dd28e605d.tar.gz perl_checker-7952c6294c573fcd9328399b08d6d79dd28e605d.tar.bz2 perl_checker-7952c6294c573fcd9328399b08d6d79dd28e605d.tar.xz perl_checker-7952c6294c573fcd9328399b08d6d79dd28e605d.zip |
check lvalue validity
-rw-r--r-- | perl_checker.src/parser.mly | 4 | ||||
-rw-r--r-- | perl_checker.src/parser_helper.ml | 20 | ||||
-rw-r--r-- | perl_checker.src/parser_helper.mli | 11 | ||||
-rw-r--r-- | perl_checker.src/test/various_errors.t | 3 |
4 files changed, 36 insertions, 2 deletions
diff --git a/perl_checker.src/parser.mly b/perl_checker.src/parser.mly index 10ad566..6a091ac 100644 --- a/perl_checker.src/parser.mly +++ b/perl_checker.src/parser.mly @@ -230,9 +230,9 @@ term: | term MULT_L_STR term {sp_same $2 $3; mcontext_check M_int $3; let pri = P_mul in to_Call_op_ (if mcontext_lower $1.mcontext M_string then M_string else M_list) pri "x" [prio_lo_concat $1; prio_lo_after pri $3] $1 $3} -| term ASSIGN term {sp_same $2 $3; let pri = P_assign in to_Call_op_ (mcontext_op_assign $1 $3) pri $2.any [$1.any.expr ; prio_lo_after pri $3] $1 $3} +| term ASSIGN term {sp_same $2 $3; let pri = P_assign in to_Call_assign_op_ (mcontext_op_assign $1 $3) pri $2.any ($1.any.expr) (prio_lo_after pri $3) $1 $3} -| term ASSIGN BRACKET expr_bracket_end {sp_p($2); sp_p($3); sp_p($4); to_Call_op_ (M_mixed [M_ref M_hash; M_none]) P_assign $2.any [prio_lo P_assign $1; $4.any] $1 $4} +| term ASSIGN BRACKET expr_bracket_end {sp_p($2); sp_p($3); sp_p($4); to_Call_assign_op_ (M_mixed [M_ref M_hash; M_none]) P_assign $2.any (prio_lo P_assign $1) $4.any $1 $4} | term AND_TIGHT BRACKET expr_bracket_end {sp_p($2); sp_p($3); sp_p($4); to_Call_op_ M_bool P_tight_and "&&" [prio_lo P_assign $1; $4.any] $1 $4} | term OR_TIGHT BRACKET expr_bracket_end {sp_p($2); sp_p($3); sp_p($4); to_Call_op_ M_bool P_tight_or "||" [prio_lo P_assign $1; $4.any] $1 $4} diff --git a/perl_checker.src/parser_helper.ml b/perl_checker.src/parser_helper.ml index a673f6d..a32e3fd 100644 --- a/perl_checker.src/parser_helper.ml +++ b/perl_checker.src/parser_helper.ml @@ -98,6 +98,23 @@ let is_always_false = function | Ident(None, "undef", _) -> true | _ -> false +let rec is_lvalue = function + | Call(Deref(I_func, Ident(None, f, _)), _) -> List.mem f [ "substr" ] + + | Call_op("?:", [ _ ; a ; b ], _) -> is_lvalue a && is_lvalue b + + | Call_op("local", l, _) + | List [ List l ] + -> List.for_all is_lvalue l + + | My_our _ + | Deref(_, _) + | Deref_with(_, _, _, _) + | Ident(None, "undef", _) + -> true + + | _ -> false + let not_complex e = if is_parenthesized e then true else let rec not_complex_ op = function @@ -728,6 +745,9 @@ let to_Call_op mcontext op para esp_start esp_end = let to_Call_op_ mcontext prio op para esp_start esp_end = let pos = raw_pos_range esp_start esp_end in new_any mcontext { priority = prio ; expr = cook_call_op op para pos } esp_start.spaces pos +let to_Call_assign_op_ mcontext prio op left right esp_left esp_end = + if not (is_lvalue left) then warn esp_left.pos "invalid lvalue"; + to_Call_op_ mcontext prio op [ left ; right ] esp_left esp_end let followed_by_comma expr true_comma = if true_comma then expr else diff --git a/perl_checker.src/parser_helper.mli b/perl_checker.src/parser_helper.mli index 7ff7c96..ecd5095 100644 --- a/perl_checker.src/parser_helper.mli +++ b/perl_checker.src/parser_helper.mli @@ -45,6 +45,7 @@ val un_parenthesize_full : Types.fromparser -> Types.fromparser val un_parenthesize_full_l : Types.fromparser list -> Types.fromparser list val is_always_true : Types.fromparser -> bool val is_always_false : Types.fromparser -> bool +val is_lvalue : Types.fromparser -> bool val not_complex : Types.fromparser -> bool val not_simple : Types.fromparser -> bool val string_of_Ident : Types.fromparser -> string @@ -105,6 +106,7 @@ val check_arrow_needed : Types.fromparser Types.prio_anyexpr Types.any_spaces_pos -> 'a Types.any_spaces_pos -> unit val check_scalar_subscripted : Types.fromparser Types.any_spaces_pos -> unit +val negatable_ops : (string * string) list val check_negatable_expr : Types.fromparser Types.prio_anyexpr Types.any_spaces_pos -> unit val check_ternary_paras : @@ -181,6 +183,15 @@ val to_Call_op_ : 'a Types.any_spaces_pos -> 'b Types.any_spaces_pos -> Types.fromparser Types.prio_anyexpr Types.any_spaces_pos +val to_Call_assign_op_ : + Types.maybe_context -> + Types.priority -> + string -> + Types.fromparser -> + Types.fromparser -> + 'a Types.any_spaces_pos -> + 'b Types.any_spaces_pos -> + Types.fromparser Types.prio_anyexpr Types.any_spaces_pos val followed_by_comma : Types.fromparser list -> bool -> Types.fromparser list val pot_strings : (string, (string * int * int) * string list) Hashtbl.t diff --git a/perl_checker.src/test/various_errors.t b/perl_checker.src/test/various_errors.t index 535034b..af21eb4 100644 --- a/perl_checker.src/test/various_errors.t +++ b/perl_checker.src/test/various_errors.t @@ -12,9 +12,12 @@ if ($xxx = '') {} are you sure you did not mean "==" inst N("xxx$yyy") don't use interpolated translated string, use %s or %d instead +if ($xxx && $yyy = xxx()) {} invalid lvalue + 1 + 2 >> 3 missing parentheses (needed for clarity) $xxx ? $yyy = 1 : $zzz = 2; missing parentheses (needed for clarity) + invalid lvalue N_("xxx") . 'yyy' N_("xxx") . "yyy" is dumb since the string "xxx" will never get translated |