aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorTobias Burnus <burnus@net-b.de>2012-09-15 17:42:01 +0200
committerTobias Burnus <burnus@gcc.gnu.org>2012-09-15 17:42:01 +0200
commitfd2805e11b7018a148a4f87201b4d85344b5aad4 (patch)
tree05e97776b1fe54ef1d015ca3c6f07b279078ff83 /gcc
parent8385420c4f45090a3393557783d8c7c73ef9a9b7 (diff)
downloadgcc-fd2805e11b7018a148a4f87201b4d85344b5aad4.zip
gcc-fd2805e11b7018a148a4f87201b4d85344b5aad4.tar.gz
gcc-fd2805e11b7018a148a4f87201b4d85344b5aad4.tar.bz2
match.c (lock_unlock_statement, [...]): Fix potential double freeing.
2012-09-15 Tobias Burnus <burnus@net-b.de> * 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. From-SVN: r191343
Diffstat (limited to 'gcc')
-rw-r--r--gcc/fortran/ChangeLog15
-rw-r--r--gcc/fortran/match.c20
-rw-r--r--gcc/fortran/simplify.c11
-rw-r--r--gcc/fortran/symbol.c6
-rw-r--r--gcc/fortran/target-memory.c21
-rw-r--r--gcc/fortran/target-memory.h3
6 files changed, 52 insertions, 24 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 21e7dbe..a1a2cd2 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,18 @@
+2012-09-15 Tobias Burnus <burnus@net-b.de>
+
+ * 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 <burnus@net-b.de>
PR fortran/54556
diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c
index cf85d52..d46a495 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 07aeee8..5aa2704 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 1f4a735..d68208d 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 637811e..bedc668 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 6ebffe8..cba2ea2 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. */