xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/d/d-convert.cc (revision 4ac76180e904e771b9d522c7e57296d371f06499)
1 /* d-convert.cc -- Data type conversion routines.
2    Copyright (C) 2006-2020 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
d_build_truthvalue_op(tree_code code,tree op0,tree op1)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
decl_with_nonnull_addr_p(const_tree expr)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
d_truthvalue_conversion(tree expr)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
convert(tree type,tree expr)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
d_convert(tree type,tree exp)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
convert_expr(tree exp,Type * etype,Type * totype)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 ("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 
615 tree
convert_for_rvalue(tree expr,Type * etype,Type * totype)616 convert_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 
695 tree
convert_for_assignment(tree expr,Type * etype,Type * totype)696 convert_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 
752 tree
convert_for_argument(tree expr,Parameter * arg)753 convert_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 
781 tree
convert_for_condition(tree expr,Type * type)782 convert_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 
847 tree
d_array_convert(Expression * exp)848 d_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 
869 tree
d_array_convert(Type * etype,Expression * exp)870 d_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