Skip several gcc.dg/builtin-dynamic-object-size tests on hppa*-*-hpux*
[official-gcc.git] / gcc / d / d-convert.cc
blob011b22ec28cf154857b629c4a43fe3e7903e1480
1 /* d-convert.cc -- Data type conversion routines.
2 Copyright (C) 2006-2024 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)
7 any later version.
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/>. */
18 #include "config.h"
19 #include "system.h"
20 #include "coretypes.h"
22 #include "dmd/aggregate.h"
23 #include "dmd/declaration.h"
24 #include "dmd/expression.h"
25 #include "dmd/mtype.h"
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"
35 #include "d-tree.h"
38 /* Build CODE expression with operands OP0 and OP1.
39 Helper function for d_truthvalue_conversion, so assumes bool result. */
41 static tree
42 d_build_truthvalue_op (tree_code code, tree op0, tree op1)
44 tree type0, type1;
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))
59 result_type = type0;
61 else if (POINTER_TYPE_P (type1) && TREE_CODE (op0) == INTEGER_CST
62 && integer_zerop (op0))
64 result_type = type1;
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))
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;
78 if (result_type)
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. */
91 bool
92 decl_with_nonnull_addr_p (const_tree expr)
94 return (DECL_P (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. */
102 tree
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)
110 return expr;
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:
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)));
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)));
131 case ERROR_MARK:
132 return expr;
134 case INTEGER_CST:
135 return integer_zerop (expr) ? d_bool_false_node
136 : d_bool_true_node;
138 case REAL_CST:
139 return real_compare (NE_EXPR, &TREE_REAL_CST (expr), &dconst0)
140 ? d_bool_true_node
141 : d_bool_false_node;
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)))
148 warning (OPT_Waddress,
149 "the address of %qD will always evaluate as %<true%>",
150 TREE_OPERAND (expr, 0));
151 return d_bool_true_node;
153 break;
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)));
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));
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)))
173 return build2 (COMPOUND_EXPR, d_bool_type, TREE_OPERAND (expr, 1),
174 d_truthvalue_conversion (TREE_OPERAND (expr, 0)));
176 else
177 return d_truthvalue_conversion (TREE_OPERAND (expr, 0));
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)));
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. */
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;
200 default:
201 break;
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)));
212 else
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. */
221 tree
222 convert (tree type, tree expr)
224 tree e = 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))
242 return 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)))
247 return expr;
249 tree ret = targetm.convert_to_type (type, expr);
250 if (ret)
251 return ret;
253 STRIP_TYPE_NOPS (e);
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 (VOID_TYPE_P (TREE_TYPE (expr)))
262 error ("void value not ignored as it ought to be");
263 return error_mark_node;
266 switch (code)
268 case VOID_TYPE:
269 return fold_convert (type, e);
271 case INTEGER_TYPE:
272 case ENUMERAL_TYPE:
273 if (POINTER_TYPE_P (etype))
275 if (integer_zerop (e))
276 return build_int_cst (type, 0);
278 /* Convert to an unsigned integer of the correct width first, and
279 from there widen/truncate to the required type. */
280 tree utype = lang_hooks.types.type_for_size (TYPE_PRECISION (etype),
282 ret = fold_build1 (CONVERT_EXPR, utype, e);
283 return fold_convert (type, ret);
286 return fold (convert_to_integer (type, e));
288 case BOOLEAN_TYPE:
289 return fold_convert (type, d_truthvalue_conversion (expr));
291 case POINTER_TYPE:
292 case REFERENCE_TYPE:
293 return fold (convert_to_pointer (type, e));
295 case REAL_TYPE:
296 if (TREE_CODE (etype) == COMPLEX_TYPE && TYPE_IMAGINARY_FLOAT (type))
297 e = build1 (IMAGPART_EXPR, TREE_TYPE (etype), e);
299 return fold (convert_to_real (type, e));
301 case COMPLEX_TYPE:
302 if (SCALAR_FLOAT_TYPE_P (etype) && TYPE_IMAGINARY_FLOAT (etype))
303 return fold_build2 (COMPLEX_EXPR, type,
304 build_zero_cst (TREE_TYPE (type)),
305 convert (TREE_TYPE (type), expr));
307 return fold (convert_to_complex (type, e));
309 case VECTOR_TYPE:
310 return fold (convert_to_vector (type, e));
312 case RECORD_TYPE:
313 case UNION_TYPE:
314 if (lang_hooks.types_compatible_p (type, TREE_TYPE (expr)))
315 return fold_build1 (VIEW_CONVERT_EXPR, type, expr);
316 break;
318 default:
319 break;
322 error ("conversion to non-scalar type requested");
323 return error_mark_node;
326 /* Return expression EXP, whose type has been converted to TYPE. */
328 tree
329 d_convert (tree type, tree exp)
331 /* Check this first before retrieving frontend type. */
332 if (error_operand_p (type) || error_operand_p (exp))
333 return error_mark_node;
335 Type *totype = TYPE_LANG_FRONTEND (type);
336 Type *etype = TYPE_LANG_FRONTEND (TREE_TYPE (exp));
338 if (totype && etype)
339 return convert_expr (exp, etype, totype);
341 return convert (type, exp);
344 /* Return expression EXP, whose type has been convert from ETYPE to TOTYPE. */
346 tree
347 convert_expr (tree exp, Type *etype, Type *totype)
349 tree result = NULL_TREE;
351 gcc_assert (etype && totype);
352 Type *ebtype = etype->toBasetype ();
353 Type *tbtype = totype->toBasetype ();
355 if (same_type_p (etype, totype))
356 return exp;
358 if (error_operand_p (exp))
359 return exp;
361 switch (ebtype->ty)
363 case TY::Tdelegate:
364 if (tbtype->ty == TY::Tdelegate)
366 exp = d_save_expr (exp);
367 return build_delegate_cst (delegate_method (exp),
368 delegate_object (exp), totype);
370 else if (tbtype->ty == TY::Tpointer)
372 /* The front-end converts <delegate>.ptr to cast (void *)<delegate>.
373 Maybe should only allow void* ? */
374 exp = delegate_object (exp);
376 else
378 error ("cannot convert a delegate expression to %qs",
379 totype->toChars ());
380 return error_mark_node;
382 break;
384 case TY::Tstruct:
385 if (tbtype->ty == TY::Tstruct)
387 if (totype->size () == etype->size ())
389 /* Allowed to cast to structs with same type size. */
390 result = build_vconvert (build_ctype (totype), exp);
392 else
394 error ("cannot convert struct %qs to %qs",
395 etype->toChars (), totype->toChars ());
396 return error_mark_node;
399 /* else, default conversion, which should produce an error. */
400 break;
402 case TY::Tclass:
403 if (tbtype->ty == TY::Tclass)
405 ClassDeclaration *cdfrom = ebtype->isClassHandle ();
406 ClassDeclaration *cdto = tbtype->isClassHandle ();
407 int offset;
409 if (cdto->isBaseOf (cdfrom, &offset) && offset != OFFSET_RUNTIME)
411 /* Casting up the inheritance tree: Don't do anything special.
412 Cast to an implemented interface: Handle at compile-time. */
413 if (offset)
415 /* Forward references should not leak from the frontend. */
416 gcc_assert (offset != OFFSET_FWDREF);
418 tree type = build_ctype (totype);
419 exp = d_save_expr (exp);
421 tree cond = build_boolop (NE_EXPR, exp, null_pointer_node);
422 tree object = build_offset (exp, size_int (offset));
424 return build_condition (build_ctype (totype), cond,
425 build_nop (type, object),
426 build_nop (type, null_pointer_node));
429 /* d_convert will make a no-op cast. */
430 break;
432 else if (cdfrom->isCPPclass () || cdto->isCPPclass ())
434 /* Downcasting in C++ is a no-op. */
435 if (cdfrom->isCPPclass () && cdto->isCPPclass ())
436 break;
438 /* Casting from a C++ interface to a class/non-C++ interface
439 always results in null as there is no run-time information,
440 and no way one can derive from the other. */
441 warning (OPT_Wcast_result, "cast to %qs will produce null result",
442 totype->toChars ());
443 result = d_convert (build_ctype (totype), null_pointer_node);
445 /* Make sure the expression is still evaluated if necessary. */
446 if (TREE_SIDE_EFFECTS (exp))
447 result = compound_expr (exp, result);
449 break;
452 /* The offset can only be determined at run-time, do dynamic cast. */
453 libcall_fn libcall = cdfrom->isInterfaceDeclaration ()
454 ? LIBCALL_INTERFACE_CAST : LIBCALL_DYNAMIC_CAST;
456 return build_libcall (libcall, totype, 2, exp,
457 build_address (get_classinfo_decl (cdto)));
459 /* else default conversion. */
460 break;
462 case TY::Tsarray:
463 if (tbtype->ty == TY::Tpointer)
465 result = build_nop (build_ctype (totype), build_address (exp));
467 else if (tbtype->ty == TY::Tarray)
469 dinteger_t dim = ebtype->isTypeSArray ()->dim->toInteger ();
470 dinteger_t esize = ebtype->nextOf ()->size ();
471 dinteger_t tsize = tbtype->nextOf ()->size ();
473 tree ptrtype = build_ctype (tbtype->nextOf ()->pointerTo ());
475 if (esize != tsize)
477 /* Array element sizes do not match, so we must adjust the
478 dimensions. */
479 if (tsize == 0 || (dim * esize) % tsize != 0)
481 error ("cannot cast %qs to %qs since sizes do not line up",
482 etype->toChars (), totype->toChars ());
483 return error_mark_node;
485 dim = (dim * esize) / tsize;
488 /* Assumes casting to dynamic array of same type or void. */
489 return d_array_value (build_ctype (totype), size_int (dim),
490 build_nop (ptrtype, build_address (exp)));
492 else if (tbtype->ty == TY::Tsarray)
494 /* D allows casting a static array to any static array type. */
495 return build_nop (build_ctype (totype), exp);
497 else if (tbtype->ty == TY::Tstruct)
499 /* And allows casting a static array to any struct type too.
500 Type sizes should have already been checked by the frontend. */
501 gcc_assert (totype->size () == etype->size ());
502 result = build_vconvert (build_ctype (totype), exp);
504 else if (tbtype->ty == TY::Tvector && tbtype->size () == ebtype->size ())
506 /* Allow casting from array to vector as if its an unaligned load. */
507 tree type = build_ctype (totype);
508 tree unaligned_type = build_variant_type_copy (type);
509 SET_TYPE_ALIGN (unaligned_type, 1 * BITS_PER_UNIT);
510 TYPE_USER_ALIGN (unaligned_type) = 1;
511 result = convert (type, build_vconvert (unaligned_type, exp));
513 else
515 error ("cannot cast expression of type %qs to type %qs",
516 etype->toChars (), totype->toChars ());
517 return error_mark_node;
519 break;
521 case TY::Tarray:
522 if (tbtype->ty == TY::Tpointer)
524 return d_convert (build_ctype (totype), d_array_ptr (exp));
526 else if (tbtype->ty == TY::Tarray)
528 /* Assume tvoid->size() == 1. */
529 dinteger_t fsize = ebtype->nextOf ()->toBasetype ()->size ();
530 dinteger_t tsize = tbtype->nextOf ()->toBasetype ()->size ();
532 if (fsize != tsize)
534 /* Conversion requires a reinterpret cast of array.
535 This case should have been lowered in the semantic pass. */
536 if (tsize != 0 && fsize % tsize == 0)
538 /* Set array dimension to (length * (fsize / tsize)). */
539 tree newlength = size_mult_expr (d_array_length (exp),
540 size_int (fsize / tsize));
541 return d_array_value (build_ctype (totype), newlength,
542 d_array_ptr (exp));
544 else
545 gcc_unreachable ();
547 else
549 /* Convert from void[] or elements are the same size
550 -- don't change length. */
551 return build_vconvert (build_ctype (totype), exp);
554 else if (tbtype->ty == TY::Tsarray)
556 /* Strings are treated as dynamic arrays in D2. */
557 if (ebtype->isString () && tbtype->isString ())
558 return indirect_ref (build_ctype (totype), d_array_ptr (exp));
560 else
562 error ("cannot cast expression of type %qs to %qs",
563 etype->toChars (), totype->toChars ());
564 return error_mark_node;
566 break;
568 case TY::Taarray:
569 if (tbtype->ty == TY::Taarray)
570 return build_vconvert (build_ctype (totype), exp);
571 /* Can convert associative arrays to void pointers. */
572 else if (tbtype->ty == TY::Tpointer && tbtype->nextOf ()->ty == TY::Tvoid)
573 return build_vconvert (build_ctype (totype), exp);
574 /* Else, default conversion, which should product an error. */
575 break;
577 case TY::Tpointer:
578 /* Can convert void pointers to associative arrays too. */
579 if (tbtype->ty == TY::Taarray && ebtype->nextOf ()->ty == TY::Tvoid)
580 return build_vconvert (build_ctype (totype), exp);
581 break;
583 case TY::Tnull:
584 case TY::Tnoreturn:
585 /* Casting from `typeof(null)' for `null' expressions, or `typeof(*null)'
586 for `noreturn' expressions is represented as all zeros. */
587 result = build_typeof_null_value (totype);
589 /* Make sure the expression is still evaluated if necessary. */
590 if (TREE_SIDE_EFFECTS (exp))
591 result = compound_expr (exp, result);
592 break;
594 case TY::Tvector:
595 if (tbtype->ty == TY::Tsarray)
597 if (tbtype->size () == ebtype->size ())
598 return build_vconvert (build_ctype (totype), exp);
600 break;
602 default:
603 /* All casts between imaginary and non-imaginary result in 0.0,
604 except for casts between complex and imaginary types. */
605 if (!ebtype->iscomplex () && !tbtype->iscomplex ()
606 && (ebtype->isimaginary () != tbtype->isimaginary ()))
608 warning (OPT_Wcast_result,
609 "cast from %qs to %qs will produce zero result",
610 ebtype->toChars (), tbtype->toChars ());
612 return compound_expr (exp, build_zero_cst (build_ctype (tbtype)));
615 gcc_assert (TREE_CODE (exp) != STRING_CST);
616 break;
619 return result ? result : convert (build_ctype (totype), exp);
622 /* Return a TREE representation of EXPR, whose type has been converted from
623 * ETYPE to TOTYPE, and is being used in an rvalue context. */
625 tree
626 convert_for_rvalue (tree expr, Type *etype, Type *totype)
628 tree result = NULL_TREE;
630 Type *ebtype = etype->toBasetype ();
631 Type *tbtype = totype->toBasetype ();
633 if (ebtype->ty == TY::Tbool)
635 /* If casting from bool, the result is either 0 or 1, any other value
636 violates @safe code, so enforce that it is never invalid. */
637 for (tree ref = expr; TREE_CODE (ref) == COMPONENT_REF;
638 ref = TREE_OPERAND (ref, 0))
640 /* If the expression is a field that's part of a union, reinterpret
641 the boolean as an integer and test the first bit. The generated
642 code should end up being equivalent to:
643 *cast(ubyte *)&expr & 1; */
644 if (TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 0))) == UNION_TYPE)
646 machine_mode bool_mode = TYPE_MODE (TREE_TYPE (expr));
647 tree mtype = lang_hooks.types.type_for_mode (bool_mode, 1);
648 result = fold_build2 (BIT_AND_EXPR, mtype,
649 build_vconvert (mtype, expr),
650 build_one_cst (mtype));
651 break;
655 if (result == NULL_TREE)
656 result = d_truthvalue_conversion (expr);
658 result = convert (build_ctype (tbtype), result);
661 if (tbtype->ty == TY::Tsarray
662 && ebtype->ty == TY::Tsarray
663 && tbtype->nextOf ()->ty == ebtype->nextOf ()->ty
664 && INDIRECT_REF_P (expr)
665 && CONVERT_EXPR_P (TREE_OPERAND (expr, 0))
666 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (expr, 0), 0)) == ADDR_EXPR)
668 /* If expression is a vector that was casted to an array either by
669 explicit type cast or by taking the vector's `.array' value, strip the
670 reinterpret cast and build a constructor instead. */
671 tree ptr = TREE_OPERAND (TREE_OPERAND (expr, 0), 0);
673 if (VECTOR_TYPE_P (TREE_TYPE (TREE_TYPE (ptr))))
675 /* Rewrite: `*(Array *)&vector'
676 into: `{ vector[0], vector[1], ... }' */
677 tree array = d_save_expr (TREE_OPERAND (ptr, 0));
678 array = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (expr), array);
680 uinteger_t dim = tbtype->isTypeSArray ()->dim->toUInteger ();
681 vec <constructor_elt, va_gc> *elms = NULL;
682 for (uinteger_t i = 0; i < dim; i++)
684 tree index = size_int (i);
685 tree value = build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (array)),
686 array, index, NULL_TREE, NULL_TREE);
687 CONSTRUCTOR_APPEND_ELT (elms, index, value);
690 return build_constructor (build_ctype (totype), elms);
694 return result ? result : convert_expr (expr, etype, totype);
697 /* Helper for convert_for_assigment and convert_for_argument.
698 Returns true if EXPR is a va_list static array parameter. */
700 static bool
701 is_valist_parameter_type (Expression *expr)
703 Declaration *decl = NULL;
705 if (VarExp *ve = expr->isVarExp ())
706 decl = ve->var;
707 else if (SymOffExp *se = expr->isSymOffExp ())
708 decl = se->var;
710 if (decl != NULL && decl->isParameter () && valist_array_p (decl->type))
711 return true;
713 return false;
716 /* Helper for convert_for_assigment and convert_for_argument.
717 Report erroneous uses of assigning or passing a va_list parameter. */
719 static void
720 check_valist_conversion (Expression *expr, Type *totype, bool in_assignment)
722 /* Parameter symbol and its converted type. */
723 Declaration *decl = NULL;
724 /* Type of parameter when evaluated in the expression. */
725 Type *type = NULL;
727 if (VarExp *ve = expr->isVarExp ())
729 decl = ve->var;
730 type = ve->var->type->nextOf ()->pointerTo ();
732 else if (SymOffExp *se = expr->isSymOffExp ())
734 decl = se->var;
735 type = se->var->type->nextOf ()->pointerTo ()->pointerTo ();
738 /* Should not be called unless is_valist_parameter_type also matched. */
739 gcc_assert (decl != NULL && decl->isParameter ()
740 && valist_array_p (decl->type));
742 /* OK if conversion between types is allowed. */
743 if (type->implicitConvTo (totype) != MATCH::nomatch)
744 return;
746 if (in_assignment)
748 error_at (make_location_t (expr->loc), "cannot convert parameter %qs "
749 "from type %qs to type %qs in assignment",
750 expr->toChars(), type->toChars (), totype->toChars ());
752 else
754 error_at (make_location_t (expr->loc), "cannot convert parameter %qs "
755 "from type %qs to type %qs in argument passing",
756 expr->toChars(), type->toChars (), totype->toChars ());
759 inform (make_location_t (decl->loc), "parameters of type %<va_list%> "
760 "{aka %qs} are decayed to pointer types, and require %<va_copy%> "
761 "to be converted back into a static array type",
762 decl->type->toChars ());
765 /* Apply semantics of assignment to a value of type TOTYPE to EXPR
766 For example: `pointer = array' gets lowered to `pointer = &array[0]'.
767 If LITERALP is true, then EXPR is a value used in the initialization
768 of another literal.
770 Return a TREE representation of EXPR implicitly converted to TOTYPE
771 for use in assignment expressions MODIFY_EXPR, INIT_EXPR. */
773 tree
774 convert_for_assignment (Expression *expr, Type *totype, bool literalp)
776 Type *ebtype = expr->type->toBasetype ();
777 Type *tbtype = totype->toBasetype ();
779 /* Assuming this only has to handle converting a non Tsarray type to
780 arbitrarily dimensioned Tsarrays. */
781 if (tbtype->ty == TY::Tsarray)
783 Type *telem = tbtype->nextOf ()->baseElemOf ();
785 if (same_type_p (telem, ebtype))
787 TypeSArray *sa_type = tbtype->isTypeSArray ();
788 uinteger_t count = sa_type->dim->toUInteger ();
790 tree ctor = build_constructor (build_ctype (totype), NULL);
791 if (count)
793 vec <constructor_elt, va_gc> *ce = NULL;
794 tree index = build2 (RANGE_EXPR, build_ctype (Type::tsize_t),
795 size_zero_node, size_int (count - 1));
796 tree value = convert_for_assignment (expr, sa_type->next,
797 literalp);
798 /* Can't use VAR_DECLs in CONSTRUCTORS. */
799 if (VAR_P (value))
801 value = DECL_INITIAL (value);
802 gcc_assert (value);
805 CONSTRUCTOR_APPEND_ELT (ce, index, value);
806 CONSTRUCTOR_ELTS (ctor) = ce;
808 TREE_READONLY (ctor) = 1;
809 TREE_CONSTANT (ctor) = 1;
810 return ctor;
814 /* D Front end uses IntegerExp(0) to mean zero-init an array or structure. */
815 if ((tbtype->ty == TY::Tsarray || tbtype->ty == TY::Tstruct)
816 && ebtype->isintegral ())
818 tree ret = build_expr (expr, false, literalp);
819 gcc_assert (integer_zerop (ret));
820 return ret;
823 /* Assigning a va_list by value or reference, check whether RHS is a parameter
824 that has has been lowered by declaration_type or parameter_type. */
825 if (is_valist_parameter_type (expr))
826 check_valist_conversion (expr, totype, true);
828 return convert_for_rvalue (build_expr (expr, false, literalp),
829 expr->type, totype);
832 /* Return a TREE representation of EXPR converted to represent
833 the parameter type ARG. */
835 tree
836 convert_for_argument (Expression *expr, Parameter *arg)
838 tree targ = build_expr (expr);
840 /* Lazy arguments: expr should already be a delegate. */
841 if (arg->storageClass & STClazy)
842 return targ;
844 /* Passing a va_list by value, check whether the target requires it to
845 be decayed to a pointer type. */
846 if (valist_array_p (arg->type))
848 if (!POINTER_TYPE_P (TREE_TYPE (targ)))
849 return build_address (targ);
851 /* Do nothing if the va_list has already been converted. */
852 return targ;
855 /* Passing a va_list by reference, check if types are really compatible
856 after conversion from static array to pointer type. */
857 if (is_valist_parameter_type (expr))
858 check_valist_conversion (expr, arg->type, false);
860 /* Front-end shouldn't automatically take the address of `ref' parameters. */
861 if (parameter_reference_p (arg))
862 return convert (parameter_type (arg), build_address (targ));
864 return targ;
867 /* Perform default promotions for data used in expressions.
868 Arrays and functions are converted to pointers;
869 enumeral types or short or char, to int.
870 In addition, manifest constants symbols are replaced by their values.
872 Return truth-value conversion of expression EXPR from value type TYPE. */
874 tree
875 convert_for_condition (tree expr, Type *type)
877 tree result = NULL_TREE;
879 switch (type->toBasetype ()->ty)
881 case TY::Taarray:
882 /* Checks that aa.ptr !is null. */
883 result = component_ref (expr, TYPE_FIELDS (TREE_TYPE (expr)));
884 break;
886 case TY::Tarray:
888 /* Checks (arr.length || arr.ptr) (i.e arr !is null). */
889 expr = d_save_expr (expr);
890 tree len = d_array_length (expr);
891 tree ptr = d_array_ptr (expr);
892 if (TYPE_MODE (TREE_TYPE (len)) == TYPE_MODE (TREE_TYPE (ptr)))
894 result = build2 (BIT_IOR_EXPR, TREE_TYPE (len), len,
895 d_convert (TREE_TYPE (len), ptr));
897 else
899 len = d_truthvalue_conversion (len);
900 ptr = d_truthvalue_conversion (ptr);
901 /* Probably not worth using TRUTH_OROR here. */
902 result = build2 (TRUTH_OR_EXPR, TREE_TYPE (len), len, ptr);
904 break;
907 case TY::Tdelegate:
909 /* Checks (function || object), but what good is it if there is
910 a null function pointer? */
911 tree obj, func;
912 if (METHOD_CALL_EXPR (expr))
913 extract_from_method_call (expr, obj, func);
914 else
916 expr = d_save_expr (expr);
917 obj = delegate_object (expr);
918 func = delegate_method (expr);
921 obj = d_truthvalue_conversion (obj);
922 func = d_truthvalue_conversion (func);
923 /* Probably not worth using TRUTH_ORIF here. */
924 result = build2 (BIT_IOR_EXPR, TREE_TYPE (obj), obj, func);
925 break;
928 case TY::Tnoreturn:
929 /* Front-end allows conditionals that never return, represent the
930 conditional result value as all zeros. */
931 result = build_zero_cst (d_bool_type);
933 /* Make sure the expression is still evaluated if necessary. */
934 if (TREE_SIDE_EFFECTS (expr))
935 result = compound_expr (expr, result);
936 break;
938 default:
939 result = convert_for_rvalue (expr, type, type);
940 break;
943 return d_truthvalue_conversion (result);
947 /* Convert EXP to a dynamic array.
948 EXP must be a static array or dynamic array. */
950 tree
951 d_array_convert (Expression *exp)
953 Type *tb = exp->type->toBasetype ();
955 if (tb->ty == TY::Tarray)
956 return build_expr (exp);
958 if (tb->ty == TY::Tsarray)
960 Type *totype = tb->nextOf ()->arrayOf ();
961 return convert_expr (build_expr (exp), exp->type, totype);
964 /* Invalid type passed. */
965 gcc_unreachable ();
968 /* Convert EXP to a dynamic array, where ETYPE is the element type.
969 Similar to above, except that EXP is allowed to be an element of an array.
970 Temporary variables are created inline if EXP is not an lvalue. */
972 tree
973 d_array_convert (Type *etype, Expression *exp)
975 Type *tb = exp->type->toBasetype ();
977 if ((tb->ty != TY::Tarray && tb->ty != TY::Tsarray)
978 || same_type_p (tb, etype))
980 /* Convert single element to an array. */
981 tree expr = build_expr (exp);
983 if (!exp->isLvalue ())
985 tree var = build_local_temp (TREE_TYPE (expr));
986 expr = compound_expr (modify_expr (var, expr), var);
989 return d_array_value (build_ctype (exp->type->arrayOf ()),
990 size_int (1), build_address (expr));
992 else
993 return d_array_convert (exp);