1 /* d-convert.cc -- Data type conversion routines.
2 Copyright (C) 2006-2021 Free Software Foundation, Inc.
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)
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.
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/>. */
20 #include "coretypes.h"
22 #include "dmd/aggregate.h"
23 #include "dmd/declaration.h"
24 #include "dmd/expression.h"
25 #include "dmd/mtype.h"
28 #include "fold-const.h"
29 #include "diagnostic.h"
30 #include "langhooks.h"
33 #include "stor-layout.h"
38 /* Build CODE expression with operands OP0 and OP1.
39 Helper function for d_truthvalue_conversion, so assumes bool result. */
42 d_build_truthvalue_op (tree_code code
, tree op0
, tree op1
)
46 tree result_type
= NULL_TREE
;
48 type0
= TREE_TYPE (op0
);
49 type1
= TREE_TYPE (op1
);
51 /* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue. */
52 STRIP_TYPE_NOPS (op0
);
53 STRIP_TYPE_NOPS (op1
);
55 /* Also need to convert pointer/int comparison. */
56 if (POINTER_TYPE_P (type0
) && TREE_CODE (op1
) == INTEGER_CST
57 && integer_zerop (op1
))
61 else if (POINTER_TYPE_P (type1
) && TREE_CODE (op0
) == INTEGER_CST
62 && integer_zerop (op0
))
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
))
70 if (TYPE_PRECISION (type0
) > TYPE_PRECISION (type1
))
72 else if (TYPE_PRECISION (type0
) < TYPE_PRECISION (type1
))
74 else if (TYPE_UNSIGNED (type0
) != TYPE_UNSIGNED (type1
))
75 result_type
= TYPE_UNSIGNED (type0
) ? type0
: type1
;
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
);
86 return fold_build2 (code
, d_bool_type
, op0
, op1
);
89 /* Return whether EXPR is a declaration whose address can never be NULL. */
92 decl_with_nonnull_addr_p (const_tree expr
)
95 && (TREE_CODE (expr
) == PARM_DECL
96 || TREE_CODE (expr
) == LABEL_DECL
97 || !DECL_WEAK (expr
)));
100 /* Convert EXPR to be a truth-value, validating its type for this purpose. */
103 d_truthvalue_conversion (tree expr
)
105 switch (TREE_CODE (expr
))
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
)
111 return build2 (TREE_CODE (expr
), d_bool_type
,
112 TREE_OPERAND (expr
, 0), TREE_OPERAND (expr
, 1));
114 case TRUTH_ANDIF_EXPR
:
115 case TRUTH_ORIF_EXPR
:
119 if (TREE_TYPE (expr
) == d_bool_type
)
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)));
126 if (TREE_TYPE (expr
) == d_bool_type
)
128 return build1 (TREE_CODE (expr
), d_bool_type
,
129 d_truthvalue_conversion (TREE_OPERAND (expr
, 0)));
135 return integer_zerop (expr
) ? boolean_false_node
139 return real_compare (NE_EXPR
, &TREE_REAL_CST (expr
), &dconst0
)
141 : boolean_false_node
;
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)))
148 warning (OPT_Waddress
,
149 "the address of %qD will always evaluate as %<true%>",
150 TREE_OPERAND (expr
, 0));
151 return boolean_true_node
;
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)));
164 /* These don't change whether an object is nonzero or zero. */
165 return d_truthvalue_conversion (TREE_OPERAND (expr
, 0));
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)))
173 return build2 (COMPOUND_EXPR
, d_bool_type
, TREE_OPERAND (expr
, 1),
174 d_truthvalue_conversion (TREE_OPERAND (expr
, 0)));
177 return d_truthvalue_conversion (TREE_OPERAND (expr
, 0));
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)));
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
)
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));
204 if (TREE_CODE (TREE_TYPE (expr
)) == COMPLEX_TYPE
)
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
)));
213 return d_build_truthvalue_op (NE_EXPR
, expr
,
214 build_zero_cst (TREE_TYPE (expr
)));
218 /* Creates an expression whose value is that of EXPR, converted to type TYPE.
219 This function implements all reasonable scalar conversions. */
222 convert (tree type
, tree expr
)
225 tree_code code
= TREE_CODE (type
);
227 if (type
== error_mark_node
228 || expr
== error_mark_node
229 || TREE_TYPE (expr
) == error_mark_node
)
230 return error_mark_node
;
232 const char *invalid_conv_diag
233 = targetm
.invalid_conversion (TREE_TYPE (expr
), type
);
235 if (invalid_conv_diag
)
237 error ("%s", invalid_conv_diag
);
238 return error_mark_node
;
241 if (type
== TREE_TYPE (expr
))
244 if (TREE_CODE (type
) == ARRAY_TYPE
245 && TREE_CODE (TREE_TYPE (expr
)) == ARRAY_TYPE
246 && TYPE_DOMAIN (type
) == TYPE_DOMAIN (TREE_TYPE (expr
)))
249 tree ret
= targetm
.convert_to_type (type
, expr
);
254 tree etype
= TREE_TYPE (e
);
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
)
262 error ("void value not ignored as it ought to be");
263 return error_mark_node
;
269 return fold_convert (type
, e
);
273 if (TREE_CODE (etype
) == POINTER_TYPE
274 || TREE_CODE (etype
) == REFERENCE_TYPE
)
276 if (integer_zerop (e
))
277 return build_int_cst (type
, 0);
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
),
283 ret
= fold_build1 (CONVERT_EXPR
, utype
, e
);
284 return fold_convert (type
, ret
);
287 return fold (convert_to_integer (type
, e
));
290 return fold_convert (type
, d_truthvalue_conversion (expr
));
294 return fold (convert_to_pointer (type
, e
));
297 if (TREE_CODE (etype
) == COMPLEX_TYPE
&& TYPE_IMAGINARY_FLOAT (type
))
298 e
= build1 (IMAGPART_EXPR
, TREE_TYPE (etype
), e
);
300 return fold (convert_to_real (type
, e
));
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
));
308 return fold (convert_to_complex (type
, e
));
311 return fold (convert_to_vector (type
, e
));
315 if (lang_hooks
.types_compatible_p (type
, TREE_TYPE (expr
)))
316 return fold_build1 (VIEW_CONVERT_EXPR
, type
, expr
);
323 error ("conversion to non-scalar type requested");
324 return error_mark_node
;
327 /* Return expression EXP, whose type has been converted to TYPE. */
330 d_convert (tree type
, tree exp
)
332 /* Check this first before retrieving frontend type. */
333 if (error_operand_p (type
) || error_operand_p (exp
))
334 return error_mark_node
;
336 Type
*totype
= TYPE_LANG_FRONTEND (type
);
337 Type
*etype
= TYPE_LANG_FRONTEND (TREE_TYPE (exp
));
340 return convert_expr (exp
, etype
, totype
);
342 return convert (type
, exp
);
345 /* Return expression EXP, whose type has been convert from ETYPE to TOTYPE. */
348 convert_expr (tree exp
, Type
*etype
, Type
*totype
)
350 tree result
= NULL_TREE
;
352 gcc_assert (etype
&& totype
);
353 Type
*ebtype
= etype
->toBasetype ();
354 Type
*tbtype
= totype
->toBasetype ();
356 if (same_type_p (etype
, totype
))
359 if (error_operand_p (exp
))
365 if (tbtype
->ty
== Tdelegate
)
367 exp
= d_save_expr (exp
);
368 return build_delegate_cst (delegate_method (exp
),
369 delegate_object (exp
), totype
);
371 else if (tbtype
->ty
== Tpointer
)
373 /* The front-end converts <delegate>.ptr to cast (void *)<delegate>.
374 Maybe should only allow void* ? */
375 exp
= delegate_object (exp
);
379 error ("cannot convert a delegate expression to %qs",
381 return error_mark_node
;
386 if (tbtype
->ty
== Tstruct
)
388 if (totype
->size () == etype
->size ())
390 /* Allowed to cast to structs with same type size. */
391 result
= build_vconvert (build_ctype (totype
), exp
);
395 error ("cannot convert struct %qs to %qs",
396 etype
->toChars (), totype
->toChars ());
397 return error_mark_node
;
400 /* else, default conversion, which should produce an error. */
404 if (tbtype
->ty
== Tclass
)
406 ClassDeclaration
*cdfrom
= ebtype
->isClassHandle ();
407 ClassDeclaration
*cdto
= tbtype
->isClassHandle ();
410 if (cdto
->isBaseOf (cdfrom
, &offset
) && offset
!= OFFSET_RUNTIME
)
412 /* Casting up the inheritance tree: Don't do anything special.
413 Cast to an implemented interface: Handle at compile-time. */
416 /* Forward references should not leak from the frontend. */
417 gcc_assert (offset
!= OFFSET_FWDREF
);
419 tree type
= build_ctype (totype
);
420 exp
= d_save_expr (exp
);
422 tree cond
= build_boolop (NE_EXPR
, exp
, null_pointer_node
);
423 tree object
= build_offset (exp
, size_int (offset
));
425 return build_condition (build_ctype (totype
), cond
,
426 build_nop (type
, object
),
427 build_nop (type
, null_pointer_node
));
430 /* d_convert will make a no-op cast. */
433 else if (cdfrom
->isCPPclass () || cdto
->isCPPclass ())
435 /* Downcasting in C++ is a no-op. */
436 if (cdfrom
->isCPPclass () && cdto
->isCPPclass ())
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",
444 result
= d_convert (build_ctype (totype
), null_pointer_node
);
446 /* Make sure the expression is still evaluated if necessary. */
447 if (TREE_SIDE_EFFECTS (exp
))
448 result
= compound_expr (exp
, result
);
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
;
457 return build_libcall (libcall
, totype
, 2, exp
,
458 build_address (get_classinfo_decl (cdto
)));
460 /* else default conversion. */
464 if (tbtype
->ty
== Tpointer
)
466 result
= build_nop (build_ctype (totype
), build_address (exp
));
468 else if (tbtype
->ty
== Tarray
)
470 dinteger_t dim
= ebtype
->isTypeSArray ()->dim
->toInteger ();
471 dinteger_t esize
= ebtype
->nextOf ()->size ();
472 dinteger_t tsize
= tbtype
->nextOf ()->size ();
474 tree ptrtype
= build_ctype (tbtype
->nextOf ()->pointerTo ());
478 /* Array element sizes do not match, so we must adjust the
480 if (tsize
== 0 || (dim
* esize
) % tsize
!= 0)
482 error ("cannot cast %qs to %qs since sizes do not line up",
483 etype
->toChars (), totype
->toChars ());
484 return error_mark_node
;
486 dim
= (dim
* esize
) / tsize
;
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
)));
493 else if (tbtype
->ty
== Tsarray
)
495 /* D allows casting a static array to any static array type. */
496 return build_nop (build_ctype (totype
), exp
);
498 else if (tbtype
->ty
== Tstruct
)
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
);
507 error ("cannot cast expression of type %qs to type %qs",
508 etype
->toChars (), totype
->toChars ());
509 return error_mark_node
;
514 if (tbtype
->ty
== Tpointer
)
516 return d_convert (build_ctype (totype
), d_array_ptr (exp
));
518 else if (tbtype
->ty
== Tarray
)
520 /* Assume tvoid->size() == 1. */
521 d_uns64 fsize
= ebtype
->nextOf ()->toBasetype ()->size ();
522 d_uns64 tsize
= tbtype
->nextOf ()->toBasetype ()->size ();
526 /* Conversion requires a reinterpret cast of array. */
527 return build_libcall (LIBCALL_ARRAYCAST
, totype
, 3,
528 size_int (tsize
), size_int (fsize
), exp
);
532 /* Convert from void[] or elements are the same size
533 -- don't change length. */
534 return build_vconvert (build_ctype (totype
), exp
);
537 else if (tbtype
->ty
== Tsarray
)
539 /* Strings are treated as dynamic arrays in D2. */
540 if (ebtype
->isString () && tbtype
->isString ())
541 return indirect_ref (build_ctype (totype
), d_array_ptr (exp
));
545 error ("cannot cast expression of type %qs to %qs",
546 etype
->toChars (), totype
->toChars ());
547 return error_mark_node
;
552 if (tbtype
->ty
== Taarray
)
553 return build_vconvert (build_ctype (totype
), exp
);
554 /* Can convert associative arrays to void pointers. */
555 else if (tbtype
->ty
== Tpointer
&& tbtype
->nextOf ()->ty
== Tvoid
)
556 return build_vconvert (build_ctype (totype
), exp
);
557 /* Else, default conversion, which should product an error. */
561 /* Can convert void pointers to associative arrays too. */
562 if (tbtype
->ty
== Taarray
&& ebtype
->nextOf ()->ty
== Tvoid
)
563 return build_vconvert (build_ctype (totype
), exp
);
568 /* Casting from `typeof(null)' for `null' expressions, or `typeof(*null)'
569 for `noreturn' expressions is represented as all zeros. */
570 result
= build_typeof_null_value (totype
);
572 /* Make sure the expression is still evaluated if necessary. */
573 if (TREE_SIDE_EFFECTS (exp
))
574 result
= compound_expr (exp
, result
);
578 if (tbtype
->ty
== Tsarray
)
580 if (tbtype
->size () == ebtype
->size ())
581 return build_vconvert (build_ctype (totype
), exp
);
586 /* All casts between imaginary and non-imaginary result in 0.0,
587 except for casts between complex and imaginary types. */
588 if (!ebtype
->iscomplex () && !tbtype
->iscomplex ()
589 && (ebtype
->isimaginary () != tbtype
->isimaginary ()))
591 warning (OPT_Wcast_result
,
592 "cast from %qs to %qs will produce zero result",
593 ebtype
->toChars (), tbtype
->toChars ());
595 return compound_expr (exp
, build_zero_cst (build_ctype (tbtype
)));
598 gcc_assert (TREE_CODE (exp
) != STRING_CST
);
602 return result
? result
: convert (build_ctype (totype
), exp
);
605 /* Return a TREE represenwation of EXPR, whose type has been converted from
606 * ETYPE to TOTYPE, and is being used in an rvalue context. */
609 convert_for_rvalue (tree expr
, Type
*etype
, Type
*totype
)
611 tree result
= NULL_TREE
;
613 Type
*ebtype
= etype
->toBasetype ();
614 Type
*tbtype
= totype
->toBasetype ();
616 if (ebtype
->ty
== Tbool
)
618 /* If casting from bool, the result is either 0 or 1, any other value
619 violates @safe code, so enforce that it is never invalid. */
620 if (CONSTANT_CLASS_P (expr
))
621 result
= d_truthvalue_conversion (expr
);
624 /* Reinterpret the boolean as an integer and test the first bit.
625 The generated code should end up being equivalent to:
626 *cast(ubyte *)&expr & 1; */
627 machine_mode bool_mode
= TYPE_MODE (TREE_TYPE (expr
));
628 tree mtype
= lang_hooks
.types
.type_for_mode (bool_mode
, 1);
629 result
= fold_build2 (BIT_AND_EXPR
, mtype
,
630 build_vconvert (mtype
, expr
),
631 build_one_cst (mtype
));
634 result
= convert (build_ctype (tbtype
), result
);
637 return result
? result
: convert_expr (expr
, etype
, totype
);
640 /* Apply semantics of assignment to a value of type TOTYPE to EXPR
641 (e.g., pointer = array -> pointer = &array[0])
643 Return a TREE representation of EXPR implicitly converted to TOTYPE
644 for use in assignment expressions MODIFY_EXPR, INIT_EXPR. */
647 convert_for_assignment (tree expr
, Type
*etype
, Type
*totype
)
649 Type
*ebtype
= etype
->toBasetype ();
650 Type
*tbtype
= totype
->toBasetype ();
652 /* Assuming this only has to handle converting a non Tsarray type to
653 arbitrarily dimensioned Tsarrays. */
654 if (tbtype
->ty
== Tsarray
)
656 Type
*telem
= tbtype
->nextOf ()->baseElemOf ();
658 if (same_type_p (telem
, ebtype
))
660 TypeSArray
*sa_type
= tbtype
->isTypeSArray ();
661 uinteger_t count
= sa_type
->dim
->toUInteger ();
663 tree ctor
= build_constructor (build_ctype (totype
), NULL
);
666 vec
<constructor_elt
, va_gc
> *ce
= NULL
;
667 tree index
= build2 (RANGE_EXPR
, build_ctype (Type::tsize_t
),
668 size_zero_node
, size_int (count
- 1));
669 tree value
= convert_for_assignment (expr
, etype
, sa_type
->next
);
671 /* Can't use VAR_DECLs in CONSTRUCTORS. */
674 value
= DECL_INITIAL (value
);
678 CONSTRUCTOR_APPEND_ELT (ce
, index
, value
);
679 CONSTRUCTOR_ELTS (ctor
) = ce
;
681 TREE_READONLY (ctor
) = 1;
682 TREE_CONSTANT (ctor
) = 1;
687 /* D Front end uses IntegerExp(0) to mean zero-init an array or structure. */
688 if ((tbtype
->ty
== Tsarray
|| tbtype
->ty
== Tstruct
)
689 && ebtype
->isintegral ())
691 if (!integer_zerop (expr
))
697 return convert_expr (expr
, etype
, totype
);
700 /* Return a TREE representation of EXPR converted to represent
701 the parameter type ARG. */
704 convert_for_argument (tree expr
, Parameter
*arg
)
706 /* Lazy arguments: expr should already be a delegate. */
707 if (arg
->storageClass
& STClazy
)
710 if (valist_array_p (arg
->type
))
712 /* Do nothing if the va_list has already been decayed to a pointer. */
713 if (!POINTER_TYPE_P (TREE_TYPE (expr
)))
714 return build_address (expr
);
716 else if (parameter_reference_p (arg
))
718 /* Front-end shouldn't automatically take the address. */
719 return convert (parameter_type (arg
), build_address (expr
));
725 /* Perform default promotions for data used in expressions.
726 Arrays and functions are converted to pointers;
727 enumeral types or short or char, to int.
728 In addition, manifest constants symbols are replaced by their values.
730 Return truth-value conversion of expression EXPR from value type TYPE. */
733 convert_for_condition (tree expr
, Type
*type
)
735 tree result
= NULL_TREE
;
737 switch (type
->toBasetype ()->ty
)
740 /* Checks that aa.ptr !is null. */
741 result
= component_ref (expr
, TYPE_FIELDS (TREE_TYPE (expr
)));
746 /* Checks (arr.length || arr.ptr) (i.e arr !is null). */
747 expr
= d_save_expr (expr
);
748 tree len
= d_array_length (expr
);
749 tree ptr
= d_array_ptr (expr
);
750 if (TYPE_MODE (TREE_TYPE (len
)) == TYPE_MODE (TREE_TYPE (ptr
)))
752 result
= build2 (BIT_IOR_EXPR
, TREE_TYPE (len
), len
,
753 d_convert (TREE_TYPE (len
), ptr
));
757 len
= d_truthvalue_conversion (len
);
758 ptr
= d_truthvalue_conversion (ptr
);
759 /* Probably not worth using TRUTH_OROR here. */
760 result
= build2 (TRUTH_OR_EXPR
, TREE_TYPE (len
), len
, ptr
);
767 /* Checks (function || object), but what good is it if there is
768 a null function pointer? */
770 if (METHOD_CALL_EXPR (expr
))
771 extract_from_method_call (expr
, obj
, func
);
774 expr
= d_save_expr (expr
);
775 obj
= delegate_object (expr
);
776 func
= delegate_method (expr
);
779 obj
= d_truthvalue_conversion (obj
);
780 func
= d_truthvalue_conversion (func
);
781 /* Probably not worth using TRUTH_ORIF here. */
782 result
= build2 (BIT_IOR_EXPR
, TREE_TYPE (obj
), obj
, func
);
787 /* Front-end allows conditionals that never return, represent the
788 conditional result value as all zeros. */
789 result
= build_zero_cst (d_bool_type
);
791 /* Make sure the expression is still evaluated if necessary. */
792 if (TREE_SIDE_EFFECTS (expr
))
793 result
= compound_expr (expr
, result
);
801 return d_truthvalue_conversion (result
);
805 /* Convert EXP to a dynamic array.
806 EXP must be a static array or dynamic array. */
809 d_array_convert (Expression
*exp
)
811 Type
*tb
= exp
->type
->toBasetype ();
813 if (tb
->ty
== Tarray
)
814 return build_expr (exp
);
816 if (tb
->ty
== Tsarray
)
818 Type
*totype
= tb
->nextOf ()->arrayOf ();
819 return convert_expr (build_expr (exp
), exp
->type
, totype
);
822 /* Invalid type passed. */
826 /* Convert EXP to a dynamic array, where ETYPE is the element type.
827 Similar to above, except that EXP is allowed to be an element of an array.
828 Temporary variables are created inline if EXP is not an lvalue. */
831 d_array_convert (Type
*etype
, Expression
*exp
)
833 Type
*tb
= exp
->type
->toBasetype ();
835 if ((tb
->ty
!= Tarray
&& tb
->ty
!= Tsarray
) || same_type_p (tb
, etype
))
837 /* Convert single element to an array. */
838 tree expr
= build_expr (exp
);
840 if (!exp
->isLvalue ())
842 tree var
= build_local_temp (TREE_TYPE (expr
));
843 expr
= compound_expr (modify_expr (var
, expr
), var
);
846 return d_array_value (build_ctype (exp
->type
->arrayOf ()),
847 size_int (1), build_address (expr
));
850 return d_array_convert (exp
);