diff options
author | Daniel Kraft <d@domob.eu> | 2008-08-22 09:13:25 +0200 |
---|---|---|
committer | Daniel Kraft <domob@gcc.gnu.org> | 2008-08-22 09:13:25 +0200 |
commit | f37e928ca481ce81aeae79ae9fb9504f2d13b3a1 (patch) | |
tree | 7eadcf3647d5b38792adf1c288e5c984abfbad59 /gcc/fortran/expr.c | |
parent | 6b7387327a09e13e7b7ae2fd5f0371b0f88189e9 (diff) | |
download | gcc-f37e928ca481ce81aeae79ae9fb9504f2d13b3a1.zip gcc-f37e928ca481ce81aeae79ae9fb9504f2d13b3a1.tar.gz gcc-f37e928ca481ce81aeae79ae9fb9504f2d13b3a1.tar.bz2 |
re PR fortran/32095 (Accepts invalid character(len(a)),dimension(1) :: a)
2008-08-22 Daniel Kraft <d@domob.eu>
PR fortran/32095
PR fortran/34228
* gfortran.h (in_prefix): New global.
(gfc_check_symbol_typed), (gfc_check_expr_typed): New methods.
* array.c (match_array_element_spec): Check that bounds-expressions
don't have symbols not-yet-typed in them.
* decl.c (var_element): Check that variable used is already typed.
(char_len_param_value): Check that expression does not contain
not-yet-typed symbols.
(in_prefix): New global.
(gfc_match_prefix): Record using `in_prefix' if we're at the moment
parsing a prefix or not.
* expr.c (gfc_expr_check_typed): New method.
* parse.c (verify_st_order): New argument to disable error output.
(check_function_result_typed): New helper method.
(parse_spec): Check that the function-result declaration, if given in
a prefix, contains no not-yet-typed symbols when the IMPLICIT rules are
parsed.
* symbol.c (gfc_check_symbol_typed): Check that a symbol already has
a type associated to it, otherwise use the IMPLICIT rules or signal
an error.
2008-08-22 Daniel Kraft <d@domob.eu>
PR fortran/32095
PR fortran/34228
* gfortran.dg/used_before_typed_1.f90: New test.
* gfortran.dg/used_before_typed_2.f90: New test.
* gfortran.dg/used_before_typed_3.f90: New test.
* gfortran.dg/array_constructor_26.f03: Add -std=gnu to not enable
legacy-behaviour for the new check.
* gfortran.dg/array_constructor_27.f03: Ditto.
* gfortran.dg/blockdata_4.f90: Ditto.
* gfortran.dg/bound_2.f90: Reordered declarations to satisfy the check.
* gfortran.dg/result_in_spec_1.f90: Ditto.
* gfortran.dg/argument_checking_7.f90: Adapted expected error messages.
From-SVN: r139425
Diffstat (limited to 'gcc/fortran/expr.c')
-rw-r--r-- | gcc/fortran/expr.c | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c index 1e92e14..941b5c5 100644 --- a/gcc/fortran/expr.c +++ b/gcc/fortran/expr.c @@ -3266,3 +3266,78 @@ gfc_expr_set_symbols_referenced (gfc_expr *expr) { gfc_traverse_expr (expr, NULL, expr_set_symbols_referenced, 0); } + + +/* Walk an expression tree and check each variable encountered for being typed. + If strict is not set, a top-level variable is tolerated untyped in -std=gnu + mode; this is for things in legacy-code like: + + INTEGER :: arr(n), n + + The namespace is needed for IMPLICIT typing. */ + +gfc_try +gfc_expr_check_typed (gfc_expr* e, gfc_namespace* ns, bool strict) +{ + gfc_try t; + gfc_actual_arglist* act; + gfc_constructor* c; + + if (!e) + return SUCCESS; + + /* FIXME: Check indices for EXPR_VARIABLE / EXPR_SUBSTRING, too, to catch + things like len(arr(1:n)) as specification expression. */ + + switch (e->expr_type) + { + + case EXPR_NULL: + case EXPR_CONSTANT: + case EXPR_SUBSTRING: + break; + + case EXPR_VARIABLE: + gcc_assert (e->symtree); + t = gfc_check_symbol_typed (e->symtree->n.sym, ns, strict, e->where); + if (t == FAILURE) + return t; + break; + + case EXPR_FUNCTION: + for (act = e->value.function.actual; act; act = act->next) + { + t = gfc_expr_check_typed (act->expr, ns, true); + if (t == FAILURE) + return t; + } + break; + + case EXPR_OP: + t = gfc_expr_check_typed (e->value.op.op1, ns, true); + if (t == FAILURE) + return t; + + t = gfc_expr_check_typed (e->value.op.op2, ns, true); + if (t == FAILURE) + return t; + + break; + + case EXPR_STRUCTURE: + case EXPR_ARRAY: + for (c = e->value.constructor; c; c = c->next) + { + t = gfc_expr_check_typed (c->expr, ns, true); + if (t == FAILURE) + return t; + } + break; + + default: + gcc_unreachable (); + + } + + return SUCCESS; +} |