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