]> gcc.gnu.org Git - gcc.git/blame - gcc/d/d-convert.cc
d: Fix ICE: verify_gimple_failed (conversion of register to a different size in ...
[gcc.git] / gcc / d / d-convert.cc
CommitLineData
b4c522fa 1/* d-convert.cc -- Data type conversion routines.
83ffe9cd 2 Copyright (C) 2006-2023 Free Software Foundation, Inc.
b4c522fa
IB
3
4GCC is free software; you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation; either version 3, or (at your option)
7any later version.
8
9GCC is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with GCC; see the file COPYING3. If not see
16<http://www.gnu.org/licenses/>. */
17
18#include "config.h"
19#include "system.h"
20#include "coretypes.h"
21
22#include "dmd/aggregate.h"
23#include "dmd/declaration.h"
24#include "dmd/expression.h"
25#include "dmd/mtype.h"
26
27#include "tree.h"
28#include "fold-const.h"
29#include "diagnostic.h"
30#include "langhooks.h"
31#include "target.h"
32#include "convert.h"
33#include "stor-layout.h"
34
35#include "d-tree.h"
36
37
38/* Build CODE expression with operands OP0 and OP1.
39 Helper function for d_truthvalue_conversion, so assumes bool result. */
40
41static tree
42d_build_truthvalue_op (tree_code code, tree op0, tree op1)
43{
44 tree type0, type1;
45
46 tree result_type = NULL_TREE;
47
48 type0 = TREE_TYPE (op0);
49 type1 = TREE_TYPE (op1);
50
51 /* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue. */
52 STRIP_TYPE_NOPS (op0);
53 STRIP_TYPE_NOPS (op1);
54
55 /* Also need to convert pointer/int comparison. */
56 if (POINTER_TYPE_P (type0) && TREE_CODE (op1) == INTEGER_CST
57 && integer_zerop (op1))
58 {
59 result_type = type0;
60 }
61 else if (POINTER_TYPE_P (type1) && TREE_CODE (op0) == INTEGER_CST
62 && integer_zerop (op0))
63 {
64 result_type = type1;
65 }
66 /* If integral, need to convert unsigned/signed comparison.
67 Will also need to convert if type precisions differ. */
68 else if (INTEGRAL_TYPE_P (type0) && INTEGRAL_TYPE_P (type1))
69 {
70 if (TYPE_PRECISION (type0) > TYPE_PRECISION (type1))
71 result_type = type0;
72 else if (TYPE_PRECISION (type0) < TYPE_PRECISION (type1))
73 result_type = type1;
74 else if (TYPE_UNSIGNED (type0) != TYPE_UNSIGNED (type1))
75 result_type = TYPE_UNSIGNED (type0) ? type0 : type1;
76 }
77
78 if (result_type)
79 {
80 if (TREE_TYPE (op0) != result_type)
81 op0 = convert (result_type, op0);
82 if (TREE_TYPE (op1) != result_type)
83 op1 = convert (result_type, op1);
84 }
85
86 return fold_build2 (code, d_bool_type, op0, op1);
87}
88
89/* Return whether EXPR is a declaration whose address can never be NULL. */
90
91bool
92decl_with_nonnull_addr_p (const_tree expr)
93{
94 return (DECL_P (expr)
95 && (TREE_CODE (expr) == PARM_DECL
96 || TREE_CODE (expr) == LABEL_DECL
97 || !DECL_WEAK (expr)));
98}
99
100/* Convert EXPR to be a truth-value, validating its type for this purpose. */
101
102tree
103d_truthvalue_conversion (tree expr)
104{
105 switch (TREE_CODE (expr))
106 {
107 case EQ_EXPR: case NE_EXPR: case LE_EXPR:
108 case GE_EXPR: case LT_EXPR: case GT_EXPR:
109 if (TREE_TYPE (expr) == d_bool_type)
110 return expr;
111 return build2 (TREE_CODE (expr), d_bool_type,
112 TREE_OPERAND (expr, 0), TREE_OPERAND (expr, 1));
113
114 case TRUTH_ANDIF_EXPR:
115 case TRUTH_ORIF_EXPR:
116 case TRUTH_AND_EXPR:
117 case TRUTH_OR_EXPR:
118 case TRUTH_XOR_EXPR:
119 if (TREE_TYPE (expr) == d_bool_type)
120 return expr;
121 return build2 (TREE_CODE (expr), d_bool_type,
122 d_truthvalue_conversion (TREE_OPERAND (expr, 0)),
123 d_truthvalue_conversion (TREE_OPERAND (expr, 1)));
124
125 case TRUTH_NOT_EXPR:
126 if (TREE_TYPE (expr) == d_bool_type)
127 return expr;
128 return build1 (TREE_CODE (expr), d_bool_type,
129 d_truthvalue_conversion (TREE_OPERAND (expr, 0)));
130
131 case ERROR_MARK:
132 return expr;
133
134 case INTEGER_CST:
ab5c18d7
IB
135 return integer_zerop (expr) ? d_bool_false_node
136 : d_bool_true_node;
b4c522fa
IB
137
138 case REAL_CST:
139 return real_compare (NE_EXPR, &TREE_REAL_CST (expr), &dconst0)
ab5c18d7
IB
140 ? d_bool_true_node
141 : d_bool_false_node;
b4c522fa
IB
142
143 case ADDR_EXPR:
144 /* If we are taking the address of a decl that can never be null,
145 then the return result is always true. */
146 if (decl_with_nonnull_addr_p (TREE_OPERAND (expr, 0)))
147 {
148 warning (OPT_Waddress,
149 "the address of %qD will always evaluate as %<true%>",
150 TREE_OPERAND (expr, 0));
ab5c18d7 151 return d_bool_true_node;
b4c522fa
IB
152 }
153 break;
154
155 case COMPLEX_EXPR:
156 return d_build_truthvalue_op ((TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1))
157 ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
158 d_truthvalue_conversion (TREE_OPERAND (expr, 0)),
159 d_truthvalue_conversion (TREE_OPERAND (expr, 1)));
160
161 case NEGATE_EXPR:
162 case ABS_EXPR:
163 case FLOAT_EXPR:
164 /* These don't change whether an object is nonzero or zero. */
165 return d_truthvalue_conversion (TREE_OPERAND (expr, 0));
166
167 case LROTATE_EXPR:
168 case RROTATE_EXPR:
169 /* These don't change whether an object is zero or nonzero, but
170 we can't ignore them if their second arg has side-effects. */
171 if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)))
172 {
173 return build2 (COMPOUND_EXPR, d_bool_type, TREE_OPERAND (expr, 1),
174 d_truthvalue_conversion (TREE_OPERAND (expr, 0)));
175 }
176 else
177 return d_truthvalue_conversion (TREE_OPERAND (expr, 0));
178
179 case COND_EXPR:
180 /* Distribute the conversion into the arms of a COND_EXPR. */
181 return fold_build3 (COND_EXPR, d_bool_type, TREE_OPERAND (expr, 0),
182 d_truthvalue_conversion (TREE_OPERAND (expr, 1)),
183 d_truthvalue_conversion (TREE_OPERAND (expr, 2)));
184
185 case CONVERT_EXPR:
186 /* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE,
187 since that affects how `default_conversion' will behave. */
188 if (TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE
189 || TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == REFERENCE_TYPE)
190 break;
191 /* Fall through. */
192
193 case NOP_EXPR:
194 /* If this isn't narrowing the argument, we can ignore it. */
195 if (TYPE_PRECISION (TREE_TYPE (expr))
196 >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
197 return d_truthvalue_conversion (TREE_OPERAND (expr, 0));
198 break;
199
200 default:
201 break;
202 }
203
204 if (TREE_CODE (TREE_TYPE (expr)) == COMPLEX_TYPE)
205 {
206 tree t = save_expr (expr);
207 return d_build_truthvalue_op ((TREE_SIDE_EFFECTS (expr)
208 ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
209 d_truthvalue_conversion (real_part (t)),
210 d_truthvalue_conversion (imaginary_part (t)));
211 }
212 else
213 return d_build_truthvalue_op (NE_EXPR, expr,
214 build_zero_cst (TREE_TYPE (expr)));
215}
216
217
218/* Creates an expression whose value is that of EXPR, converted to type TYPE.
219 This function implements all reasonable scalar conversions. */
220
221tree
222convert (tree type, tree expr)
223{
224 tree e = expr;
225 tree_code code = TREE_CODE (type);
226
227 if (type == error_mark_node
228 || expr == error_mark_node
229 || TREE_TYPE (expr) == error_mark_node)
230 return error_mark_node;
231
232 const char *invalid_conv_diag
233 = targetm.invalid_conversion (TREE_TYPE (expr), type);
234
235 if (invalid_conv_diag)
236 {
237 error ("%s", invalid_conv_diag);
238 return error_mark_node;
239 }
240
241 if (type == TREE_TYPE (expr))
242 return expr;
243
244 if (TREE_CODE (type) == ARRAY_TYPE
245 && TREE_CODE (TREE_TYPE (expr)) == ARRAY_TYPE
246 && TYPE_DOMAIN (type) == TYPE_DOMAIN (TREE_TYPE (expr)))
247 return expr;
248
249 tree ret = targetm.convert_to_type (type, expr);
250 if (ret)
251 return ret;
252
253 STRIP_TYPE_NOPS (e);
254 tree etype = TREE_TYPE (e);
255
256 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (expr)))
257 return fold_convert (type, expr);
258 if (TREE_CODE (TREE_TYPE (expr)) == ERROR_MARK)
259 return error_mark_node;
260 if (TREE_CODE (TREE_TYPE (expr)) == VOID_TYPE)
261 {
262 error ("void value not ignored as it ought to be");
263 return error_mark_node;
264 }
265
266 switch (code)
267 {
268 case VOID_TYPE:
269 return fold_convert (type, e);
270
271 case INTEGER_TYPE:
272 case ENUMERAL_TYPE:
273 if (TREE_CODE (etype) == POINTER_TYPE
274 || TREE_CODE (etype) == REFERENCE_TYPE)
275 {
276 if (integer_zerop (e))
277 return build_int_cst (type, 0);
278
279 /* Convert to an unsigned integer of the correct width first, and
280 from there widen/truncate to the required type. */
281 tree utype = lang_hooks.types.type_for_size (TYPE_PRECISION (etype),
282 1);
283 ret = fold_build1 (CONVERT_EXPR, utype, e);
284 return fold_convert (type, ret);
285 }
286
287 return fold (convert_to_integer (type, e));
288
289 case BOOLEAN_TYPE:
290 return fold_convert (type, d_truthvalue_conversion (expr));
291
292 case POINTER_TYPE:
293 case REFERENCE_TYPE:
294 return fold (convert_to_pointer (type, e));
295
296 case REAL_TYPE:
297 if (TREE_CODE (etype) == COMPLEX_TYPE && TYPE_IMAGINARY_FLOAT (type))
298 e = build1 (IMAGPART_EXPR, TREE_TYPE (etype), e);
299
300 return fold (convert_to_real (type, e));
301
302 case COMPLEX_TYPE:
303 if (TREE_CODE (etype) == REAL_TYPE && TYPE_IMAGINARY_FLOAT (etype))
304 return fold_build2 (COMPLEX_EXPR, type,
305 build_zero_cst (TREE_TYPE (type)),
306 convert (TREE_TYPE (type), expr));
307
308 return fold (convert_to_complex (type, e));
309
310 case VECTOR_TYPE:
311 return fold (convert_to_vector (type, e));
312
313 case RECORD_TYPE:
314 case UNION_TYPE:
315 if (lang_hooks.types_compatible_p (type, TREE_TYPE (expr)))
316 return fold_build1 (VIEW_CONVERT_EXPR, type, expr);
317 break;
318
319 default:
320 break;
321 }
322
323 error ("conversion to non-scalar type requested");
324 return error_mark_node;
325}
326
327/* Return expression EXP, whose type has been converted to TYPE. */
328
329tree
330d_convert (tree type, tree exp)
331{
332 /* Check this first before retrieving frontend type. */
333 if (error_operand_p (type) || error_operand_p (exp))
334 return error_mark_node;
335
336 Type *totype = TYPE_LANG_FRONTEND (type);
337 Type *etype = TYPE_LANG_FRONTEND (TREE_TYPE (exp));
338
339 if (totype && etype)
340 return convert_expr (exp, etype, totype);
341
342 return convert (type, exp);
343}
344
345/* Return expression EXP, whose type has been convert from ETYPE to TOTYPE. */
346
347tree
348convert_expr (tree exp, Type *etype, Type *totype)
349{
350 tree result = NULL_TREE;
351
352 gcc_assert (etype && totype);
353 Type *ebtype = etype->toBasetype ();
354 Type *tbtype = totype->toBasetype ();
355
356 if (same_type_p (etype, totype))
357 return exp;
358
359 if (error_operand_p (exp))
360 return exp;
361
362 switch (ebtype->ty)
363 {
5fee5ec3
IB
364 case TY::Tdelegate:
365 if (tbtype->ty == TY::Tdelegate)
b4c522fa
IB
366 {
367 exp = d_save_expr (exp);
368 return build_delegate_cst (delegate_method (exp),
369 delegate_object (exp), totype);
370 }
5fee5ec3 371 else if (tbtype->ty == TY::Tpointer)
b4c522fa
IB
372 {
373 /* The front-end converts <delegate>.ptr to cast (void *)<delegate>.
374 Maybe should only allow void* ? */
375 exp = delegate_object (exp);
376 }
377 else
378 {
a9c697b8 379 error ("cannot convert a delegate expression to %qs",
b4c522fa
IB
380 totype->toChars ());
381 return error_mark_node;
382 }
383 break;
384
5fee5ec3
IB
385 case TY::Tstruct:
386 if (tbtype->ty == TY::Tstruct)
b4c522fa
IB
387 {
388 if (totype->size () == etype->size ())
389 {
390 /* Allowed to cast to structs with same type size. */
391 result = build_vconvert (build_ctype (totype), exp);
392 }
393 else
394 {
a9c697b8 395 error ("cannot convert struct %qs to %qs",
b4c522fa
IB
396 etype->toChars (), totype->toChars ());
397 return error_mark_node;
398 }
399 }
400 /* else, default conversion, which should produce an error. */
401 break;
402
5fee5ec3
IB
403 case TY::Tclass:
404 if (tbtype->ty == TY::Tclass)
b4c522fa
IB
405 {
406 ClassDeclaration *cdfrom = ebtype->isClassHandle ();
407 ClassDeclaration *cdto = tbtype->isClassHandle ();
408 int offset;
409
410 if (cdto->isBaseOf (cdfrom, &offset) && offset != OFFSET_RUNTIME)
411 {
412 /* Casting up the inheritance tree: Don't do anything special.
413 Cast to an implemented interface: Handle at compile-time. */
414 if (offset)
415 {
416 /* Forward references should not leak from the frontend. */
417 gcc_assert (offset != OFFSET_FWDREF);
418
419 tree type = build_ctype (totype);
420 exp = d_save_expr (exp);
421
422 tree cond = build_boolop (NE_EXPR, exp, null_pointer_node);
423 tree object = build_offset (exp, size_int (offset));
424
425 return build_condition (build_ctype (totype), cond,
426 build_nop (type, object),
427 build_nop (type, null_pointer_node));
428 }
429
430 /* d_convert will make a no-op cast. */
431 break;
432 }
29ff25e7 433 else if (cdfrom->isCPPclass () || cdto->isCPPclass ())
b4c522fa
IB
434 {
435 /* Downcasting in C++ is a no-op. */
29ff25e7 436 if (cdfrom->isCPPclass () && cdto->isCPPclass ())
b4c522fa
IB
437 break;
438
439 /* Casting from a C++ interface to a class/non-C++ interface
440 always results in null as there is no run-time information,
441 and no way one can derive from the other. */
442 warning (OPT_Wcast_result, "cast to %qs will produce null result",
443 totype->toChars ());
444 result = d_convert (build_ctype (totype), null_pointer_node);
445
446 /* Make sure the expression is still evaluated if necessary. */
447 if (TREE_SIDE_EFFECTS (exp))
448 result = compound_expr (exp, result);
449
450 break;
451 }
452
453 /* The offset can only be determined at run-time, do dynamic cast. */
454 libcall_fn libcall = cdfrom->isInterfaceDeclaration ()
455 ? LIBCALL_INTERFACE_CAST : LIBCALL_DYNAMIC_CAST;
456
457 return build_libcall (libcall, totype, 2, exp,
458 build_address (get_classinfo_decl (cdto)));
459 }
460 /* else default conversion. */
461 break;
462
5fee5ec3
IB
463 case TY::Tsarray:
464 if (tbtype->ty == TY::Tpointer)
b4c522fa
IB
465 {
466 result = build_nop (build_ctype (totype), build_address (exp));
467 }
5fee5ec3 468 else if (tbtype->ty == TY::Tarray)
b4c522fa 469 {
89fdaf5a 470 dinteger_t dim = ebtype->isTypeSArray ()->dim->toInteger ();
b4c522fa
IB
471 dinteger_t esize = ebtype->nextOf ()->size ();
472 dinteger_t tsize = tbtype->nextOf ()->size ();
473
474 tree ptrtype = build_ctype (tbtype->nextOf ()->pointerTo ());
475
c936c39f 476 if (esize != tsize)
b4c522fa 477 {
c936c39f
IB
478 /* Array element sizes do not match, so we must adjust the
479 dimensions. */
480 if (tsize == 0 || (dim * esize) % tsize != 0)
481 {
482 error ("cannot cast %qs to %qs since sizes do not line up",
483 etype->toChars (), totype->toChars ());
484 return error_mark_node;
485 }
486 dim = (dim * esize) / tsize;
b4c522fa 487 }
b4c522fa
IB
488
489 /* Assumes casting to dynamic array of same type or void. */
490 return d_array_value (build_ctype (totype), size_int (dim),
491 build_nop (ptrtype, build_address (exp)));
492 }
5fee5ec3 493 else if (tbtype->ty == TY::Tsarray)
b4c522fa
IB
494 {
495 /* D allows casting a static array to any static array type. */
496 return build_nop (build_ctype (totype), exp);
497 }
5fee5ec3 498 else if (tbtype->ty == TY::Tstruct)
b4c522fa
IB
499 {
500 /* And allows casting a static array to any struct type too.
501 Type sizes should have already been checked by the frontend. */
502 gcc_assert (totype->size () == etype->size ());
503 result = build_vconvert (build_ctype (totype), exp);
504 }
329bef49
IB
505 else if (tbtype->ty == TY::Tvector && tbtype->size () == ebtype->size ())
506 {
507 /* Allow casting from array to vector as if its an unaligned load. */
508 tree type = build_ctype (totype);
509 tree unaligned_type = build_variant_type_copy (type);
510 SET_TYPE_ALIGN (unaligned_type, 1 * BITS_PER_UNIT);
511 TYPE_USER_ALIGN (unaligned_type) = 1;
512 result = convert (type, build_vconvert (unaligned_type, exp));
513 }
b4c522fa
IB
514 else
515 {
516 error ("cannot cast expression of type %qs to type %qs",
517 etype->toChars (), totype->toChars ());
518 return error_mark_node;
519 }
520 break;
521
5fee5ec3
IB
522 case TY::Tarray:
523 if (tbtype->ty == TY::Tpointer)
b4c522fa
IB
524 {
525 return d_convert (build_ctype (totype), d_array_ptr (exp));
526 }
5fee5ec3 527 else if (tbtype->ty == TY::Tarray)
b4c522fa
IB
528 {
529 /* Assume tvoid->size() == 1. */
fbdaa581
IB
530 dinteger_t fsize = ebtype->nextOf ()->toBasetype ()->size ();
531 dinteger_t tsize = tbtype->nextOf ()->toBasetype ()->size ();
b4c522fa
IB
532
533 if (fsize != tsize)
534 {
5fee5ec3
IB
535 /* Conversion requires a reinterpret cast of array.
536 This case should have been lowered in the semantic pass. */
537 if (tsize != 0 && fsize % tsize == 0)
538 {
539 /* Set array dimension to (length * (fsize / tsize)). */
540 tree newlength = size_mult_expr (d_array_length (exp),
541 size_int (fsize / tsize));
542 return d_array_value (build_ctype (totype), newlength,
543 d_array_ptr (exp));
544 }
545 else
546 gcc_unreachable ();
b4c522fa
IB
547 }
548 else
549 {
550 /* Convert from void[] or elements are the same size
551 -- don't change length. */
552 return build_vconvert (build_ctype (totype), exp);
553 }
554 }
5fee5ec3 555 else if (tbtype->ty == TY::Tsarray)
b4c522fa
IB
556 {
557 /* Strings are treated as dynamic arrays in D2. */
558 if (ebtype->isString () && tbtype->isString ())
559 return indirect_ref (build_ctype (totype), d_array_ptr (exp));
560 }
561 else
562 {
563 error ("cannot cast expression of type %qs to %qs",
564 etype->toChars (), totype->toChars ());
565 return error_mark_node;
566 }
567 break;
568
5fee5ec3
IB
569 case TY::Taarray:
570 if (tbtype->ty == TY::Taarray)
b4c522fa
IB
571 return build_vconvert (build_ctype (totype), exp);
572 /* Can convert associative arrays to void pointers. */
5fee5ec3 573 else if (tbtype->ty == TY::Tpointer && tbtype->nextOf ()->ty == TY::Tvoid)
b4c522fa
IB
574 return build_vconvert (build_ctype (totype), exp);
575 /* Else, default conversion, which should product an error. */
576 break;
577
5fee5ec3 578 case TY::Tpointer:
b4c522fa 579 /* Can convert void pointers to associative arrays too. */
5fee5ec3 580 if (tbtype->ty == TY::Taarray && ebtype->nextOf ()->ty == TY::Tvoid)
b4c522fa
IB
581 return build_vconvert (build_ctype (totype), exp);
582 break;
583
5fee5ec3
IB
584 case TY::Tnull:
585 case TY::Tnoreturn:
5a0aa603
IB
586 /* Casting from `typeof(null)' for `null' expressions, or `typeof(*null)'
587 for `noreturn' expressions is represented as all zeros. */
5e95646e 588 result = build_typeof_null_value (totype);
b4c522fa 589
5e95646e
IB
590 /* Make sure the expression is still evaluated if necessary. */
591 if (TREE_SIDE_EFFECTS (exp))
592 result = compound_expr (exp, result);
593 break;
b4c522fa 594
5fee5ec3
IB
595 case TY::Tvector:
596 if (tbtype->ty == TY::Tsarray)
b4c522fa
IB
597 {
598 if (tbtype->size () == ebtype->size ())
599 return build_vconvert (build_ctype (totype), exp);
600 }
601 break;
602
603 default:
604 /* All casts between imaginary and non-imaginary result in 0.0,
605 except for casts between complex and imaginary types. */
606 if (!ebtype->iscomplex () && !tbtype->iscomplex ()
607 && (ebtype->isimaginary () != tbtype->isimaginary ()))
608 {
609 warning (OPT_Wcast_result,
610 "cast from %qs to %qs will produce zero result",
611 ebtype->toChars (), tbtype->toChars ());
612
613 return compound_expr (exp, build_zero_cst (build_ctype (tbtype)));
614 }
615
b4c522fa
IB
616 gcc_assert (TREE_CODE (exp) != STRING_CST);
617 break;
618 }
619
620 return result ? result : convert (build_ctype (totype), exp);
621}
622
9599da71 623/* Return a TREE representation of EXPR, whose type has been converted from
5c9b7408
IB
624 * ETYPE to TOTYPE, and is being used in an rvalue context. */
625
626tree
627convert_for_rvalue (tree expr, Type *etype, Type *totype)
628{
629 tree result = NULL_TREE;
630
631 Type *ebtype = etype->toBasetype ();
632 Type *tbtype = totype->toBasetype ();
633
5fee5ec3 634 if (ebtype->ty == TY::Tbool)
5c9b7408 635 {
5c9b7408
IB
636 /* If casting from bool, the result is either 0 or 1, any other value
637 violates @safe code, so enforce that it is never invalid. */
9599da71
IB
638 for (tree ref = expr; TREE_CODE (ref) == COMPONENT_REF;
639 ref = TREE_OPERAND (ref, 0))
5c9b7408 640 {
9599da71
IB
641 /* If the expression is a field that's part of a union, reinterpret
642 the boolean as an integer and test the first bit. The generated
643 code should end up being equivalent to:
5c9b7408 644 *cast(ubyte *)&expr & 1; */
9599da71
IB
645 if (TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 0))) == UNION_TYPE)
646 {
647 machine_mode bool_mode = TYPE_MODE (TREE_TYPE (expr));
648 tree mtype = lang_hooks.types.type_for_mode (bool_mode, 1);
649 result = fold_build2 (BIT_AND_EXPR, mtype,
650 build_vconvert (mtype, expr),
651 build_one_cst (mtype));
652 break;
653 }
5c9b7408
IB
654 }
655
9599da71
IB
656 if (result == NULL_TREE)
657 result = d_truthvalue_conversion (expr);
658
5c9b7408 659 result = convert (build_ctype (tbtype), result);
5c9b7408
IB
660 }
661
329bef49
IB
662 if (tbtype->ty == TY::Tsarray
663 && ebtype->ty == TY::Tsarray
664 && tbtype->nextOf ()->ty == ebtype->nextOf ()->ty
665 && INDIRECT_REF_P (expr)
666 && CONVERT_EXPR_CODE_P (TREE_CODE (TREE_OPERAND (expr, 0)))
667 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (expr, 0), 0)) == ADDR_EXPR)
668 {
669 /* If expression is a vector that was casted to an array either by
670 explicit type cast or by taking the vector's `.array' value, strip the
671 reinterpret cast and build a constructor instead. */
672 tree ptr = TREE_OPERAND (TREE_OPERAND (expr, 0), 0);
673
674 if (VECTOR_TYPE_P (TREE_TYPE (TREE_TYPE (ptr))))
675 {
676 /* Rewrite: `*(Array *)&vector'
677 into: `{ vector[0], vector[1], ... }' */
678 tree array = d_save_expr (TREE_OPERAND (ptr, 0));
679 array = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (expr), array);
680
681 uinteger_t dim = tbtype->isTypeSArray ()->dim->toUInteger ();
682 vec <constructor_elt, va_gc> *elms = NULL;
683 for (uinteger_t i = 0; i < dim; i++)
684 {
685 tree index = size_int (i);
686 tree value = build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (array)),
687 array, index, NULL_TREE, NULL_TREE);
688 CONSTRUCTOR_APPEND_ELT (elms, index, value);
689 }
690
691 return build_constructor (build_ctype (totype), elms);
692 }
693 }
694
5c9b7408
IB
695 return result ? result : convert_expr (expr, etype, totype);
696}
b4c522fa 697
46024d05
IB
698/* Helper for convert_for_assigment and convert_for_argument.
699 Returns true if EXPR is a va_list static array parameter. */
700
701static bool
702is_valist_parameter_type (Expression *expr)
703{
704 Declaration *decl = NULL;
705
706 if (VarExp *ve = expr->isVarExp ())
707 decl = ve->var;
708 else if (SymOffExp *se = expr->isSymOffExp ())
709 decl = se->var;
710
711 if (decl != NULL && decl->isParameter () && valist_array_p (decl->type))
712 return true;
713
714 return false;
715}
716
717/* Helper for convert_for_assigment and convert_for_argument.
718 Report erroneous uses of assigning or passing a va_list parameter. */
719
720static void
721check_valist_conversion (Expression *expr, Type *totype, bool in_assignment)
722{
723 /* Parameter symbol and its converted type. */
724 Declaration *decl = NULL;
725 /* Type of parameter when evaluated in the expression. */
726 Type *type = NULL;
727
728 if (VarExp *ve = expr->isVarExp ())
729 {
730 decl = ve->var;
731 type = ve->var->type->nextOf ()->pointerTo ();
732 }
733 else if (SymOffExp *se = expr->isSymOffExp ())
734 {
735 decl = se->var;
736 type = se->var->type->nextOf ()->pointerTo ()->pointerTo ();
737 }
738
739 /* Should not be called unless is_valist_parameter_type also matched. */
740 gcc_assert (decl != NULL && decl->isParameter ()
741 && valist_array_p (decl->type));
742
743 /* OK if conversion between types is allowed. */
744 if (type->implicitConvTo (totype) != MATCH::nomatch)
745 return;
746
747 if (in_assignment)
748 {
749 error_at (make_location_t (expr->loc), "cannot convert parameter %qs "
750 "from type %qs to type %qs in assignment",
751 expr->toChars(), type->toChars (), totype->toChars ());
752 }
753 else
754 {
755 error_at (make_location_t (expr->loc), "cannot convert parameter %qs "
756 "from type %qs to type %qs in argument passing",
757 expr->toChars(), type->toChars (), totype->toChars ());
758 }
759
760 inform (make_location_t (decl->loc), "parameters of type %<va_list%> "
761 "{aka %qs} are decayed to pointer types, and require %<va_copy%> "
762 "to be converted back into a static array type",
763 decl->type->toChars ());
764}
765
b4c522fa 766/* Apply semantics of assignment to a value of type TOTYPE to EXPR
46024d05
IB
767 For example: `pointer = array' gets lowered to `pointer = &array[0]'.
768 If LITERALP is true, then EXPR is a value used in the initialization
769 of another literal.
b4c522fa
IB
770
771 Return a TREE representation of EXPR implicitly converted to TOTYPE
772 for use in assignment expressions MODIFY_EXPR, INIT_EXPR. */
773
774tree
46024d05 775convert_for_assignment (Expression *expr, Type *totype, bool literalp)
b4c522fa 776{
46024d05 777 Type *ebtype = expr->type->toBasetype ();
b4c522fa
IB
778 Type *tbtype = totype->toBasetype ();
779
780 /* Assuming this only has to handle converting a non Tsarray type to
781 arbitrarily dimensioned Tsarrays. */
5fee5ec3 782 if (tbtype->ty == TY::Tsarray)
b4c522fa
IB
783 {
784 Type *telem = tbtype->nextOf ()->baseElemOf ();
785
786 if (same_type_p (telem, ebtype))
787 {
89fdaf5a 788 TypeSArray *sa_type = tbtype->isTypeSArray ();
b4c522fa
IB
789 uinteger_t count = sa_type->dim->toUInteger ();
790
791 tree ctor = build_constructor (build_ctype (totype), NULL);
792 if (count)
793 {
af3c19f0 794 vec <constructor_elt, va_gc> *ce = NULL;
b4c522fa
IB
795 tree index = build2 (RANGE_EXPR, build_ctype (Type::tsize_t),
796 size_zero_node, size_int (count - 1));
46024d05
IB
797 tree value = convert_for_assignment (expr, sa_type->next,
798 literalp);
b4c522fa
IB
799 /* Can't use VAR_DECLs in CONSTRUCTORS. */
800 if (VAR_P (value))
801 {
802 value = DECL_INITIAL (value);
803 gcc_assert (value);
804 }
805
806 CONSTRUCTOR_APPEND_ELT (ce, index, value);
807 CONSTRUCTOR_ELTS (ctor) = ce;
808 }
809 TREE_READONLY (ctor) = 1;
810 TREE_CONSTANT (ctor) = 1;
811 return ctor;
812 }
813 }
814
815 /* D Front end uses IntegerExp(0) to mean zero-init an array or structure. */
5fee5ec3 816 if ((tbtype->ty == TY::Tsarray || tbtype->ty == TY::Tstruct)
b4c522fa
IB
817 && ebtype->isintegral ())
818 {
46024d05
IB
819 tree ret = build_expr (expr, false, literalp);
820 gcc_assert (integer_zerop (ret));
821 return ret;
b4c522fa
IB
822 }
823
46024d05
IB
824 /* Assigning a va_list by value or reference, check whether RHS is a parameter
825 that has has been lowered by declaration_type or parameter_type. */
826 if (is_valist_parameter_type (expr))
827 check_valist_conversion (expr, totype, true);
828
829 return convert_for_rvalue (build_expr (expr, false, literalp),
830 expr->type, totype);
b4c522fa
IB
831}
832
833/* Return a TREE representation of EXPR converted to represent
834 the parameter type ARG. */
835
836tree
46024d05 837convert_for_argument (Expression *expr, Parameter *arg)
b4c522fa 838{
46024d05
IB
839 tree targ = build_expr (expr);
840
b4c522fa
IB
841 /* Lazy arguments: expr should already be a delegate. */
842 if (arg->storageClass & STClazy)
46024d05 843 return targ;
b4c522fa 844
46024d05
IB
845 /* Passing a va_list by value, check whether the target requires it to
846 be decayed to a pointer type. */
b4c522fa
IB
847 if (valist_array_p (arg->type))
848 {
46024d05
IB
849 if (!POINTER_TYPE_P (TREE_TYPE (targ)))
850 return build_address (targ);
851
852 /* Do nothing if the va_list has already been converted. */
853 return targ;
b4c522fa
IB
854 }
855
46024d05
IB
856 /* Passing a va_list by reference, check if types are really compatible
857 after conversion from static array to pointer type. */
858 if (is_valist_parameter_type (expr))
859 check_valist_conversion (expr, arg->type, false);
860
861 /* Front-end shouldn't automatically take the address of `ref' parameters. */
862 if (parameter_reference_p (arg))
863 return convert (parameter_type (arg), build_address (targ));
864
865 return targ;
b4c522fa
IB
866}
867
868/* Perform default promotions for data used in expressions.
869 Arrays and functions are converted to pointers;
870 enumeral types or short or char, to int.
871 In addition, manifest constants symbols are replaced by their values.
872
873 Return truth-value conversion of expression EXPR from value type TYPE. */
874
875tree
876convert_for_condition (tree expr, Type *type)
877{
878 tree result = NULL_TREE;
879
880 switch (type->toBasetype ()->ty)
881 {
5fee5ec3 882 case TY::Taarray:
b4c522fa
IB
883 /* Checks that aa.ptr !is null. */
884 result = component_ref (expr, TYPE_FIELDS (TREE_TYPE (expr)));
885 break;
886
5fee5ec3 887 case TY::Tarray:
b4c522fa
IB
888 {
889 /* Checks (arr.length || arr.ptr) (i.e arr !is null). */
890 expr = d_save_expr (expr);
891 tree len = d_array_length (expr);
892 tree ptr = d_array_ptr (expr);
893 if (TYPE_MODE (TREE_TYPE (len)) == TYPE_MODE (TREE_TYPE (ptr)))
894 {
895 result = build2 (BIT_IOR_EXPR, TREE_TYPE (len), len,
896 d_convert (TREE_TYPE (len), ptr));
897 }
898 else
899 {
900 len = d_truthvalue_conversion (len);
901 ptr = d_truthvalue_conversion (ptr);
902 /* Probably not worth using TRUTH_OROR here. */
903 result = build2 (TRUTH_OR_EXPR, TREE_TYPE (len), len, ptr);
904 }
905 break;
906 }
907
5fee5ec3 908 case TY::Tdelegate:
b4c522fa
IB
909 {
910 /* Checks (function || object), but what good is it if there is
911 a null function pointer? */
912 tree obj, func;
913 if (METHOD_CALL_EXPR (expr))
914 extract_from_method_call (expr, obj, func);
915 else
916 {
917 expr = d_save_expr (expr);
918 obj = delegate_object (expr);
919 func = delegate_method (expr);
920 }
921
922 obj = d_truthvalue_conversion (obj);
923 func = d_truthvalue_conversion (func);
924 /* Probably not worth using TRUTH_ORIF here. */
925 result = build2 (BIT_IOR_EXPR, TREE_TYPE (obj), obj, func);
926 break;
927 }
928
5fee5ec3 929 case TY::Tnoreturn:
5a0aa603
IB
930 /* Front-end allows conditionals that never return, represent the
931 conditional result value as all zeros. */
932 result = build_zero_cst (d_bool_type);
933
934 /* Make sure the expression is still evaluated if necessary. */
935 if (TREE_SIDE_EFFECTS (expr))
936 result = compound_expr (expr, result);
937 break;
938
b4c522fa 939 default:
9599da71 940 result = convert_for_rvalue (expr, type, type);
b4c522fa
IB
941 break;
942 }
943
944 return d_truthvalue_conversion (result);
945}
946
947
948/* Convert EXP to a dynamic array.
949 EXP must be a static array or dynamic array. */
950
951tree
952d_array_convert (Expression *exp)
953{
954 Type *tb = exp->type->toBasetype ();
955
5fee5ec3 956 if (tb->ty == TY::Tarray)
b4c522fa
IB
957 return build_expr (exp);
958
5fee5ec3 959 if (tb->ty == TY::Tsarray)
b4c522fa
IB
960 {
961 Type *totype = tb->nextOf ()->arrayOf ();
962 return convert_expr (build_expr (exp), exp->type, totype);
963 }
964
965 /* Invalid type passed. */
966 gcc_unreachable ();
967}
968
969/* Convert EXP to a dynamic array, where ETYPE is the element type.
970 Similar to above, except that EXP is allowed to be an element of an array.
0af711e1 971 Temporary variables are created inline if EXP is not an lvalue. */
b4c522fa
IB
972
973tree
0af711e1 974d_array_convert (Type *etype, Expression *exp)
b4c522fa
IB
975{
976 Type *tb = exp->type->toBasetype ();
977
5fee5ec3
IB
978 if ((tb->ty != TY::Tarray && tb->ty != TY::Tsarray)
979 || same_type_p (tb, etype))
b4c522fa
IB
980 {
981 /* Convert single element to an array. */
0af711e1 982 tree expr = build_expr (exp);
b4c522fa 983
0af711e1
IB
984 if (!exp->isLvalue ())
985 {
986 tree var = build_local_temp (TREE_TYPE (expr));
987 expr = compound_expr (modify_expr (var, expr), var);
988 }
b4c522fa
IB
989
990 return d_array_value (build_ctype (exp->type->arrayOf ()),
991 size_int (1), build_address (expr));
992 }
993 else
994 return d_array_convert (exp);
995}
This page took 1.621677 seconds and 5 git commands to generate.