]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/d/d-convert.cc
Update copyright years.
[thirdparty/gcc.git] / gcc / d / d-convert.cc
1 /* d-convert.cc -- Data type conversion routines.
2 Copyright (C) 2006-2019 Free Software Foundation, Inc.
3
4 GCC is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
8
9 GCC is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along 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
41 static tree
42 d_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
91 bool
92 decl_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
102 tree
103 d_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:
135 return integer_zerop (expr) ? boolean_false_node
136 : boolean_true_node;
137
138 case REAL_CST:
139 return real_compare (NE_EXPR, &TREE_REAL_CST (expr), &dconst0)
140 ? boolean_true_node
141 : boolean_false_node;
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));
151 return boolean_true_node;
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
221 tree
222 convert (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
329 tree
330 d_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
347 tree
348 convert_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 {
364 case Tdelegate:
365 if (tbtype->ty == Tdelegate)
366 {
367 exp = d_save_expr (exp);
368 return build_delegate_cst (delegate_method (exp),
369 delegate_object (exp), totype);
370 }
371 else if (tbtype->ty == Tpointer)
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 {
379 error ("can't convert a delegate expression to %qs",
380 totype->toChars ());
381 return error_mark_node;
382 }
383 break;
384
385 case Tstruct:
386 if (tbtype->ty == Tstruct)
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 {
395 error ("can't convert struct %qs to %qs",
396 etype->toChars (), totype->toChars ());
397 return error_mark_node;
398 }
399 }
400 /* else, default conversion, which should produce an error. */
401 break;
402
403 case Tclass:
404 if (tbtype->ty == Tclass)
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 }
433 else if (cdfrom->isCPPclass ())
434 {
435 /* Downcasting in C++ is a no-op. */
436 if (cdto->isCPPclass ())
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
463 case Tsarray:
464 if (tbtype->ty == Tpointer)
465 {
466 result = build_nop (build_ctype (totype), build_address (exp));
467 }
468 else if (tbtype->ty == Tarray)
469 {
470 dinteger_t dim = ((TypeSArray *) ebtype)->dim->toInteger ();
471 dinteger_t esize = ebtype->nextOf ()->size ();
472 dinteger_t tsize = tbtype->nextOf ()->size ();
473
474 tree ptrtype = build_ctype (tbtype->nextOf ()->pointerTo ());
475
476 if ((dim * esize) % tsize != 0)
477 {
478 error ("cannot cast %qs to %qs since sizes don't line up",
479 etype->toChars (), totype->toChars ());
480 return error_mark_node;
481 }
482 dim = (dim * esize) / tsize;
483
484 /* Assumes casting to dynamic array of same type or void. */
485 return d_array_value (build_ctype (totype), size_int (dim),
486 build_nop (ptrtype, build_address (exp)));
487 }
488 else if (tbtype->ty == Tsarray)
489 {
490 /* D allows casting a static array to any static array type. */
491 return build_nop (build_ctype (totype), exp);
492 }
493 else if (tbtype->ty == Tstruct)
494 {
495 /* And allows casting a static array to any struct type too.
496 Type sizes should have already been checked by the frontend. */
497 gcc_assert (totype->size () == etype->size ());
498 result = build_vconvert (build_ctype (totype), exp);
499 }
500 else
501 {
502 error ("cannot cast expression of type %qs to type %qs",
503 etype->toChars (), totype->toChars ());
504 return error_mark_node;
505 }
506 break;
507
508 case Tarray:
509 if (tbtype->ty == Tpointer)
510 {
511 return d_convert (build_ctype (totype), d_array_ptr (exp));
512 }
513 else if (tbtype->ty == Tarray)
514 {
515 /* Assume tvoid->size() == 1. */
516 d_uns64 fsize = ebtype->nextOf ()->toBasetype ()->size ();
517 d_uns64 tsize = tbtype->nextOf ()->toBasetype ()->size ();
518
519 if (fsize != tsize)
520 {
521 /* Conversion requires a reinterpret cast of array. */
522 return build_libcall (LIBCALL_ARRAYCAST, totype, 3,
523 size_int (tsize), size_int (fsize), exp);
524 }
525 else
526 {
527 /* Convert from void[] or elements are the same size
528 -- don't change length. */
529 return build_vconvert (build_ctype (totype), exp);
530 }
531 }
532 else if (tbtype->ty == Tsarray)
533 {
534 /* Strings are treated as dynamic arrays in D2. */
535 if (ebtype->isString () && tbtype->isString ())
536 return indirect_ref (build_ctype (totype), d_array_ptr (exp));
537 }
538 else
539 {
540 error ("cannot cast expression of type %qs to %qs",
541 etype->toChars (), totype->toChars ());
542 return error_mark_node;
543 }
544 break;
545
546 case Taarray:
547 if (tbtype->ty == Taarray)
548 return build_vconvert (build_ctype (totype), exp);
549 /* Can convert associative arrays to void pointers. */
550 else if (tbtype->ty == Tpointer && tbtype->nextOf ()->ty == Tvoid)
551 return build_vconvert (build_ctype (totype), exp);
552 /* Else, default conversion, which should product an error. */
553 break;
554
555 case Tpointer:
556 /* Can convert void pointers to associative arrays too. */
557 if (tbtype->ty == Taarray && ebtype->nextOf ()->ty == Tvoid)
558 return build_vconvert (build_ctype (totype), exp);
559 break;
560
561 case Tnull:
562 /* Casting from typeof(null) is represented as all zeros. */
563 if (tbtype->ty == Tarray)
564 {
565 tree ptrtype = build_ctype (tbtype->nextOf ()->pointerTo ());
566 return d_array_value (build_ctype (totype), size_int (0),
567 build_nop (ptrtype, exp));
568 }
569 else if (tbtype->ty == Taarray)
570 return build_constructor (build_ctype (totype), NULL);
571 else if (tbtype->ty == Tdelegate)
572 return build_delegate_cst (exp, null_pointer_node, totype);
573
574 return build_zero_cst (build_ctype (totype));
575
576 case Tvector:
577 if (tbtype->ty == Tsarray)
578 {
579 if (tbtype->size () == ebtype->size ())
580 return build_vconvert (build_ctype (totype), exp);
581 }
582 break;
583
584 default:
585 /* All casts between imaginary and non-imaginary result in 0.0,
586 except for casts between complex and imaginary types. */
587 if (!ebtype->iscomplex () && !tbtype->iscomplex ()
588 && (ebtype->isimaginary () != tbtype->isimaginary ()))
589 {
590 warning (OPT_Wcast_result,
591 "cast from %qs to %qs will produce zero result",
592 ebtype->toChars (), tbtype->toChars ());
593
594 return compound_expr (exp, build_zero_cst (build_ctype (tbtype)));
595 }
596
597 exp = fold_convert (build_ctype (etype), exp);
598 gcc_assert (TREE_CODE (exp) != STRING_CST);
599 break;
600 }
601
602 return result ? result : convert (build_ctype (totype), exp);
603 }
604
605
606 /* Apply semantics of assignment to a value of type TOTYPE to EXPR
607 (e.g., pointer = array -> pointer = &array[0])
608
609 Return a TREE representation of EXPR implicitly converted to TOTYPE
610 for use in assignment expressions MODIFY_EXPR, INIT_EXPR. */
611
612 tree
613 convert_for_assignment (tree expr, Type *etype, Type *totype)
614 {
615 Type *ebtype = etype->toBasetype ();
616 Type *tbtype = totype->toBasetype ();
617
618 /* Assuming this only has to handle converting a non Tsarray type to
619 arbitrarily dimensioned Tsarrays. */
620 if (tbtype->ty == Tsarray)
621 {
622 Type *telem = tbtype->nextOf ()->baseElemOf ();
623
624 if (same_type_p (telem, ebtype))
625 {
626 TypeSArray *sa_type = (TypeSArray *) tbtype;
627 uinteger_t count = sa_type->dim->toUInteger ();
628
629 tree ctor = build_constructor (build_ctype (totype), NULL);
630 if (count)
631 {
632 vec<constructor_elt, va_gc> *ce = NULL;
633 tree index = build2 (RANGE_EXPR, build_ctype (Type::tsize_t),
634 size_zero_node, size_int (count - 1));
635 tree value = convert_for_assignment (expr, etype, sa_type->next);
636
637 /* Can't use VAR_DECLs in CONSTRUCTORS. */
638 if (VAR_P (value))
639 {
640 value = DECL_INITIAL (value);
641 gcc_assert (value);
642 }
643
644 CONSTRUCTOR_APPEND_ELT (ce, index, value);
645 CONSTRUCTOR_ELTS (ctor) = ce;
646 }
647 TREE_READONLY (ctor) = 1;
648 TREE_CONSTANT (ctor) = 1;
649 return ctor;
650 }
651 }
652
653 /* D Front end uses IntegerExp(0) to mean zero-init an array or structure. */
654 if ((tbtype->ty == Tsarray || tbtype->ty == Tstruct)
655 && ebtype->isintegral ())
656 {
657 if (!integer_zerop (expr))
658 gcc_unreachable ();
659
660 return expr;
661 }
662
663 return convert_expr (expr, etype, totype);
664 }
665
666 /* Return a TREE representation of EXPR converted to represent
667 the parameter type ARG. */
668
669 tree
670 convert_for_argument (tree expr, Parameter *arg)
671 {
672 /* Lazy arguments: expr should already be a delegate. */
673 if (arg->storageClass & STClazy)
674 return expr;
675
676 if (valist_array_p (arg->type))
677 {
678 /* Do nothing if the va_list has already been decayed to a pointer. */
679 if (!POINTER_TYPE_P (TREE_TYPE (expr)))
680 return build_address (expr);
681 }
682 else if (argument_reference_p (arg))
683 {
684 /* Front-end shouldn't automatically take the address. */
685 return convert (type_passed_as (arg), build_address (expr));
686 }
687
688 return expr;
689 }
690
691 /* Perform default promotions for data used in expressions.
692 Arrays and functions are converted to pointers;
693 enumeral types or short or char, to int.
694 In addition, manifest constants symbols are replaced by their values.
695
696 Return truth-value conversion of expression EXPR from value type TYPE. */
697
698 tree
699 convert_for_condition (tree expr, Type *type)
700 {
701 tree result = NULL_TREE;
702
703 switch (type->toBasetype ()->ty)
704 {
705 case Taarray:
706 /* Checks that aa.ptr !is null. */
707 result = component_ref (expr, TYPE_FIELDS (TREE_TYPE (expr)));
708 break;
709
710 case Tarray:
711 {
712 /* Checks (arr.length || arr.ptr) (i.e arr !is null). */
713 expr = d_save_expr (expr);
714 tree len = d_array_length (expr);
715 tree ptr = d_array_ptr (expr);
716 if (TYPE_MODE (TREE_TYPE (len)) == TYPE_MODE (TREE_TYPE (ptr)))
717 {
718 result = build2 (BIT_IOR_EXPR, TREE_TYPE (len), len,
719 d_convert (TREE_TYPE (len), ptr));
720 }
721 else
722 {
723 len = d_truthvalue_conversion (len);
724 ptr = d_truthvalue_conversion (ptr);
725 /* Probably not worth using TRUTH_OROR here. */
726 result = build2 (TRUTH_OR_EXPR, TREE_TYPE (len), len, ptr);
727 }
728 break;
729 }
730
731 case Tdelegate:
732 {
733 /* Checks (function || object), but what good is it if there is
734 a null function pointer? */
735 tree obj, func;
736 if (METHOD_CALL_EXPR (expr))
737 extract_from_method_call (expr, obj, func);
738 else
739 {
740 expr = d_save_expr (expr);
741 obj = delegate_object (expr);
742 func = delegate_method (expr);
743 }
744
745 obj = d_truthvalue_conversion (obj);
746 func = d_truthvalue_conversion (func);
747 /* Probably not worth using TRUTH_ORIF here. */
748 result = build2 (BIT_IOR_EXPR, TREE_TYPE (obj), obj, func);
749 break;
750 }
751
752 default:
753 result = expr;
754 break;
755 }
756
757 return d_truthvalue_conversion (result);
758 }
759
760
761 /* Convert EXP to a dynamic array.
762 EXP must be a static array or dynamic array. */
763
764 tree
765 d_array_convert (Expression *exp)
766 {
767 Type *tb = exp->type->toBasetype ();
768
769 if (tb->ty == Tarray)
770 return build_expr (exp);
771
772 if (tb->ty == Tsarray)
773 {
774 Type *totype = tb->nextOf ()->arrayOf ();
775 return convert_expr (build_expr (exp), exp->type, totype);
776 }
777
778 /* Invalid type passed. */
779 gcc_unreachable ();
780 }
781
782 /* Convert EXP to a dynamic array, where ETYPE is the element type.
783 Similar to above, except that EXP is allowed to be an element of an array.
784 Temporary variables that need some kind of BIND_EXPR are pushed to VARS. */
785
786 tree
787 d_array_convert (Type *etype, Expression *exp, vec<tree, va_gc> **vars)
788 {
789 Type *tb = exp->type->toBasetype ();
790
791 if ((tb->ty != Tarray && tb->ty != Tsarray) || same_type_p (tb, etype))
792 {
793 /* Convert single element to an array. */
794 tree var = NULL_TREE;
795 tree expr = maybe_temporary_var (build_expr (exp), &var);
796
797 if (var != NULL_TREE)
798 vec_safe_push (*vars, var);
799
800 return d_array_value (build_ctype (exp->type->arrayOf ()),
801 size_int (1), build_address (expr));
802 }
803 else
804 return d_array_convert (exp);
805 }