1760c2415Smrg /* Translation of constants
2*0bfacb9bSmrg Copyright (C) 2002-2020 Free Software Foundation, Inc.
3760c2415Smrg Contributed by Paul Brook
4760c2415Smrg
5760c2415Smrg This file is part of GCC.
6760c2415Smrg
7760c2415Smrg GCC is free software; you can redistribute it and/or modify it under
8760c2415Smrg the terms of the GNU General Public License as published by the Free
9760c2415Smrg Software Foundation; either version 3, or (at your option) any later
10760c2415Smrg version.
11760c2415Smrg
12760c2415Smrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13760c2415Smrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
14760c2415Smrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15760c2415Smrg for more details.
16760c2415Smrg
17760c2415Smrg You should have received a copy of the GNU General Public License
18760c2415Smrg along with GCC; see the file COPYING3. If not see
19760c2415Smrg <http://www.gnu.org/licenses/>. */
20760c2415Smrg
21760c2415Smrg /* trans-const.c -- convert constant values */
22760c2415Smrg
23760c2415Smrg #include "config.h"
24760c2415Smrg #include "system.h"
25760c2415Smrg #include "coretypes.h"
26760c2415Smrg #include "tree.h"
27760c2415Smrg #include "gfortran.h"
28*0bfacb9bSmrg #include "options.h"
29760c2415Smrg #include "trans.h"
30760c2415Smrg #include "fold-const.h"
31760c2415Smrg #include "stor-layout.h"
32760c2415Smrg #include "realmpfr.h"
33760c2415Smrg #include "trans-const.h"
34760c2415Smrg #include "trans-types.h"
35760c2415Smrg #include "target-memory.h"
36760c2415Smrg
37760c2415Smrg tree gfc_rank_cst[GFC_MAX_DIMENSIONS + 1];
38760c2415Smrg
39760c2415Smrg /* Build a constant with given type from an int_cst. */
40760c2415Smrg
41760c2415Smrg tree
gfc_build_const(tree type,tree intval)42760c2415Smrg gfc_build_const (tree type, tree intval)
43760c2415Smrg {
44760c2415Smrg tree val;
45760c2415Smrg tree zero;
46760c2415Smrg
47760c2415Smrg switch (TREE_CODE (type))
48760c2415Smrg {
49760c2415Smrg case INTEGER_TYPE:
50760c2415Smrg val = convert (type, intval);
51760c2415Smrg break;
52760c2415Smrg
53760c2415Smrg case REAL_TYPE:
54760c2415Smrg val = build_real_from_int_cst (type, intval);
55760c2415Smrg break;
56760c2415Smrg
57760c2415Smrg case COMPLEX_TYPE:
58760c2415Smrg val = build_real_from_int_cst (TREE_TYPE (type), intval);
59760c2415Smrg zero = build_real_from_int_cst (TREE_TYPE (type), integer_zero_node);
60760c2415Smrg val = build_complex (type, val, zero);
61760c2415Smrg break;
62760c2415Smrg
63760c2415Smrg default:
64760c2415Smrg gcc_unreachable ();
65760c2415Smrg }
66760c2415Smrg return val;
67760c2415Smrg }
68760c2415Smrg
69760c2415Smrg /* Build a string constant with C char type. */
70760c2415Smrg
71760c2415Smrg tree
gfc_build_string_const(size_t length,const char * s)72760c2415Smrg gfc_build_string_const (size_t length, const char *s)
73760c2415Smrg {
74760c2415Smrg tree str;
75760c2415Smrg tree len;
76760c2415Smrg
77760c2415Smrg str = build_string (length, s);
78760c2415Smrg len = size_int (length);
79760c2415Smrg TREE_TYPE (str) =
80760c2415Smrg build_array_type (gfc_character1_type_node,
81760c2415Smrg build_range_type (gfc_charlen_type_node,
82760c2415Smrg size_one_node, len));
83760c2415Smrg TYPE_STRING_FLAG (TREE_TYPE (str)) = 1;
84760c2415Smrg return str;
85760c2415Smrg }
86760c2415Smrg
87760c2415Smrg
88760c2415Smrg /* Build a string constant with a type given by its kind; take care of
89760c2415Smrg non-default character kinds. */
90760c2415Smrg
91760c2415Smrg tree
gfc_build_wide_string_const(int kind,size_t length,const gfc_char_t * string)92760c2415Smrg gfc_build_wide_string_const (int kind, size_t length, const gfc_char_t *string)
93760c2415Smrg {
94760c2415Smrg int i;
95760c2415Smrg tree str, len;
96760c2415Smrg size_t size;
97760c2415Smrg char *s;
98760c2415Smrg
99760c2415Smrg i = gfc_validate_kind (BT_CHARACTER, kind, false);
100760c2415Smrg size = length * gfc_character_kinds[i].bit_size / 8;
101760c2415Smrg
102760c2415Smrg s = XCNEWVAR (char, size);
103760c2415Smrg gfc_encode_character (kind, length, string, (unsigned char *) s, size);
104760c2415Smrg
105760c2415Smrg str = build_string (size, s);
106760c2415Smrg free (s);
107760c2415Smrg
108760c2415Smrg len = size_int (length);
109760c2415Smrg TREE_TYPE (str) =
110760c2415Smrg build_array_type (gfc_get_char_type (kind),
111760c2415Smrg build_range_type (gfc_charlen_type_node,
112760c2415Smrg size_one_node, len));
113760c2415Smrg TYPE_STRING_FLAG (TREE_TYPE (str)) = 1;
114760c2415Smrg return str;
115760c2415Smrg }
116760c2415Smrg
117760c2415Smrg
118760c2415Smrg /* Build a Fortran character constant from a zero-terminated string.
119760c2415Smrg There a two version of this function, one that translates the string
120760c2415Smrg and one that doesn't. */
121760c2415Smrg tree
gfc_build_cstring_const(const char * string)122760c2415Smrg gfc_build_cstring_const (const char *string)
123760c2415Smrg {
124760c2415Smrg return gfc_build_string_const (strlen (string) + 1, string);
125760c2415Smrg }
126760c2415Smrg
127760c2415Smrg tree
gfc_build_localized_cstring_const(const char * msgid)128760c2415Smrg gfc_build_localized_cstring_const (const char *msgid)
129760c2415Smrg {
130760c2415Smrg const char *localized = _(msgid);
131760c2415Smrg return gfc_build_string_const (strlen (localized) + 1, localized);
132760c2415Smrg }
133760c2415Smrg
134760c2415Smrg
135760c2415Smrg /* Return a string constant with the given length. Used for static
136760c2415Smrg initializers. The constant will be padded or truncated to match
137760c2415Smrg length. */
138760c2415Smrg
139760c2415Smrg tree
gfc_conv_string_init(tree length,gfc_expr * expr)140760c2415Smrg gfc_conv_string_init (tree length, gfc_expr * expr)
141760c2415Smrg {
142760c2415Smrg gfc_char_t *s;
143760c2415Smrg HOST_WIDE_INT len;
144760c2415Smrg gfc_charlen_t slen;
145760c2415Smrg tree str;
146760c2415Smrg bool free_s = false;
147760c2415Smrg
148760c2415Smrg gcc_assert (expr->expr_type == EXPR_CONSTANT);
149760c2415Smrg gcc_assert (expr->ts.type == BT_CHARACTER);
150760c2415Smrg gcc_assert (tree_fits_uhwi_p (length));
151760c2415Smrg
152760c2415Smrg len = TREE_INT_CST_LOW (length);
153760c2415Smrg slen = expr->value.character.length;
154760c2415Smrg
155760c2415Smrg if (len > slen)
156760c2415Smrg {
157760c2415Smrg s = gfc_get_wide_string (len);
158760c2415Smrg memcpy (s, expr->value.character.string, slen * sizeof (gfc_char_t));
159760c2415Smrg gfc_wide_memset (&s[slen], ' ', len - slen);
160760c2415Smrg free_s = true;
161760c2415Smrg }
162760c2415Smrg else
163760c2415Smrg s = expr->value.character.string;
164760c2415Smrg
165760c2415Smrg str = gfc_build_wide_string_const (expr->ts.kind, len, s);
166760c2415Smrg
167760c2415Smrg if (free_s)
168760c2415Smrg free (s);
169760c2415Smrg
170760c2415Smrg return str;
171760c2415Smrg }
172760c2415Smrg
173760c2415Smrg
174760c2415Smrg /* Create a tree node for the string length if it is constant. */
175760c2415Smrg
176760c2415Smrg void
gfc_conv_const_charlen(gfc_charlen * cl)177760c2415Smrg gfc_conv_const_charlen (gfc_charlen * cl)
178760c2415Smrg {
179760c2415Smrg if (!cl || cl->backend_decl)
180760c2415Smrg return;
181760c2415Smrg
182760c2415Smrg if (cl->length && cl->length->expr_type == EXPR_CONSTANT)
183760c2415Smrg {
184760c2415Smrg cl->backend_decl = gfc_conv_mpz_to_tree (cl->length->value.integer,
185760c2415Smrg cl->length->ts.kind);
186760c2415Smrg cl->backend_decl = fold_convert (gfc_charlen_type_node,
187760c2415Smrg cl->backend_decl);
188760c2415Smrg }
189760c2415Smrg }
190760c2415Smrg
191760c2415Smrg void
gfc_init_constants(void)192760c2415Smrg gfc_init_constants (void)
193760c2415Smrg {
194760c2415Smrg int n;
195760c2415Smrg
196760c2415Smrg for (n = 0; n <= GFC_MAX_DIMENSIONS; n++)
197760c2415Smrg gfc_rank_cst[n] = build_int_cst (gfc_array_index_type, n);
198760c2415Smrg }
199760c2415Smrg
200760c2415Smrg /* Converts a GMP integer into a backend tree node. */
201760c2415Smrg
202760c2415Smrg tree
gfc_conv_mpz_to_tree(mpz_t i,int kind)203760c2415Smrg gfc_conv_mpz_to_tree (mpz_t i, int kind)
204760c2415Smrg {
205760c2415Smrg wide_int val = wi::from_mpz (gfc_get_int_type (kind), i, true);
206760c2415Smrg return wide_int_to_tree (gfc_get_int_type (kind), val);
207760c2415Smrg }
208760c2415Smrg
209760c2415Smrg
210760c2415Smrg /* Convert a GMP integer into a tree node of type given by the type
211760c2415Smrg argument. */
212760c2415Smrg
213760c2415Smrg tree
gfc_conv_mpz_to_tree_type(mpz_t i,const tree type)214760c2415Smrg gfc_conv_mpz_to_tree_type (mpz_t i, const tree type)
215760c2415Smrg {
216760c2415Smrg const wide_int val = wi::from_mpz (type, i, true);
217760c2415Smrg return wide_int_to_tree (type, val);
218760c2415Smrg }
219760c2415Smrg
220760c2415Smrg
221760c2415Smrg /* Converts a backend tree into a GMP integer. */
222760c2415Smrg
223760c2415Smrg void
gfc_conv_tree_to_mpz(mpz_t i,tree source)224760c2415Smrg gfc_conv_tree_to_mpz (mpz_t i, tree source)
225760c2415Smrg {
226760c2415Smrg wi::to_mpz (wi::to_wide (source), i, TYPE_SIGN (TREE_TYPE (source)));
227760c2415Smrg }
228760c2415Smrg
229760c2415Smrg /* Converts a real constant into backend form. */
230760c2415Smrg
231760c2415Smrg tree
gfc_conv_mpfr_to_tree(mpfr_t f,int kind,int is_snan)232760c2415Smrg gfc_conv_mpfr_to_tree (mpfr_t f, int kind, int is_snan)
233760c2415Smrg {
234760c2415Smrg tree type;
235760c2415Smrg int n;
236760c2415Smrg REAL_VALUE_TYPE real;
237760c2415Smrg
238760c2415Smrg n = gfc_validate_kind (BT_REAL, kind, false);
239760c2415Smrg gcc_assert (gfc_real_kinds[n].radix == 2);
240760c2415Smrg
241760c2415Smrg type = gfc_get_real_type (kind);
242760c2415Smrg if (mpfr_nan_p (f) && is_snan)
243760c2415Smrg real_from_string (&real, "SNaN");
244760c2415Smrg else
245760c2415Smrg real_from_mpfr (&real, f, type, GFC_RND_MODE);
246760c2415Smrg
247760c2415Smrg return build_real (type, real);
248760c2415Smrg }
249760c2415Smrg
250760c2415Smrg /* Returns a real constant that is +Infinity if the target
251760c2415Smrg supports infinities for this floating-point mode, and
252760c2415Smrg +HUGE_VAL otherwise (the largest representable number). */
253760c2415Smrg
254760c2415Smrg tree
gfc_build_inf_or_huge(tree type,int kind)255760c2415Smrg gfc_build_inf_or_huge (tree type, int kind)
256760c2415Smrg {
257760c2415Smrg if (HONOR_INFINITIES (TYPE_MODE (type)))
258760c2415Smrg {
259760c2415Smrg REAL_VALUE_TYPE real;
260760c2415Smrg real_inf (&real);
261760c2415Smrg return build_real (type, real);
262760c2415Smrg }
263760c2415Smrg else
264760c2415Smrg {
265760c2415Smrg int k = gfc_validate_kind (BT_REAL, kind, false);
266760c2415Smrg return gfc_conv_mpfr_to_tree (gfc_real_kinds[k].huge, kind, 0);
267760c2415Smrg }
268760c2415Smrg }
269760c2415Smrg
270760c2415Smrg /* Returns a floating-point NaN of a given type. */
271760c2415Smrg
272760c2415Smrg tree
gfc_build_nan(tree type,const char * str)273760c2415Smrg gfc_build_nan (tree type, const char *str)
274760c2415Smrg {
275760c2415Smrg REAL_VALUE_TYPE real;
276760c2415Smrg real_nan (&real, str, 1, TYPE_MODE (type));
277760c2415Smrg return build_real (type, real);
278760c2415Smrg }
279760c2415Smrg
280760c2415Smrg /* Converts a backend tree into a real constant. */
281760c2415Smrg
282760c2415Smrg void
gfc_conv_tree_to_mpfr(mpfr_ptr f,tree source)283760c2415Smrg gfc_conv_tree_to_mpfr (mpfr_ptr f, tree source)
284760c2415Smrg {
285760c2415Smrg mpfr_from_real (f, TREE_REAL_CST_PTR (source), GFC_RND_MODE);
286760c2415Smrg }
287760c2415Smrg
288760c2415Smrg /* Translate any literal constant to a tree. Constants never have
289760c2415Smrg pre or post chains. Character literal constants are special
290760c2415Smrg special because they have a value and a length, so they cannot be
291760c2415Smrg returned as a single tree. It is up to the caller to set the
292760c2415Smrg length somewhere if necessary.
293760c2415Smrg
294760c2415Smrg Returns the translated constant, or aborts if it gets a type it
295760c2415Smrg can't handle. */
296760c2415Smrg
297760c2415Smrg tree
gfc_conv_constant_to_tree(gfc_expr * expr)298760c2415Smrg gfc_conv_constant_to_tree (gfc_expr * expr)
299760c2415Smrg {
300760c2415Smrg tree res;
301760c2415Smrg
302760c2415Smrg gcc_assert (expr->expr_type == EXPR_CONSTANT);
303760c2415Smrg
304760c2415Smrg /* If it is has a prescribed memory representation, we build a string
305760c2415Smrg constant and VIEW_CONVERT to its type. */
306760c2415Smrg
307760c2415Smrg switch (expr->ts.type)
308760c2415Smrg {
309760c2415Smrg case BT_INTEGER:
310760c2415Smrg if (expr->representation.string)
311760c2415Smrg return fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
312760c2415Smrg gfc_get_int_type (expr->ts.kind),
313760c2415Smrg gfc_build_string_const (expr->representation.length,
314760c2415Smrg expr->representation.string));
315760c2415Smrg else
316760c2415Smrg return gfc_conv_mpz_to_tree (expr->value.integer, expr->ts.kind);
317760c2415Smrg
318760c2415Smrg case BT_REAL:
319760c2415Smrg if (expr->representation.string)
320760c2415Smrg return fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
321760c2415Smrg gfc_get_real_type (expr->ts.kind),
322760c2415Smrg gfc_build_string_const (expr->representation.length,
323760c2415Smrg expr->representation.string));
324760c2415Smrg else
325760c2415Smrg return gfc_conv_mpfr_to_tree (expr->value.real, expr->ts.kind, expr->is_snan);
326760c2415Smrg
327760c2415Smrg case BT_LOGICAL:
328760c2415Smrg if (expr->representation.string)
329760c2415Smrg {
330760c2415Smrg tree tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
331760c2415Smrg gfc_get_int_type (expr->ts.kind),
332760c2415Smrg gfc_build_string_const (expr->representation.length,
333760c2415Smrg expr->representation.string));
334760c2415Smrg if (!integer_zerop (tmp) && !integer_onep (tmp))
335*0bfacb9bSmrg gfc_warning (flag_dec_char_conversions ? OPT_Wsurprising : 0,
336*0bfacb9bSmrg "Assigning value other than 0 or 1 to LOGICAL has "
337*0bfacb9bSmrg "undefined result at %L", &expr->where);
338760c2415Smrg return fold_convert (gfc_get_logical_type (expr->ts.kind), tmp);
339760c2415Smrg }
340760c2415Smrg else
341760c2415Smrg return build_int_cst (gfc_get_logical_type (expr->ts.kind),
342760c2415Smrg expr->value.logical);
343760c2415Smrg
344760c2415Smrg case BT_COMPLEX:
345760c2415Smrg if (expr->representation.string)
346760c2415Smrg return fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
347760c2415Smrg gfc_get_complex_type (expr->ts.kind),
348760c2415Smrg gfc_build_string_const (expr->representation.length,
349760c2415Smrg expr->representation.string));
350760c2415Smrg else
351760c2415Smrg {
352760c2415Smrg tree real = gfc_conv_mpfr_to_tree (mpc_realref (expr->value.complex),
353760c2415Smrg expr->ts.kind, expr->is_snan);
354760c2415Smrg tree imag = gfc_conv_mpfr_to_tree (mpc_imagref (expr->value.complex),
355760c2415Smrg expr->ts.kind, expr->is_snan);
356760c2415Smrg
357760c2415Smrg return build_complex (gfc_typenode_for_spec (&expr->ts),
358760c2415Smrg real, imag);
359760c2415Smrg }
360760c2415Smrg
361760c2415Smrg case BT_CHARACTER:
362760c2415Smrg res = gfc_build_wide_string_const (expr->ts.kind,
363760c2415Smrg expr->value.character.length,
364760c2415Smrg expr->value.character.string);
365760c2415Smrg return res;
366760c2415Smrg
367760c2415Smrg case BT_HOLLERITH:
368760c2415Smrg return gfc_build_string_const (expr->representation.length,
369760c2415Smrg expr->representation.string);
370760c2415Smrg
371760c2415Smrg default:
372760c2415Smrg gcc_unreachable ();
373760c2415Smrg }
374760c2415Smrg }
375760c2415Smrg
376760c2415Smrg
377760c2415Smrg /* Like gfc_conv_constant_to_tree, but for a simplified expression.
378760c2415Smrg We can handle character literal constants here as well. */
379760c2415Smrg
380760c2415Smrg void
gfc_conv_constant(gfc_se * se,gfc_expr * expr)381760c2415Smrg gfc_conv_constant (gfc_se * se, gfc_expr * expr)
382760c2415Smrg {
383760c2415Smrg gfc_ss *ss;
384760c2415Smrg
385760c2415Smrg /* We may be receiving an expression for C_NULL_PTR or C_NULL_FUNPTR. If
386760c2415Smrg so, the expr_type will not yet be an EXPR_CONSTANT. We need to make
387760c2415Smrg it so here. */
388760c2415Smrg if (expr->ts.type == BT_DERIVED && expr->ts.u.derived
389760c2415Smrg && expr->ts.u.derived->attr.is_iso_c)
390760c2415Smrg {
391760c2415Smrg if (expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_PTR
392760c2415Smrg || expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_FUNPTR)
393760c2415Smrg {
394760c2415Smrg /* Create a new EXPR_CONSTANT expression for our local uses. */
395760c2415Smrg expr = gfc_get_int_expr (gfc_default_integer_kind, NULL, 0);
396760c2415Smrg }
397760c2415Smrg }
398760c2415Smrg
399760c2415Smrg if (expr->expr_type != EXPR_CONSTANT)
400760c2415Smrg {
401760c2415Smrg gfc_expr *e = gfc_get_int_expr (gfc_default_integer_kind, NULL, 0);
402760c2415Smrg gfc_error ("non-constant initialization expression at %L", &expr->where);
403760c2415Smrg se->expr = gfc_conv_constant_to_tree (e);
404760c2415Smrg return;
405760c2415Smrg }
406760c2415Smrg
407760c2415Smrg ss = se->ss;
408760c2415Smrg if (ss != NULL)
409760c2415Smrg {
410760c2415Smrg gfc_ss_info *ss_info;
411760c2415Smrg
412760c2415Smrg ss_info = ss->info;
413760c2415Smrg gcc_assert (ss != gfc_ss_terminator);
414760c2415Smrg gcc_assert (ss_info->type == GFC_SS_SCALAR);
415760c2415Smrg gcc_assert (ss_info->expr == expr);
416760c2415Smrg
417760c2415Smrg se->expr = ss_info->data.scalar.value;
418760c2415Smrg se->string_length = ss_info->string_length;
419760c2415Smrg gfc_advance_se_ss_chain (se);
420760c2415Smrg return;
421760c2415Smrg }
422760c2415Smrg
423760c2415Smrg /* Translate the constant and put it in the simplifier structure. */
424760c2415Smrg se->expr = gfc_conv_constant_to_tree (expr);
425760c2415Smrg
426760c2415Smrg /* If this is a CHARACTER string, set its length in the simplifier
427760c2415Smrg structure, too. */
428760c2415Smrg if (expr->ts.type == BT_CHARACTER)
429760c2415Smrg se->string_length = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se->expr)));
430760c2415Smrg }
431