]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/fortran/trans-const.c
Update copyright years.
[thirdparty/gcc.git] / gcc / fortran / trans-const.c
CommitLineData
4ee9c684 1/* Translation of constants
fbd26352 2 Copyright (C) 2002-2019 Free Software Foundation, Inc.
4ee9c684 3 Contributed by Paul Brook
4
c84b470d 5This file is part of GCC.
4ee9c684 6
c84b470d 7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
bdabe786 9Software Foundation; either version 3, or (at your option) any later
c84b470d 10version.
4ee9c684 11
c84b470d 12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
4ee9c684 16
17You should have received a copy of the GNU General Public License
bdabe786 18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
4ee9c684 20
21/* trans-const.c -- convert constant values */
22
23#include "config.h"
24#include "system.h"
25#include "coretypes.h"
4cba6f60 26#include "tree.h"
dc8078a3 27#include "gfortran.h"
4cba6f60 28#include "trans.h"
b20a8bb4 29#include "fold-const.h"
9ed99284 30#include "stor-layout.h"
dae0b5cb 31#include "realmpfr.h"
4ee9c684 32#include "trans-const.h"
33#include "trans-types.h"
b44437b9 34#include "target-memory.h"
4ee9c684 35
4ee9c684 36tree gfc_rank_cst[GFC_MAX_DIMENSIONS + 1];
37
38/* Build a constant with given type from an int_cst. */
f888a3fb 39
4ee9c684 40tree
41gfc_build_const (tree type, tree intval)
42{
43 tree val;
44 tree zero;
45
46 switch (TREE_CODE (type))
47 {
48 case INTEGER_TYPE:
49 val = convert (type, intval);
50 break;
51
52 case REAL_TYPE:
53 val = build_real_from_int_cst (type, intval);
54 break;
55
56 case COMPLEX_TYPE:
57 val = build_real_from_int_cst (TREE_TYPE (type), intval);
58 zero = build_real_from_int_cst (TREE_TYPE (type), integer_zero_node);
59 val = build_complex (type, val, zero);
60 break;
61
62 default:
22d678e8 63 gcc_unreachable ();
4ee9c684 64 }
65 return val;
66}
67
b44437b9 68/* Build a string constant with C char type. */
69
4ee9c684 70tree
bdfec5bf 71gfc_build_string_const (size_t length, const char *s)
4ee9c684 72{
73 tree str;
74 tree len;
75
76 str = build_string (length, s);
35bf1214 77 len = size_int (length);
4ee9c684 78 TREE_TYPE (str) =
79 build_array_type (gfc_character1_type_node,
9ad09405 80 build_range_type (gfc_charlen_type_node,
35bf1214 81 size_one_node, len));
5f4a118e 82 TYPE_STRING_FLAG (TREE_TYPE (str)) = 1;
4ee9c684 83 return str;
84}
85
b44437b9 86
87/* Build a string constant with a type given by its kind; take care of
88 non-default character kinds. */
89
90tree
bdfec5bf 91gfc_build_wide_string_const (int kind, size_t length, const gfc_char_t *string)
b44437b9 92{
93 int i;
94 tree str, len;
95 size_t size;
96 char *s;
97
98 i = gfc_validate_kind (BT_CHARACTER, kind, false);
99 size = length * gfc_character_kinds[i].bit_size / 8;
100
48d8ad5a 101 s = XCNEWVAR (char, size);
b44437b9 102 gfc_encode_character (kind, length, string, (unsigned char *) s, size);
103
104 str = build_string (size, s);
434f0922 105 free (s);
b44437b9 106
35bf1214 107 len = size_int (length);
b44437b9 108 TREE_TYPE (str) =
109 build_array_type (gfc_get_char_type (kind),
110 build_range_type (gfc_charlen_type_node,
35bf1214 111 size_one_node, len));
5f4a118e 112 TYPE_STRING_FLAG (TREE_TYPE (str)) = 1;
b44437b9 113 return str;
114}
115
116
41481754 117/* Build a Fortran character constant from a zero-terminated string.
8fb9e3cd 118 There a two version of this function, one that translates the string
119 and one that doesn't. */
4f576d6a 120tree
8fb9e3cd 121gfc_build_cstring_const (const char *string)
4f576d6a 122{
8fb9e3cd 123 return gfc_build_string_const (strlen (string) + 1, string);
4f576d6a 124}
125
8fb9e3cd 126tree
127gfc_build_localized_cstring_const (const char *msgid)
128{
129 const char *localized = _(msgid);
130 return gfc_build_string_const (strlen (localized) + 1, localized);
131}
132
133
4ee9c684 134/* Return a string constant with the given length. Used for static
c3f718e4 135 initializers. The constant will be padded or truncated to match
39fd2abe 136 length. */
137
4ee9c684 138tree
139gfc_conv_string_init (tree length, gfc_expr * expr)
140{
c32f863c 141 gfc_char_t *s;
4ee9c684 142 HOST_WIDE_INT len;
7ffa1621 143 gfc_charlen_t slen;
4ee9c684 144 tree str;
b44437b9 145 bool free_s = false;
4ee9c684 146
22d678e8 147 gcc_assert (expr->expr_type == EXPR_CONSTANT);
b44437b9 148 gcc_assert (expr->ts.type == BT_CHARACTER);
e1d65c9f 149 gcc_assert (tree_fits_uhwi_p (length));
4ee9c684 150
f9ae6f95 151 len = TREE_INT_CST_LOW (length);
4ee9c684 152 slen = expr->value.character.length;
39fd2abe 153
154 if (len > slen)
4ee9c684 155 {
c32f863c 156 s = gfc_get_wide_string (len);
157 memcpy (s, expr->value.character.string, slen * sizeof (gfc_char_t));
158 gfc_wide_memset (&s[slen], ' ', len - slen);
b44437b9 159 free_s = true;
4ee9c684 160 }
161 else
b44437b9 162 s = expr->value.character.string;
c32f863c 163
b44437b9 164 str = gfc_build_wide_string_const (expr->ts.kind, len, s);
165
166 if (free_s)
434f0922 167 free (s);
4ee9c684 168
169 return str;
170}
171
172
173/* Create a tree node for the string length if it is constant. */
174
175void
176gfc_conv_const_charlen (gfc_charlen * cl)
177{
180a5dc0 178 if (!cl || cl->backend_decl)
4ee9c684 179 return;
180
181 if (cl->length && cl->length->expr_type == EXPR_CONSTANT)
182 {
183 cl->backend_decl = gfc_conv_mpz_to_tree (cl->length->value.integer,
184 cl->length->ts.kind);
41dc7285 185 cl->backend_decl = fold_convert (gfc_charlen_type_node,
186 cl->backend_decl);
4ee9c684 187 }
188}
189
190void
191gfc_init_constants (void)
192{
193 int n;
194
195 for (n = 0; n <= GFC_MAX_DIMENSIONS; n++)
7016c612 196 gfc_rank_cst[n] = build_int_cst (gfc_array_index_type, n);
4ee9c684 197}
198
4ee9c684 199/* Converts a GMP integer into a backend tree node. */
6b755e72 200
4ee9c684 201tree
202gfc_conv_mpz_to_tree (mpz_t i, int kind)
203{
796b6678 204 wide_int val = wi::from_mpz (gfc_get_int_type (kind), i, true);
e913b5cd 205 return wide_int_to_tree (gfc_get_int_type (kind), val);
6b755e72 206}
4ee9c684 207
9f4d9f83 208
209/* Convert a GMP integer into a tree node of type given by the type
210 argument. */
211
212tree
213gfc_conv_mpz_to_tree_type (mpz_t i, const tree type)
214{
215 const wide_int val = wi::from_mpz (type, i, true);
216 return wide_int_to_tree (type, val);
217}
218
219
6b755e72 220/* Converts a backend tree into a GMP integer. */
4ee9c684 221
6b755e72 222void
223gfc_conv_tree_to_mpz (mpz_t i, tree source)
224{
e3d0f65c 225 wi::to_mpz (wi::to_wide (source), i, TYPE_SIGN (TREE_TYPE (source)));
4ee9c684 226}
227
6b755e72 228/* Converts a real constant into backend form. */
f888a3fb 229
4ee9c684 230tree
2b6bc4f2 231gfc_conv_mpfr_to_tree (mpfr_t f, int kind, int is_snan)
4ee9c684 232{
4ee9c684 233 tree type;
4ee9c684 234 int n;
09638e2c 235 REAL_VALUE_TYPE real;
4ee9c684 236
c60e6567 237 n = gfc_validate_kind (BT_REAL, kind, false);
c60e6567 238 gcc_assert (gfc_real_kinds[n].radix == 2);
239
09638e2c 240 type = gfc_get_real_type (kind);
2b6bc4f2 241 if (mpfr_nan_p (f) && is_snan)
242 real_from_string (&real, "SNaN");
243 else
244 real_from_mpfr (&real, f, type, GFC_RND_MODE);
245
6b755e72 246 return build_real (type, real);
247}
09638e2c 248
729e6db2 249/* Returns a real constant that is +Infinity if the target
250 supports infinities for this floating-point mode, and
251 +HUGE_VAL otherwise (the largest representable number). */
252
253tree
254gfc_build_inf_or_huge (tree type, int kind)
255{
256 if (HONOR_INFINITIES (TYPE_MODE (type)))
257 {
258 REAL_VALUE_TYPE real;
259 real_inf (&real);
260 return build_real (type, real);
261 }
262 else
263 {
264 int k = gfc_validate_kind (BT_REAL, kind, false);
265 return gfc_conv_mpfr_to_tree (gfc_real_kinds[k].huge, kind, 0);
266 }
267}
268
1d8a0522 269/* Returns a floating-point NaN of a given type. */
270
271tree
272gfc_build_nan (tree type, const char *str)
273{
274 REAL_VALUE_TYPE real;
275 real_nan (&real, str, 1, TYPE_MODE (type));
276 return build_real (type, real);
277}
278
6b755e72 279/* Converts a backend tree into a real constant. */
4ee9c684 280
6b755e72 281void
282gfc_conv_tree_to_mpfr (mpfr_ptr f, tree source)
283{
284 mpfr_from_real (f, TREE_REAL_CST_PTR (source), GFC_RND_MODE);
4ee9c684 285}
286
4ee9c684 287/* Translate any literal constant to a tree. Constants never have
288 pre or post chains. Character literal constants are special
289 special because they have a value and a length, so they cannot be
290 returned as a single tree. It is up to the caller to set the
291 length somewhere if necessary.
292
293 Returns the translated constant, or aborts if it gets a type it
294 can't handle. */
295
296tree
297gfc_conv_constant_to_tree (gfc_expr * expr)
298{
c32f863c 299 tree res;
c32f863c 300
22d678e8 301 gcc_assert (expr->expr_type == EXPR_CONSTANT);
4ee9c684 302
667787ce 303 /* If it is has a prescribed memory representation, we build a string
304 constant and VIEW_CONVERT to its type. */
c3f718e4 305
4ee9c684 306 switch (expr->ts.type)
307 {
308 case BT_INTEGER:
667787ce 309 if (expr->representation.string)
fd779e1d 310 return fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
311 gfc_get_int_type (expr->ts.kind),
312 gfc_build_string_const (expr->representation.length,
313 expr->representation.string));
169f9d09 314 else
315 return gfc_conv_mpz_to_tree (expr->value.integer, expr->ts.kind);
4ee9c684 316
317 case BT_REAL:
667787ce 318 if (expr->representation.string)
fd779e1d 319 return fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
320 gfc_get_real_type (expr->ts.kind),
321 gfc_build_string_const (expr->representation.length,
322 expr->representation.string));
169f9d09 323 else
2b6bc4f2 324 return gfc_conv_mpfr_to_tree (expr->value.real, expr->ts.kind, expr->is_snan);
4ee9c684 325
326 case BT_LOGICAL:
667787ce 327 if (expr->representation.string)
95b7221a 328 {
fd779e1d 329 tree tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
330 gfc_get_int_type (expr->ts.kind),
331 gfc_build_string_const (expr->representation.length,
332 expr->representation.string));
95b7221a 333 if (!integer_zerop (tmp) && !integer_onep (tmp))
6f521718 334 gfc_warning (0, "Assigning value other than 0 or 1 to LOGICAL"
95b7221a 335 " has undefined result at %L", &expr->where);
336 return fold_convert (gfc_get_logical_type (expr->ts.kind), tmp);
337 }
169f9d09 338 else
339 return build_int_cst (gfc_get_logical_type (expr->ts.kind),
95b7221a 340 expr->value.logical);
4ee9c684 341
342 case BT_COMPLEX:
667787ce 343 if (expr->representation.string)
fd779e1d 344 return fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
345 gfc_get_complex_type (expr->ts.kind),
346 gfc_build_string_const (expr->representation.length,
347 expr->representation.string));
169f9d09 348 else
349 {
f8e9f06c 350 tree real = gfc_conv_mpfr_to_tree (mpc_realref (expr->value.complex),
2b6bc4f2 351 expr->ts.kind, expr->is_snan);
f8e9f06c 352 tree imag = gfc_conv_mpfr_to_tree (mpc_imagref (expr->value.complex),
2b6bc4f2 353 expr->ts.kind, expr->is_snan);
4ee9c684 354
169f9d09 355 return build_complex (gfc_typenode_for_spec (&expr->ts),
356 real, imag);
357 }
4ee9c684 358
359 case BT_CHARACTER:
b44437b9 360 res = gfc_build_wide_string_const (expr->ts.kind,
361 expr->value.character.length,
362 expr->value.character.string);
c32f863c 363 return res;
4ee9c684 364
667787ce 365 case BT_HOLLERITH:
366 return gfc_build_string_const (expr->representation.length,
367 expr->representation.string);
368
4ee9c684 369 default:
b9d79b9e 370 gcc_unreachable ();
4ee9c684 371 }
372}
373
374
f888a3fb 375/* Like gfc_conv_constant_to_tree, but for a simplified expression.
4ee9c684 376 We can handle character literal constants here as well. */
377
378void
379gfc_conv_constant (gfc_se * se, gfc_expr * expr)
380{
45f39826 381 gfc_ss *ss;
382
c5d33754 383 /* We may be receiving an expression for C_NULL_PTR or C_NULL_FUNPTR. If
9d6ee0cd 384 so, the expr_type will not yet be an EXPR_CONSTANT. We need to make
c5d33754 385 it so here. */
eeebe20b 386 if (expr->ts.type == BT_DERIVED && expr->ts.u.derived
387 && expr->ts.u.derived->attr.is_iso_c)
c5d33754 388 {
c3f718e4 389 if (expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_PTR
390 || expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_FUNPTR)
391 {
392 /* Create a new EXPR_CONSTANT expression for our local uses. */
393 expr = gfc_get_int_expr (gfc_default_integer_kind, NULL, 0);
394 }
c5d33754 395 }
396
9d6ee0cd 397 if (expr->expr_type != EXPR_CONSTANT)
398 {
126387b5 399 gfc_expr *e = gfc_get_int_expr (gfc_default_integer_kind, NULL, 0);
9d6ee0cd 400 gfc_error ("non-constant initialization expression at %L", &expr->where);
126387b5 401 se->expr = gfc_conv_constant_to_tree (e);
9d6ee0cd 402 return;
403 }
4ee9c684 404
45f39826 405 ss = se->ss;
406 if (ss != NULL)
4ee9c684 407 {
bfa43780 408 gfc_ss_info *ss_info;
409
410 ss_info = ss->info;
45f39826 411 gcc_assert (ss != gfc_ss_terminator);
bfa43780 412 gcc_assert (ss_info->type == GFC_SS_SCALAR);
413 gcc_assert (ss_info->expr == expr);
4ee9c684 414
aaaf75f7 415 se->expr = ss_info->data.scalar.value;
3d653dea 416 se->string_length = ss_info->string_length;
4ee9c684 417 gfc_advance_se_ss_chain (se);
418 return;
419 }
420
421 /* Translate the constant and put it in the simplifier structure. */
422 se->expr = gfc_conv_constant_to_tree (expr);
423
f888a3fb 424 /* If this is a CHARACTER string, set its length in the simplifier
4ee9c684 425 structure, too. */
426 if (expr->ts.type == BT_CHARACTER)
427 se->string_length = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se->expr)));
428}