1/* d-convert.cc -- Data type conversion routines.
2   Copyright (C) 2006-2020 Free Software Foundation, Inc.
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:
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
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    {
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 ("cannot 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 ("cannot 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 (esize != tsize)
477	    {
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;
487	    }
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	}
493      else if (tbtype->ty == Tsarray)
494	{
495	  /* D allows casting a static array to any static array type.  */
496	  return build_nop (build_ctype (totype), exp);
497	}
498      else if (tbtype->ty == Tstruct)
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	}
505      else if (tbtype->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	}
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
522    case Tarray:
523      if (tbtype->ty == Tpointer)
524	{
525	  return d_convert (build_ctype (totype), d_array_ptr (exp));
526	}
527      else if (tbtype->ty == Tarray)
528	{
529	  /* Assume tvoid->size() == 1.  */
530	  d_uns64 fsize = ebtype->nextOf ()->toBasetype ()->size ();
531	  d_uns64 tsize = tbtype->nextOf ()->toBasetype ()->size ();
532
533	  if (fsize != tsize)
534	    {
535	      /* Conversion requires a reinterpret cast of array.  */
536	      return build_libcall (LIBCALL_ARRAYCAST, totype, 3,
537				    size_int (tsize), size_int (fsize), exp);
538	    }
539	  else
540	    {
541	      /* Convert from void[] or elements are the same size
542		 -- don't change length.  */
543	      return build_vconvert (build_ctype (totype), exp);
544	    }
545	}
546      else if (tbtype->ty == Tsarray)
547	{
548	  /* Strings are treated as dynamic arrays in D2.  */
549	  if (ebtype->isString () && tbtype->isString ())
550	    return indirect_ref (build_ctype (totype), d_array_ptr (exp));
551	}
552      else
553	{
554	  error ("cannot cast expression of type %qs to %qs",
555		 etype->toChars (), totype->toChars ());
556	  return error_mark_node;
557	}
558      break;
559
560    case Taarray:
561      if (tbtype->ty == Taarray)
562	return build_vconvert (build_ctype (totype), exp);
563      /* Can convert associative arrays to void pointers.  */
564      else if (tbtype->ty == Tpointer && tbtype->nextOf ()->ty == Tvoid)
565	return build_vconvert (build_ctype (totype), exp);
566      /* Else, default conversion, which should product an error.  */
567      break;
568
569    case Tpointer:
570      /* Can convert void pointers to associative arrays too.  */
571      if (tbtype->ty == Taarray && ebtype->nextOf ()->ty == Tvoid)
572	return build_vconvert (build_ctype (totype), exp);
573      break;
574
575    case Tnull:
576      /* Casting from typeof(null) is represented as all zeros.  */
577      result = build_typeof_null_value (totype);
578
579      /* Make sure the expression is still evaluated if necessary.  */
580      if (TREE_SIDE_EFFECTS (exp))
581	result = compound_expr (exp, result);
582      break;
583
584    case Tvector:
585      if (tbtype->ty == Tsarray)
586	{
587	  if (tbtype->size () == ebtype->size ())
588	    return build_vconvert (build_ctype (totype), exp);
589	}
590      break;
591
592    default:
593      /* All casts between imaginary and non-imaginary result in 0.0,
594	 except for casts between complex and imaginary types.  */
595      if (!ebtype->iscomplex () && !tbtype->iscomplex ()
596	  && (ebtype->isimaginary () != tbtype->isimaginary ()))
597	{
598	  warning (OPT_Wcast_result,
599		   "cast from %qs to %qs will produce zero result",
600		   ebtype->toChars (), tbtype->toChars ());
601
602	  return compound_expr (exp, build_zero_cst (build_ctype (tbtype)));
603	}
604
605      gcc_assert (TREE_CODE (exp) != STRING_CST);
606      break;
607    }
608
609  return result ? result : convert (build_ctype (totype), exp);
610}
611
612/* Return a TREE representation of EXPR, whose type has been converted from
613 * ETYPE to TOTYPE, and is being used in an rvalue context.  */
614
615tree
616convert_for_rvalue (tree expr, Type *etype, Type *totype)
617{
618  tree result = NULL_TREE;
619
620  Type *ebtype = etype->toBasetype ();
621  Type *tbtype = totype->toBasetype ();
622
623  switch (ebtype->ty)
624    {
625    case Tbool:
626      /* If casting from bool, the result is either 0 or 1, any other value
627	 violates @safe code, so enforce that it is never invalid.  */
628      for (tree ref = expr; TREE_CODE (ref) == COMPONENT_REF;
629	   ref = TREE_OPERAND (ref, 0))
630	{
631	  /* If the expression is a field that's part of a union, reinterpret
632	     the boolean as an integer and test the first bit.  The generated
633	     code should end up being equivalent to:
634		*cast(ubyte *)&expr & 1;  */
635	  if (TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 0))) == UNION_TYPE)
636	    {
637	      machine_mode bool_mode = TYPE_MODE (TREE_TYPE (expr));
638	      tree mtype = lang_hooks.types.type_for_mode (bool_mode, 1);
639	      result = fold_build2 (BIT_AND_EXPR, mtype,
640				    build_vconvert (mtype, expr),
641				    build_one_cst (mtype));
642	      break;
643	    }
644	}
645
646      if (result == NULL_TREE)
647	result = d_truthvalue_conversion (expr);
648
649      result = convert (build_ctype (tbtype), result);
650      break;
651    }
652
653  if (tbtype->ty == Tsarray
654      && ebtype->ty == Tsarray
655      && tbtype->nextOf ()->ty == ebtype->nextOf ()->ty
656      && INDIRECT_REF_P (expr)
657      && CONVERT_EXPR_CODE_P (TREE_CODE (TREE_OPERAND (expr, 0)))
658      && TREE_CODE (TREE_OPERAND (TREE_OPERAND (expr, 0), 0)) == ADDR_EXPR)
659    {
660      /* If expression is a vector that was casted to an array either by
661	 explicit type cast or by taking the vector's `.array' value, strip the
662	 reinterpret cast and build a constructor instead.  */
663      tree ptr = TREE_OPERAND (TREE_OPERAND (expr, 0), 0);
664
665      if (VECTOR_TYPE_P (TREE_TYPE (TREE_TYPE (ptr))))
666	{
667	  /* Rewrite: `*(Array *)&vector'
668		into: `{ vector[0], vector[1], ... }'  */
669	  tree array = d_save_expr (TREE_OPERAND (ptr, 0));
670	  array = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (expr), array);
671
672	  uinteger_t dim = ((TypeSArray *)tbtype)->dim->toUInteger ();
673	  vec <constructor_elt, va_gc> *elms = NULL;
674	  for (uinteger_t i = 0; i < dim; i++)
675	    {
676	      tree index = size_int (i);
677	      tree value = build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (array)),
678				   array, index, NULL_TREE, NULL_TREE);
679	      CONSTRUCTOR_APPEND_ELT (elms, index, value);
680	    }
681
682	  return build_constructor (build_ctype (totype), elms);
683	}
684    }
685
686  return result ? result : convert_expr (expr, etype, totype);
687}
688
689/* Apply semantics of assignment to a value of type TOTYPE to EXPR
690   (e.g., pointer = array -> pointer = &array[0])
691
692   Return a TREE representation of EXPR implicitly converted to TOTYPE
693   for use in assignment expressions MODIFY_EXPR, INIT_EXPR.  */
694
695tree
696convert_for_assignment (tree expr, Type *etype, Type *totype)
697{
698  Type *ebtype = etype->toBasetype ();
699  Type *tbtype = totype->toBasetype ();
700
701  /* Assuming this only has to handle converting a non Tsarray type to
702     arbitrarily dimensioned Tsarrays.  */
703  if (tbtype->ty == Tsarray)
704    {
705      Type *telem = tbtype->nextOf ()->baseElemOf ();
706
707      if (same_type_p (telem, ebtype))
708	{
709	  TypeSArray *sa_type = (TypeSArray *) tbtype;
710	  uinteger_t count = sa_type->dim->toUInteger ();
711
712	  tree ctor = build_constructor (build_ctype (totype), NULL);
713	  if (count)
714	    {
715	      vec<constructor_elt, va_gc> *ce = NULL;
716	      tree index = build2 (RANGE_EXPR, build_ctype (Type::tsize_t),
717				   size_zero_node, size_int (count - 1));
718	      tree value = convert_for_assignment (expr, etype, sa_type->next);
719
720	      /* Can't use VAR_DECLs in CONSTRUCTORS.  */
721	      if (VAR_P (value))
722		{
723		  value = DECL_INITIAL (value);
724		  gcc_assert (value);
725		}
726
727	      CONSTRUCTOR_APPEND_ELT (ce, index, value);
728	      CONSTRUCTOR_ELTS (ctor) = ce;
729	    }
730	  TREE_READONLY (ctor) = 1;
731	  TREE_CONSTANT (ctor) = 1;
732	  return ctor;
733	}
734    }
735
736  /* D Front end uses IntegerExp(0) to mean zero-init an array or structure.  */
737  if ((tbtype->ty == Tsarray || tbtype->ty == Tstruct)
738      && ebtype->isintegral ())
739    {
740      if (!integer_zerop (expr))
741	gcc_unreachable ();
742
743      return expr;
744    }
745
746  return convert_for_rvalue (expr, etype, totype);
747}
748
749/* Return a TREE representation of EXPR converted to represent
750   the parameter type ARG.  */
751
752tree
753convert_for_argument (tree expr, Parameter *arg)
754{
755  /* Lazy arguments: expr should already be a delegate.  */
756  if (arg->storageClass & STClazy)
757    return expr;
758
759  if (valist_array_p (arg->type))
760    {
761      /* Do nothing if the va_list has already been decayed to a pointer.  */
762      if (!POINTER_TYPE_P (TREE_TYPE (expr)))
763	return build_address (expr);
764    }
765  else if (parameter_reference_p (arg))
766    {
767      /* Front-end shouldn't automatically take the address.  */
768      return convert (parameter_type (arg), build_address (expr));
769    }
770
771  return expr;
772}
773
774/* Perform default promotions for data used in expressions.
775   Arrays and functions are converted to pointers;
776   enumeral types or short or char, to int.
777   In addition, manifest constants symbols are replaced by their values.
778
779   Return truth-value conversion of expression EXPR from value type TYPE.  */
780
781tree
782convert_for_condition (tree expr, Type *type)
783{
784  tree result = NULL_TREE;
785
786  switch (type->toBasetype ()->ty)
787    {
788    case Taarray:
789      /* Checks that aa.ptr !is null.  */
790      result = component_ref (expr, TYPE_FIELDS (TREE_TYPE (expr)));
791      break;
792
793    case Tarray:
794      {
795	/* Checks (arr.length || arr.ptr) (i.e arr !is null).  */
796	expr = d_save_expr (expr);
797	tree len = d_array_length (expr);
798	tree ptr = d_array_ptr (expr);
799	if (TYPE_MODE (TREE_TYPE (len)) == TYPE_MODE (TREE_TYPE (ptr)))
800	  {
801	    result = build2 (BIT_IOR_EXPR, TREE_TYPE (len), len,
802			     d_convert (TREE_TYPE (len), ptr));
803	  }
804	else
805	  {
806	    len = d_truthvalue_conversion (len);
807	    ptr = d_truthvalue_conversion (ptr);
808	    /* Probably not worth using TRUTH_OROR here.  */
809	    result = build2 (TRUTH_OR_EXPR, TREE_TYPE (len), len, ptr);
810	  }
811	break;
812      }
813
814    case Tdelegate:
815      {
816	/* Checks (function || object), but what good is it if there is
817	   a null function pointer?  */
818	tree obj, func;
819	if (METHOD_CALL_EXPR (expr))
820	  extract_from_method_call (expr, obj, func);
821	else
822	  {
823	    expr = d_save_expr (expr);
824	    obj = delegate_object (expr);
825	    func = delegate_method (expr);
826	  }
827
828	obj = d_truthvalue_conversion (obj);
829	func = d_truthvalue_conversion (func);
830	/* Probably not worth using TRUTH_ORIF here.  */
831	result = build2 (BIT_IOR_EXPR, TREE_TYPE (obj), obj, func);
832	break;
833      }
834
835    default:
836      result = convert_for_rvalue (expr, type, type);
837      break;
838    }
839
840  return d_truthvalue_conversion (result);
841}
842
843
844/* Convert EXP to a dynamic array.
845   EXP must be a static array or dynamic array.  */
846
847tree
848d_array_convert (Expression *exp)
849{
850  Type *tb = exp->type->toBasetype ();
851
852  if (tb->ty == Tarray)
853    return build_expr (exp);
854
855  if (tb->ty == Tsarray)
856    {
857      Type *totype = tb->nextOf ()->arrayOf ();
858      return convert_expr (build_expr (exp), exp->type, totype);
859    }
860
861  /* Invalid type passed.  */
862  gcc_unreachable ();
863}
864
865/* Convert EXP to a dynamic array, where ETYPE is the element type.
866   Similar to above, except that EXP is allowed to be an element of an array.
867   Temporary variables are created inline if EXP is not an lvalue.  */
868
869tree
870d_array_convert (Type *etype, Expression *exp)
871{
872  Type *tb = exp->type->toBasetype ();
873
874  if ((tb->ty != Tarray && tb->ty != Tsarray) || same_type_p (tb, etype))
875    {
876      /* Convert single element to an array.  */
877      tree expr = build_expr (exp);
878
879      if (!exp->isLvalue ())
880	{
881	  tree var = build_local_temp (TREE_TYPE (expr));
882	  expr = compound_expr (modify_expr (var, expr), var);
883	}
884
885      return d_array_value (build_ctype (exp->type->arrayOf ()),
886			    size_int (1), build_address (expr));
887    }
888  else
889    return d_array_convert (exp);
890}
891