]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/m2/gm2-gcc/m2convert.cc
Update copyright years.
[thirdparty/gcc.git] / gcc / m2 / gm2-gcc / m2convert.cc
CommitLineData
1eee94d3
GM
1/* m2convert.cc provides GCC tree conversion for the Modula-2 language.
2
a945c346 3Copyright (C) 2012-2024 Free Software Foundation, Inc.
1eee94d3
GM
4Contributed by Gaius Mulley <gaius@glam.ac.uk>.
5
6This file is part of GNU Modula-2.
7
8GNU Modula-2 is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 3, or (at your option)
11any later version.
12
13GNU Modula-2 is distributed in the hope that it will be useful, but
14WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with GNU Modula-2; see the file COPYING3. If not see
20<http://www.gnu.org/licenses/>. */
21
22#include "gcc-consolidation.h"
23
24#include "../gm2-lang.h"
25#include "../m2-tree.h"
26
27#define m2convert_c
28#include "m2assert.h"
29#include "m2block.h"
30#include "m2convert.h"
31#include "m2decl.h"
32#include "m2expr.h"
33#include "m2expr.h"
34#include "m2statement.h"
35#include "m2tree.h"
36#include "m2treelib.h"
37#include "m2type.h"
38
39static tree const_to_ISO_type (location_t location, tree expr, tree iso_type);
40static tree const_to_ISO_aggregate_type (location_t location, tree expr,
41 tree iso_type);
42
43/* These enumerators are possible types of unsafe conversions.
44 SAFE_CONVERSION The conversion is safe UNSAFE_OTHER Another type of
45 conversion with problems UNSAFE_SIGN Conversion between signed and
46 unsigned integers which are all warned about immediately, so this is
47 unused UNSAFE_REAL Conversions that reduce the precision of reals
48 including conversions from reals to integers. */
49enum conversion_safety
50{
51 SAFE_CONVERSION = 0,
52 UNSAFE_OTHER,
53 UNSAFE_SIGN,
54 UNSAFE_REAL
55};
56
57/* ConvertString - converts string, expr, into a string of type,
58 type. */
59
60tree
61m2convert_ConvertString (tree type, tree expr)
62{
63 const char *str = TREE_STRING_POINTER (expr);
64 int len = TREE_STRING_LENGTH (expr);
65 return m2decl_BuildStringConstantType (len, str, type);
66}
67
68
69/* (Taken from c-common.cc and trimmed for Modula-2)
70
71 Checks if expression EXPR of real/integer type cannot be converted to
72 the real/integer type TYPE. Function returns non-zero when:
73 EXPR is a constant which cannot be exactly converted to TYPE.
74 EXPR is not a constant and size of EXPR's type > than size of
75 TYPE, for EXPR type and TYPE being both integers or both real.
76 EXPR is not a constant of real type and TYPE is an integer.
77 EXPR is not a constant of integer type which cannot be exactly
78 converted to real type. Function allows conversions between types
79 of different signedness and can return SAFE_CONVERSION (zero) in
80 that case. Function can produce signedness warnings if
81 PRODUCE_WARNS is true. */
82
83enum conversion_safety
84unsafe_conversion_p (location_t loc, tree type, tree expr, bool produce_warns)
85{
86 enum conversion_safety give_warning = SAFE_CONVERSION; /* Is 0 or false. */
87 tree expr_type = TREE_TYPE (expr);
88
89 if (TREE_CODE (expr) == REAL_CST || TREE_CODE (expr) == INTEGER_CST)
90 {
91
92 /* Warn for real constant that is not an exact integer converted to
93 integer type. */
8621e06a 94 if (SCALAR_FLOAT_TYPE_P (expr_type)
1eee94d3
GM
95 && TREE_CODE (type) == INTEGER_TYPE)
96 {
97 if (!real_isinteger (TREE_REAL_CST_PTR (expr),
98 TYPE_MODE (expr_type)))
99 give_warning = UNSAFE_REAL;
100 }
101 /* Warn for an integer constant that does not fit into integer type. */
102 else if (TREE_CODE (expr_type) == INTEGER_TYPE
103 && TREE_CODE (type) == INTEGER_TYPE
104 && !int_fits_type_p (expr, type))
105 {
106 if (TYPE_UNSIGNED (type) && !TYPE_UNSIGNED (expr_type)
107 && tree_int_cst_sgn (expr) < 0)
108 {
109 if (produce_warns)
110 warning_at (loc, OPT_Wsign_conversion,
111 "negative integer"
112 " implicitly converted to unsigned type");
113 }
114 else if (!TYPE_UNSIGNED (type) && TYPE_UNSIGNED (expr_type))
115 {
116 if (produce_warns)
117 warning_at (loc, OPT_Wsign_conversion,
118 "conversion of unsigned"
119 " constant value to negative integer");
120 }
121 else
122 give_warning = UNSAFE_OTHER;
123 }
8621e06a 124 else if (SCALAR_FLOAT_TYPE_P (type))
1eee94d3
GM
125 {
126 /* Warn for an integer constant that does not fit into real type. */
127 if (TREE_CODE (expr_type) == INTEGER_TYPE)
128 {
129 REAL_VALUE_TYPE a = real_value_from_int_cst (0, expr);
130 if (!exact_real_truncate (TYPE_MODE (type), &a))
131 give_warning = UNSAFE_REAL;
132 }
133
134 /* Warn for a real constant that does not fit into a smaller real
135 type. */
8621e06a 136 else if (SCALAR_FLOAT_TYPE_P (expr_type)
1eee94d3
GM
137 && TYPE_PRECISION (type) < TYPE_PRECISION (expr_type))
138 {
139 REAL_VALUE_TYPE a = TREE_REAL_CST (expr);
140 if (!exact_real_truncate (TYPE_MODE (type), &a))
141 give_warning = UNSAFE_REAL;
142 }
143 }
144 }
145 else
146 {
147 /* Warn for real types converted to integer types. */
8621e06a 148 if (SCALAR_FLOAT_TYPE_P (expr_type)
1eee94d3
GM
149 && TREE_CODE (type) == INTEGER_TYPE)
150 give_warning = UNSAFE_REAL;
151
152 }
153
154 return give_warning;
155}
156
157/* (Taken from c-common.cc and trimmed for Modula-2)
158
159 Warns if the conversion of EXPR to TYPE may alter a value. This is
160 a helper function for warnings_for_convert_and_check. */
161
162static void
163conversion_warning (location_t loc, tree type, tree expr)
164{
165 tree expr_type = TREE_TYPE (expr);
166 enum conversion_safety conversion_kind;
167
168 if (!warn_conversion && !warn_sign_conversion && !warn_float_conversion)
169 return;
170
171 switch (TREE_CODE (expr))
172 {
173 case EQ_EXPR:
174 case NE_EXPR:
175 case LE_EXPR:
176 case GE_EXPR:
177 case LT_EXPR:
178 case GT_EXPR:
179 case TRUTH_ANDIF_EXPR:
180 case TRUTH_ORIF_EXPR:
181 case TRUTH_AND_EXPR:
182 case TRUTH_OR_EXPR:
183 case TRUTH_XOR_EXPR:
184 case TRUTH_NOT_EXPR:
185
186 /* Conversion from boolean to a signed:1 bit-field (which only can
187 hold the values 0 and -1) doesn't lose information - but it does
188 change the value. */
189 if (TYPE_PRECISION (type) == 1 && !TYPE_UNSIGNED (type))
190 warning_at (loc, OPT_Wconversion,
191 "conversion to %qT from boolean expression", type);
192 return;
193
194 case REAL_CST:
195 case INTEGER_CST:
196 conversion_kind = unsafe_conversion_p (loc, type, expr, true);
197 if (conversion_kind == UNSAFE_REAL)
198 warning_at (loc, OPT_Wfloat_conversion,
199 "conversion to %qT alters %qT constant value", type,
200 expr_type);
201 else if (conversion_kind)
202 warning_at (loc, OPT_Wconversion,
203 "conversion to %qT alters %qT constant value", type,
204 expr_type);
205 return;
206
207 case COND_EXPR:
208 {
209
210 /* In case of COND_EXPR, we do not care about the type of COND_EXPR,
211 only about the conversion of each operand. */
212 tree op1 = TREE_OPERAND (expr, 1);
213 tree op2 = TREE_OPERAND (expr, 2);
214
215 conversion_warning (loc, type, op1);
216 conversion_warning (loc, type, op2);
217 return;
218 }
219
220 default: /* 'expr' is not a constant. */
221 conversion_kind = unsafe_conversion_p (loc, type, expr, true);
222 if (conversion_kind == UNSAFE_REAL)
223 warning_at (loc, OPT_Wfloat_conversion,
224 "conversion to %qT from %qT may alter its value", type,
225 expr_type);
226 else if (conversion_kind)
227 warning_at (loc, OPT_Wconversion,
228 "conversion to %qT from %qT may alter its value", type,
229 expr_type);
230 }
231}
232
233/* (Taken from c-common.cc and trimmed for Modula-2)
234
235 Produce warnings after a conversion. RESULT is the result of
236 converting EXPR to TYPE. This is a helper function for
237 convert_and_check and cp_convert_and_check. */
238
239void
240warnings_for_convert_and_check (location_t loc, tree type, tree expr,
241 tree result)
242{
243 if (TREE_CODE (expr) == INTEGER_CST && (TREE_CODE (type) == INTEGER_TYPE
244 || TREE_CODE (type) == ENUMERAL_TYPE)
245 && !int_fits_type_p (expr, type))
246 {
247
248 /* Do not diagnose overflow in a constant expression merely because a
249 conversion overflowed. */
250 if (TREE_OVERFLOW (result))
251 TREE_OVERFLOW (result) = TREE_OVERFLOW (expr);
252
253 if (TYPE_UNSIGNED (type))
254 {
255
256 /* This detects cases like converting -129 or 256 to unsigned
257 char. */
258 if (!int_fits_type_p (expr, m2type_gm2_signed_type (type)))
259 warning_at (loc, OPT_Woverflow,
260 "large integer implicitly truncated to unsigned type");
261 else
262 conversion_warning (loc, type, expr);
263 }
264 else if (!int_fits_type_p (expr, m2type_gm2_unsigned_type (type)))
265 warning_at (loc, OPT_Woverflow,
266 "overflow in implicit constant conversion");
267 /* No warning for converting 0x80000000 to int. */
268 else if (pedantic && (TREE_CODE (TREE_TYPE (expr)) != INTEGER_TYPE
269 || TYPE_PRECISION (TREE_TYPE (expr))
270 != TYPE_PRECISION (type)))
271 warning_at (loc, OPT_Woverflow,
272 "overflow in implicit constant conversion");
273
274 else
275 conversion_warning (loc, type, expr);
276 }
277 else if ((TREE_CODE (result) == INTEGER_CST
278 || TREE_CODE (result) == FIXED_CST)
279 && TREE_OVERFLOW (result))
280 warning_at (loc, OPT_Woverflow,
281 "overflow in implicit constant conversion");
282 else
283 conversion_warning (loc, type, expr);
284}
285
286/* (Taken from c-common.cc and trimmed for Modula-2)
287
288 Convert EXPR to TYPE, warning about conversion problems with
289 constants. Invoke this function on every expression that is
290 converted implicitly, i.e. because of language rules and not
291 because of an explicit cast. */
292
293static tree
294convert_and_check (location_t loc, tree type, tree expr)
295{
296 tree result;
297 tree expr_for_warning;
298
299 /* Convert from a value with possible excess precision rather than
300 via the semantic type, but do not warn about values not fitting
301 exactly in the semantic type. */
302 if (TREE_CODE (expr) == EXCESS_PRECISION_EXPR)
303 {
304 tree orig_type = TREE_TYPE (expr);
305 expr = TREE_OPERAND (expr, 0);
306 expr_for_warning = convert (orig_type, expr);
307 if (orig_type == type)
308 return expr_for_warning;
309 }
310 else
311 expr_for_warning = expr;
312
313 if (TREE_TYPE (expr) == type)
314 return expr;
315
316 result = convert_loc (loc, type, expr);
317
318 if (!TREE_OVERFLOW_P (expr) && result != error_mark_node)
319 warnings_for_convert_and_check (loc, type, expr_for_warning, result);
320
321 return result;
322}
323
324
325static tree
326doOrdinal (tree value)
327{
328 if (TREE_CODE (value) == STRING_CST && (m2expr_StringLength (value) <= 1))
329 {
330 const char *p = TREE_STRING_POINTER (value);
331 int i = p[0];
332
333 return m2decl_BuildIntegerConstant (i);
334 }
335 return value;
336}
337
338static int
339same_size_types (location_t location, tree t1, tree t2)
340{
341 tree n1 = m2expr_GetSizeOf (location, t1);
342 tree n2 = m2expr_GetSizeOf (location, t2);
343
344 return m2expr_CompareTrees (n1, n2) == 0;
345}
346
347static int
348converting_ISO_generic (location_t location, tree type, tree value,
349 tree generic_type, tree *result)
350{
351 tree value_type = m2tree_skip_type_decl (TREE_TYPE (value));
352
353 if (value_type == type)
354 /* We let the caller deal with this. */
431c0669 355 return false;
1eee94d3
GM
356
357 if ((TREE_CODE (value) == INTEGER_CST) && (type == generic_type))
358 {
359 *result = const_to_ISO_type (location, value, generic_type);
431c0669 360 return true;
1eee94d3
GM
361 }
362
363 if (same_size_types (location, type, value_type))
364 {
365 if (value_type == generic_type)
366 {
367 tree pt = build_pointer_type (type);
368 tree a = build1 (ADDR_EXPR, pt, value);
369 tree t = build1 (INDIRECT_REF, type, a);
370 *result = build1 (NOP_EXPR, type, t);
431c0669 371 return true;
1eee94d3
GM
372 }
373 else if (type == generic_type)
374 {
375 tree pt = build_pointer_type (type);
376 tree a = build1 (ADDR_EXPR, pt, value);
377 tree t = build1 (INDIRECT_REF, type, a);
378 *result = build1 (NOP_EXPR, type, t);
431c0669 379 return true;
1eee94d3
GM
380 }
381 }
431c0669 382 return false;
1eee94d3
GM
383}
384
385/* convert_char_to_array - convert a single char, value, into an
386 type. The type will be array [..] of char. The array type
387 returned will have nuls appended to pad the single char to the
388 correct array length. */
389
390static tree
391convert_char_to_array (location_t location, tree type, tree value)
392{
393 tree i = m2decl_BuildIntegerConstant (0);
394 struct struct_constructor *c
395 = (struct struct_constructor *)m2type_BuildStartArrayConstructor (type);
396 tree n = m2type_GetArrayNoOfElements (location, type);
397 char nul[1];
398
399 nul[0] = (char)0;
400
401 /* Store the initial char. */
402 m2type_BuildArrayConstructorElement (c, value, i);
431c0669 403 i = m2expr_BuildAdd (location, i, m2decl_BuildIntegerConstant (1), false);
1eee94d3
GM
404
405 /* Now pad out the remaining elements with nul chars. */
406 while (m2expr_CompareTrees (i, n) < 0)
407 {
408 m2type_BuildArrayConstructorElement (
409 c, m2type_BuildCharConstant (location, &nul[0]), i);
410 i = m2expr_BuildAdd (location, i, m2decl_BuildIntegerConstant (1),
431c0669 411 false);
1eee94d3
GM
412 }
413 return m2type_BuildEndArrayConstructor (c);
414}
415
416/* convert_string_to_array - convert a STRING_CST into an array type.
417 array [..] of char. The array constant returned will have nuls
418 appended to pad the contents to the correct length. */
419
420static tree
421convert_string_to_array (location_t location, tree type, tree value)
422{
423 tree n = m2type_GetArrayNoOfElements (location, type);
424
425 return m2type_BuildArrayStringConstructor (location, type, value, n);
426}
427
428/* BuildConvert - build and return tree VAL (type, value).
429 checkOverflow determines whether we should suppress overflow
430 checking. */
431
432tree
433m2convert_BuildConvert (location_t location, tree type, tree value,
431c0669 434 bool checkOverflow)
1eee94d3
GM
435{
436 type = m2tree_skip_type_decl (type);
437 tree t;
438
439 value = fold (value);
440 STRIP_NOPS (value);
441 value = m2expr_FoldAndStrip (value);
442
443 if (TREE_CODE (value) == STRING_CST && (m2expr_StringLength (value) <= 1)
444 && (m2tree_IsOrdinal (type)))
445 value = doOrdinal (value);
446 else if (TREE_CODE (value) == FUNCTION_DECL && TREE_TYPE (value) != type)
431c0669 447 value = m2expr_BuildAddr (0, value, false);
1eee94d3
GM
448
449 if (converting_ISO_generic (location, type, value, m2type_GetByteType (), &t)
450 || converting_ISO_generic (location, type, value,
451 m2type_GetISOLocType (), &t)
452 || converting_ISO_generic (location, type, value,
453 m2type_GetISOByteType (), &t)
454 || converting_ISO_generic (location, type, value,
455 m2type_GetISOWordType (), &t)
456 || converting_ISO_generic (location, type, value, m2type_GetM2Word16 (),
457 &t)
458 || converting_ISO_generic (location, type, value, m2type_GetM2Word32 (),
459 &t)
460 || converting_ISO_generic (location, type, value, m2type_GetM2Word64 (),
461 &t))
462 return t;
463
464 if (TREE_CODE (type) == ARRAY_TYPE
465 && TREE_TYPE (type) == m2type_GetM2CharType ())
466 {
467 if (TREE_TYPE (value) == m2type_GetM2CharType ())
468
469 /* Passing a const char to an array [..] of char. So we convert
470 const char into the correct length string. */
471 return convert_char_to_array (location, type, value);
472 if (TREE_CODE (value) == STRING_CST)
473 /* Convert a string into an array constant, padding with zeros if
474 necessary. */
475 return convert_string_to_array (location, type, value);
476 }
477
478 if (checkOverflow)
479 return convert_and_check (location, type, value);
480 else
81d5ca0b 481 return convert_loc (location, type, value);
1eee94d3
GM
482}
483
484/* const_to_ISO_type - perform VAL (iso_type, expr). */
485
486static tree
487const_to_ISO_type (location_t location, tree expr, tree iso_type)
488{
489 tree n = m2expr_GetSizeOf (location, iso_type);
490
491 if ((m2expr_CompareTrees (n, m2decl_BuildIntegerConstant (1)) == 0)
492 && (iso_type == m2type_GetByteType ()
493 || iso_type == m2type_GetISOLocType ()
494 || iso_type == m2type_GetISOByteType ()))
495 return build1 (NOP_EXPR, iso_type, expr);
496 return const_to_ISO_aggregate_type (location, expr, iso_type);
497}
498
499/* const_to_ISO_aggregate_type - perform VAL (iso_type, expr). The
500 iso_type will be declared by the SYSTEM module as: TYPE iso_type =
501 ARRAY [0..n] OF LOC
502
503 this function will store a constant into the iso_type in the correct
504 endian order. It converts the expr into a unsigned int or signed
505 int and then strips it a byte at a time. */
506
507static tree
508const_to_ISO_aggregate_type (location_t location, tree expr, tree iso_type)
509{
510 tree byte;
511 m2type_Constructor c;
512 tree i = m2decl_BuildIntegerConstant (0);
513 tree n = m2expr_GetSizeOf (location, iso_type);
514 tree max_uint = m2decl_BuildIntegerConstant (256);
515
516 while (m2expr_CompareTrees (i, n) < 0)
517 {
518 max_uint = m2expr_BuildMult (location, max_uint,
431c0669 519 m2decl_BuildIntegerConstant (256), false);
1eee94d3 520 i = m2expr_BuildAdd (location, i, m2decl_BuildIntegerConstant (1),
431c0669 521 false);
1eee94d3
GM
522 }
523 max_uint = m2expr_BuildDivFloor (location, max_uint,
431c0669 524 m2decl_BuildIntegerConstant (2), false);
1eee94d3
GM
525
526 if (m2expr_CompareTrees (expr, m2decl_BuildIntegerConstant (0)) < 0)
431c0669 527 expr = m2expr_BuildAdd (location, expr, max_uint, false);
1eee94d3
GM
528
529 i = m2decl_BuildIntegerConstant (0);
530 c = m2type_BuildStartArrayConstructor (iso_type);
531 while (m2expr_CompareTrees (i, n) < 0)
532 {
533 byte = m2expr_BuildModTrunc (location, expr,
431c0669 534 m2decl_BuildIntegerConstant (256), false);
1eee94d3
GM
535 if (BYTES_BIG_ENDIAN)
536 m2type_BuildArrayConstructorElement (
537 c, m2convert_ToLoc (location, byte),
431c0669
GM
538 m2expr_BuildSub (location, m2expr_BuildSub (location, n, i, false),
539 m2decl_BuildIntegerConstant (1), false));
1eee94d3
GM
540 else
541 m2type_BuildArrayConstructorElement (
542 c, m2convert_ToLoc (location, byte), i);
543
544 i = m2expr_BuildAdd (location, i, m2decl_BuildIntegerConstant (1),
431c0669 545 false);
1eee94d3 546 expr = m2expr_BuildDivFloor (location, expr,
431c0669 547 m2decl_BuildIntegerConstant (256), false);
1eee94d3
GM
548 }
549
550 return m2type_BuildEndArrayConstructor (c);
551}
552
553/* ConvertConstantAndCheck - in Modula-2 sementics: RETURN( VAL(type,
554 expr) ). Only to be used for a constant expr, overflow checking
555 is performed. */
556
557tree
558m2convert_ConvertConstantAndCheck (location_t location, tree type, tree expr)
559{
560 tree etype;
561 expr = fold (expr);
562 STRIP_NOPS (expr);
563 expr = m2expr_FoldAndStrip (expr);
564 etype = TREE_TYPE (expr);
565
566 m2assert_AssertLocation (location);
567 if (etype == type)
568 return expr;
569
570 if (TREE_CODE (expr) == FUNCTION_DECL)
431c0669 571 expr = m2expr_BuildAddr (location, expr, false);
1eee94d3
GM
572
573 type = m2tree_skip_type_decl (type);
574 if (type == m2type_GetByteType () || type == m2type_GetISOLocType ()
575 || type == m2type_GetISOByteType () || type == m2type_GetISOWordType ()
576 || type == m2type_GetM2Word16 () || type == m2type_GetM2Word32 ()
577 || type == m2type_GetM2Word64 ())
578 return const_to_ISO_type (location, expr, type);
579
580 return convert_and_check (location, type, m2expr_FoldAndStrip (expr));
581}
582
583/* ToWord - converts an expression (Integer or Ordinal type) into a
584 WORD. */
585
586tree
587m2convert_ToWord (location_t location, tree expr)
588{
431c0669 589 return m2convert_BuildConvert (location, m2type_GetWordType (), expr, false);
1eee94d3
GM
590}
591
592/* ToCardinal - convert an expression, expr, to a CARDINAL. */
593
594tree
595m2convert_ToCardinal (location_t location, tree expr)
596{
597 return m2convert_BuildConvert (location, m2type_GetCardinalType (), expr,
431c0669 598 false);
1eee94d3
GM
599}
600
601/* convertToPtr - if the type of tree, t, is not a ptr_type_node then
602 convert it. */
603
604tree
605m2convert_convertToPtr (location_t location, tree type)
606{
607 if (TREE_CODE (TREE_TYPE (type)) == POINTER_TYPE)
608 return type;
609 else
610 return m2convert_BuildConvert (location, m2type_GetPointerType (), type,
431c0669 611 false);
1eee94d3
GM
612}
613
614/* ToInteger - convert an expression, expr, to an INTEGER. */
615
616tree
617m2convert_ToInteger (location_t location, tree expr)
618{
619 return m2convert_BuildConvert (location, m2type_GetIntegerType (), expr,
431c0669 620 false);
1eee94d3
GM
621}
622
623/* ToBitset - convert an expression, expr, to a BITSET type. */
624
625tree
626m2convert_ToBitset (location_t location, tree expr)
627{
628 return m2convert_BuildConvert (location, m2type_GetBitsetType (), expr,
431c0669 629 false);
1eee94d3
GM
630}
631
632/* ToLoc - convert an expression, expr, to a LOC. */
633
634tree
635m2convert_ToLoc (location_t location, tree expr)
636{
637 return m2convert_BuildConvert (location, m2type_GetISOByteType (), expr,
431c0669 638 false);
1eee94d3
GM
639}
640
641/* GenericToType - converts, expr, into, type, providing that expr is
642 a generic system type (byte, word etc). Otherwise expr is
643 returned unaltered. */
644
645tree
646m2convert_GenericToType (location_t location, tree type, tree expr)
647{
648 tree etype = TREE_TYPE (expr);
649
650 type = m2tree_skip_type_decl (type);
651 if (type == etype)
652 return expr;
653
654 if (type == m2type_GetISOWordType () || type == m2type_GetM2Word16 ()
655 || type == m2type_GetM2Word32 () || type == m2type_GetM2Word64 ())
656 return const_to_ISO_type (location, expr, type);
657
658 return expr;
659}