diff options
author | Tobias Burnus <burnus@gcc.gnu.org> | 2013-03-27 11:45:58 +0100 |
---|---|---|
committer | Tobias Burnus <burnus@gcc.gnu.org> | 2013-03-27 11:45:58 +0100 |
commit | 1a8c1e35b38094868dacad28eed2373233088dd2 (patch) | |
tree | 250e755fad9572f8dcf4d3ab8eb89f9394a11c3d /gcc/fortran/simplify.c | |
parent | 7d24f650fa1886c29e2431c969e5b7e6f8a50836 (diff) | |
download | gcc-1a8c1e35b38094868dacad28eed2373233088dd2.zip gcc-1a8c1e35b38094868dacad28eed2373233088dd2.tar.gz gcc-1a8c1e35b38094868dacad28eed2373233088dd2.tar.bz2 |
re PR fortran/56650 (Odd error messages with C_SIZEOF for valid code)
2013-03-27 Tobias Burnus <burnus@net-b.de>
PR fortran/56650
PR fortran/36437
* check.c (gfc_check_sizeof, gfc_check_c_sizeof,
gfc_check_storage_size): Update checks.
* intrinsic.texi (SIZEOF): Correct class.
* intrinsic.h (gfc_simplify_sizeof,
gfc_simplify_storage_size): New prototypes.
* intrinsic.c (add_functions): Use them.
* simplify.c (gfc_simplify_sizeof,
gfc_simplify_storage_size): New functions.
2013-03-27 Tobias Burnus <burnus@net-b.de>
PR fortran/56650
PR fortran/36437
* gfortran.dg/sizeof_2.f90: New.
* gfortran.dg/sizeof_3.f90: New.
* gfortran.dg/sizeof_proc.f90: Update dg-error.
From-SVN: r197159
Diffstat (limited to 'gcc/fortran/simplify.c')
-rw-r--r-- | gcc/fortran/simplify.c | 79 |
1 files changed, 78 insertions, 1 deletions
diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c index dc5dad2..e24cfcf 100644 --- a/gcc/fortran/simplify.c +++ b/gcc/fortran/simplify.c @@ -27,7 +27,8 @@ along with GCC; see the file COPYING3. If not see #include "intrinsic.h" #include "target-memory.h" #include "constructor.h" -#include "version.h" /* For version_string. */ +#include "tm.h" /* For BITS_PER_UNIT. */ +#include "version.h" /* For version_string. */ gfc_expr gfc_bad_expr; @@ -5649,6 +5650,82 @@ gfc_simplify_size (gfc_expr *array, gfc_expr *dim, gfc_expr *kind) } +/* SIZEOF and C_SIZEOF return the size in bytes of an array element + multiplied by the array size. */ + +gfc_expr * +gfc_simplify_sizeof (gfc_expr *x) +{ + gfc_expr *result = NULL; + mpz_t array_size; + + if (x->ts.type == BT_CLASS || x->ts.deferred) + return NULL; + + if (x->ts.type == BT_CHARACTER + && (!x->ts.u.cl || !x->ts.u.cl->length + || x->ts.u.cl->length->expr_type != EXPR_CONSTANT)) + return NULL; + + if (x->rank && x->expr_type != EXPR_ARRAY + && gfc_array_size (x, &array_size) == FAILURE) + return NULL; + + result = gfc_get_constant_expr (BT_INTEGER, gfc_index_integer_kind, + &x->where); + mpz_set_si (result->value.integer, gfc_target_expr_size (x)); + + /* gfc_target_expr_size already takes the array size for array constructors + into account. */ + if (x->rank && x->expr_type != EXPR_ARRAY) + { + mpz_mul (result->value.integer, result->value.integer, array_size); + mpz_clear (array_size); + } + + return result; +} + + +/* STORAGE_SIZE returns the size in bits of a single array element. */ + +gfc_expr * +gfc_simplify_storage_size (gfc_expr *x, + gfc_expr *kind) +{ + gfc_expr *result = NULL; + int k; + size_t elt_size; + + if (x->ts.type == BT_CLASS || x->ts.deferred) + return NULL; + + if (x->ts.type == BT_CHARACTER + && (!x->ts.u.cl || !x->ts.u.cl->length + || x->ts.u.cl->length->expr_type != EXPR_CONSTANT)) + return NULL; + + k = get_kind (BT_INTEGER, kind, "STORAGE_SIZE", gfc_default_integer_kind); + if (k == -1) + return &gfc_bad_expr; + + if (x->expr_type == EXPR_ARRAY) + { + gfc_constructor *c = gfc_constructor_first (x->value.constructor); + elt_size = gfc_target_expr_size (c->expr); + } + else + elt_size = gfc_target_expr_size (x); + + result = gfc_get_constant_expr (BT_INTEGER, gfc_index_integer_kind, + &x->where); + mpz_set_si (result->value.integer, elt_size); + + mpz_mul_ui (result->value.integer, result->value.integer, BITS_PER_UNIT); + return result; +} + + gfc_expr * gfc_simplify_sign (gfc_expr *x, gfc_expr *y) { |