diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 21e7dbe676d..a1a2cd2dd53 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,18 @@ +2012-09-15 Tobias Burnus + + * match.c (lock_unlock_statement, sync_statement): Fix potential + double freeing. + (sync_statement): Remove unreachable code. + * simplify.c (gfc_simplify_bessel_n2): Avoid double freeing. + (gfc_simplify_repeat): Remove bogus code. + * target-memory.h (gfc_target_encode_expr): Update prototype. + * target-memory.c (gfc_target_encode_expr, encode_array, + encode_derived): Return unsigned HOST_WIDE_INT. + (gfc_target_interpret_expr): Add assert. + (gfc_merge_initializers): Fix "== 0" check for mpz_t. + * symbol.c (gfc_get_typebound_proc): Add assert. + (gfc_merge_initializers): Remove unreachable check. + 2012-09-13 Tobias Burnus PR fortran/54556 diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c index cf85d527749..d46a495ae01 100644 --- a/gcc/fortran/match.c +++ b/gcc/fortran/match.c @@ -2964,11 +2964,15 @@ syntax: gfc_syntax_error (st); cleanup: + if (acq_lock != tmp) + gfc_free_expr (acq_lock); + if (errmsg != tmp) + gfc_free_expr (errmsg); + if (stat != tmp) + gfc_free_expr (stat); + gfc_free_expr (tmp); gfc_free_expr (lockvar); - gfc_free_expr (acq_lock); - gfc_free_expr (stat); - gfc_free_expr (errmsg); return MATCH_ERROR; } @@ -3121,9 +3125,6 @@ sync_statement (gfc_statement st) break; } - if (m == MATCH_ERROR) - goto syntax; - if (gfc_match (" )%t") != MATCH_YES) goto syntax; @@ -3153,10 +3154,13 @@ syntax: gfc_syntax_error (st); cleanup: + if (stat != tmp) + gfc_free_expr (stat); + if (errmsg != tmp) + gfc_free_expr (errmsg); + gfc_free_expr (tmp); gfc_free_expr (imageset); - gfc_free_expr (stat); - gfc_free_expr (errmsg); return MATCH_ERROR; } diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c index 07aeee88e15..5aa27044d08 100644 --- a/gcc/fortran/simplify.c +++ b/gcc/fortran/simplify.c @@ -1370,7 +1370,11 @@ gfc_simplify_bessel_n2 (gfc_expr *order1, gfc_expr *order2, gfc_expr *x, mpfr_sub (e->value.real, e->value.real, last1, GFC_RND_MODE); if (range_check (e, jn ? "BESSEL_JN" : "BESSEL_YN") == &gfc_bad_expr) - goto error; + { + /* Range_check frees "e" in that case. */ + e = NULL; + goto error; + } if (jn) gfc_constructor_insert_expr (&result->value.constructor, e, &x->where, @@ -4930,11 +4934,6 @@ gfc_simplify_repeat (gfc_expr *e, gfc_expr *n) else ncop = 0; - len = e->value.character.length; - nlen = ncop * len; - - result = gfc_get_constant_expr (BT_CHARACTER, e->ts.kind, &e->where); - if (ncop == 0) return gfc_get_character_expr (e->ts.kind, &e->where, NULL, 0); diff --git a/gcc/fortran/symbol.c b/gcc/fortran/symbol.c index 1f4a7352686..d68208d3010 100644 --- a/gcc/fortran/symbol.c +++ b/gcc/fortran/symbol.c @@ -4846,7 +4846,9 @@ gfc_get_typebound_proc (gfc_typebound_proc *tb0) gfc_symbol* gfc_get_derived_super_type (gfc_symbol* derived) { - if (derived && derived->attr.generic) + gcc_assert (derived); + + if (derived->attr.generic) derived = gfc_find_dt_in_generic (derived); if (!derived->attr.extension) @@ -4968,7 +4970,7 @@ gfc_find_dt_in_generic (gfc_symbol *sym) return sym; if (sym->attr.generic) - for (intr = (sym ? sym->generic : NULL); intr; intr = intr->next) + for (intr = sym->generic; intr; intr = intr->next) if (intr->sym->attr.flavor == FL_DERIVED) break; return intr ? intr->sym : NULL; diff --git a/gcc/fortran/target-memory.c b/gcc/fortran/target-memory.c index 637811e0965..bedc668d52f 100644 --- a/gcc/fortran/target-memory.c +++ b/gcc/fortran/target-memory.c @@ -140,7 +140,7 @@ gfc_target_expr_size (gfc_expr *e) return the number of bytes of the buffer that have been used. */ -static int +static unsigned HOST_WIDE_INT encode_array (gfc_expr *expr, unsigned char *buffer, size_t buffer_size) { mpz_t array_size; @@ -217,13 +217,14 @@ gfc_encode_character (int kind, int length, const gfc_char_t *string, } -static int +static unsigned HOST_WIDE_INT encode_derived (gfc_expr *source, unsigned char *buffer, size_t buffer_size) { gfc_constructor *c; gfc_component *cmp; int ptr; tree type; + HOST_WIDE_INT size; type = gfc_typenode_for_spec (&source->ts); @@ -239,19 +240,24 @@ encode_derived (gfc_expr *source, unsigned char *buffer, size_t buffer_size) + TREE_INT_CST_LOW(DECL_FIELD_BIT_OFFSET(cmp->backend_decl))/8; if (c->expr->expr_type == EXPR_NULL) - memset (&buffer[ptr], 0, - int_size_in_bytes (TREE_TYPE (cmp->backend_decl))); + { + size = int_size_in_bytes (TREE_TYPE (cmp->backend_decl)); + gcc_assert (size >= 0); + memset (&buffer[ptr], 0, size); + } else gfc_target_encode_expr (c->expr, &buffer[ptr], buffer_size - ptr); } - return int_size_in_bytes (type); + size = int_size_in_bytes (type); + gcc_assert (size >= 0); + return size; } /* Write a constant expression in binary form to a buffer. */ -int +unsigned HOST_WIDE_INT gfc_target_encode_expr (gfc_expr *source, unsigned char *buffer, size_t buffer_size) { @@ -567,6 +573,7 @@ gfc_target_interpret_expr (unsigned char *buffer, size_t buffer_size, case BT_DERIVED: result->representation.length = gfc_interpret_derived (buffer, buffer_size, result); + gcc_assert (result->representation.length >= 0); break; default: @@ -678,7 +685,7 @@ gfc_merge_initializers (gfc_typespec ts, gfc_expr *e, unsigned char *data, { size_t elt_size = gfc_target_expr_size (c->expr); - if (c->offset) + if (mpz_cmp_si (c->offset, 0) != 0) len = elt_size * (size_t)mpz_get_si (c->offset); len = len + gfc_merge_initializers (ts, c->expr, &data[len], diff --git a/gcc/fortran/target-memory.h b/gcc/fortran/target-memory.h index 6ebffe86521..cba2ea2d348 100644 --- a/gcc/fortran/target-memory.h +++ b/gcc/fortran/target-memory.h @@ -31,7 +31,8 @@ size_t gfc_target_expr_size (gfc_expr *); /* Write a constant expression in binary form to a target buffer. */ int gfc_encode_character (int, int, const gfc_char_t *, unsigned char *, size_t); -int gfc_target_encode_expr (gfc_expr *, unsigned char *, size_t); +unsigned HOST_WIDE_INT gfc_target_encode_expr (gfc_expr *, unsigned char *, + size_t); /* Read a target buffer into a constant expression. */