Home | History | Annotate | Line # | Download | only in d
      1 /* d-convert.cc -- Data type conversion routines.
      2    Copyright (C) 2006-2022 Free Software Foundation, Inc.
      3 
      4 GCC is free software; you can redistribute it and/or modify
      5 it under the terms of the GNU General Public License as published by
      6 the Free Software Foundation; either version 3, or (at your option)
      7 any later version.
      8 
      9 GCC is distributed in the hope that it will be useful,
     10 but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12 GNU General Public License for more details.
     13 
     14 You should have received a copy of the GNU General Public License
     15 along with GCC; see the file COPYING3.  If not see
     16 <http://www.gnu.org/licenses/>.  */
     17 
     18 #include "config.h"
     19 #include "system.h"
     20 #include "coretypes.h"
     21 
     22 #include "dmd/aggregate.h"
     23 #include "dmd/declaration.h"
     24 #include "dmd/expression.h"
     25 #include "dmd/mtype.h"
     26 
     27 #include "tree.h"
     28 #include "fold-const.h"
     29 #include "diagnostic.h"
     30 #include "langhooks.h"
     31 #include "target.h"
     32 #include "convert.h"
     33 #include "stor-layout.h"
     34 
     35 #include "d-tree.h"
     36 
     37 
     38 /* Build CODE expression with operands OP0 and OP1.
     39    Helper function for d_truthvalue_conversion, so assumes bool result.  */
     40 
     41 static tree
     42 d_build_truthvalue_op (tree_code code, tree op0, tree op1)
     43 {
     44   tree type0, type1;
     45 
     46   tree result_type = NULL_TREE;
     47 
     48   type0 = TREE_TYPE (op0);
     49   type1 = TREE_TYPE (op1);
     50 
     51   /* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue.  */
     52   STRIP_TYPE_NOPS (op0);
     53   STRIP_TYPE_NOPS (op1);
     54 
     55   /* Also need to convert pointer/int comparison.  */
     56   if (POINTER_TYPE_P (type0) && TREE_CODE (op1) == INTEGER_CST
     57       && integer_zerop (op1))
     58     {
     59       result_type = type0;
     60     }
     61   else if (POINTER_TYPE_P (type1) && TREE_CODE (op0) == INTEGER_CST
     62 	   && integer_zerop (op0))
     63     {
     64       result_type = type1;
     65     }
     66   /* If integral, need to convert unsigned/signed comparison.
     67      Will also need to convert if type precisions differ.  */
     68   else if (INTEGRAL_TYPE_P (type0) && INTEGRAL_TYPE_P (type1))
     69     {
     70       if (TYPE_PRECISION (type0) > TYPE_PRECISION (type1))
     71 	result_type = type0;
     72       else if (TYPE_PRECISION (type0) < TYPE_PRECISION (type1))
     73 	result_type = type1;
     74       else if (TYPE_UNSIGNED (type0) != TYPE_UNSIGNED (type1))
     75 	result_type = TYPE_UNSIGNED (type0) ? type0 : type1;
     76     }
     77 
     78   if (result_type)
     79     {
     80       if (TREE_TYPE (op0) != result_type)
     81 	op0 = convert (result_type, op0);
     82       if (TREE_TYPE (op1) != result_type)
     83 	op1 = convert (result_type, op1);
     84     }
     85 
     86   return fold_build2 (code, d_bool_type, op0, op1);
     87 }
     88 
     89 /* Return whether EXPR is a declaration whose address can never be NULL.  */
     90 
     91 bool
     92 decl_with_nonnull_addr_p (const_tree expr)
     93 {
     94   return (DECL_P (expr)
     95 	  && (TREE_CODE (expr) == PARM_DECL
     96 	      || TREE_CODE (expr) == LABEL_DECL
     97 	      || !DECL_WEAK (expr)));
     98 }
     99 
    100 /* Convert EXPR to be a truth-value, validating its type for this purpose.  */
    101 
    102 tree
    103 d_truthvalue_conversion (tree expr)
    104 {
    105   switch (TREE_CODE (expr))
    106     {
    107     case EQ_EXPR:   case NE_EXPR:   case LE_EXPR:
    108     case GE_EXPR:   case LT_EXPR:   case GT_EXPR:
    109       if (TREE_TYPE (expr) == d_bool_type)
    110 	return expr;
    111       return build2 (TREE_CODE (expr), d_bool_type,
    112 		     TREE_OPERAND (expr, 0), TREE_OPERAND (expr, 1));
    113 
    114     case TRUTH_ANDIF_EXPR:
    115     case TRUTH_ORIF_EXPR:
    116     case TRUTH_AND_EXPR:
    117     case TRUTH_OR_EXPR:
    118     case TRUTH_XOR_EXPR:
    119       if (TREE_TYPE (expr) == d_bool_type)
    120 	return expr;
    121       return build2 (TREE_CODE (expr), d_bool_type,
    122 		     d_truthvalue_conversion (TREE_OPERAND (expr, 0)),
    123 		     d_truthvalue_conversion (TREE_OPERAND (expr, 1)));
    124 
    125     case TRUTH_NOT_EXPR:
    126       if (TREE_TYPE (expr) == d_bool_type)
    127 	return expr;
    128       return build1 (TREE_CODE (expr), d_bool_type,
    129 		     d_truthvalue_conversion (TREE_OPERAND (expr, 0)));
    130 
    131     case ERROR_MARK:
    132       return expr;
    133 
    134     case INTEGER_CST:
    135       return integer_zerop (expr) ? d_bool_false_node
    136 				  : d_bool_true_node;
    137 
    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;
    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 d_bool_true_node;
    152 	}
    153       break;
    154 
    155     case COMPLEX_EXPR:
    156       return d_build_truthvalue_op ((TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1))
    157 				     ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
    158 			d_truthvalue_conversion (TREE_OPERAND (expr, 0)),
    159 			d_truthvalue_conversion (TREE_OPERAND (expr, 1)));
    160 
    161     case NEGATE_EXPR:
    162     case ABS_EXPR:
    163     case FLOAT_EXPR:
    164       /* These don't change whether an object is nonzero or zero.  */
    165       return d_truthvalue_conversion (TREE_OPERAND (expr, 0));
    166 
    167     case LROTATE_EXPR:
    168     case RROTATE_EXPR:
    169       /* These don't change whether an object is zero or nonzero, but
    170 	 we can't ignore them if their second arg has side-effects.  */
    171       if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)))
    172 	{
    173 	  return build2 (COMPOUND_EXPR, d_bool_type, TREE_OPERAND (expr, 1),
    174 			 d_truthvalue_conversion (TREE_OPERAND (expr, 0)));
    175 	}
    176       else
    177 	return d_truthvalue_conversion (TREE_OPERAND (expr, 0));
    178 
    179     case COND_EXPR:
    180       /* Distribute the conversion into the arms of a COND_EXPR.  */
    181       return fold_build3 (COND_EXPR, d_bool_type, TREE_OPERAND (expr, 0),
    182 			  d_truthvalue_conversion (TREE_OPERAND (expr, 1)),
    183 			  d_truthvalue_conversion (TREE_OPERAND (expr, 2)));
    184 
    185     case CONVERT_EXPR:
    186       /* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE,
    187 	 since that affects how `default_conversion' will behave.  */
    188       if (TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE
    189 	  || TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == REFERENCE_TYPE)
    190 	break;
    191       /* Fall through.  */
    192 
    193     case NOP_EXPR:
    194       /* If this isn't narrowing the argument, we can ignore it.  */
    195       if (TYPE_PRECISION (TREE_TYPE (expr))
    196 	  >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
    197 	return d_truthvalue_conversion (TREE_OPERAND (expr, 0));
    198       break;
    199 
    200     default:
    201       break;
    202     }
    203 
    204   if (TREE_CODE (TREE_TYPE (expr)) == COMPLEX_TYPE)
    205     {
    206       tree t = save_expr (expr);
    207       return d_build_truthvalue_op ((TREE_SIDE_EFFECTS (expr)
    208 				     ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
    209 			d_truthvalue_conversion (real_part (t)),
    210 			d_truthvalue_conversion (imaginary_part (t)));
    211     }
    212   else
    213     return d_build_truthvalue_op (NE_EXPR, expr,
    214 				  build_zero_cst (TREE_TYPE (expr)));
    215 }
    216 
    217 
    218 /* Creates an expression whose value is that of EXPR, converted to type TYPE.
    219    This function implements all reasonable scalar conversions.  */
    220 
    221 tree
    222 convert (tree type, tree expr)
    223 {
    224   tree e = expr;
    225   tree_code code = TREE_CODE (type);
    226 
    227   if (type == error_mark_node
    228       || expr == error_mark_node
    229       || TREE_TYPE (expr) == error_mark_node)
    230     return error_mark_node;
    231 
    232   const char *invalid_conv_diag
    233     = targetm.invalid_conversion (TREE_TYPE (expr), type);
    234 
    235   if (invalid_conv_diag)
    236     {
    237       error ("%s", invalid_conv_diag);
    238       return error_mark_node;
    239     }
    240 
    241   if (type == TREE_TYPE (expr))
    242     return expr;
    243 
    244   if (TREE_CODE (type) == ARRAY_TYPE
    245       && TREE_CODE (TREE_TYPE (expr)) == ARRAY_TYPE
    246       && TYPE_DOMAIN (type) == TYPE_DOMAIN (TREE_TYPE (expr)))
    247     return expr;
    248 
    249   tree ret = targetm.convert_to_type (type, expr);
    250   if (ret)
    251     return ret;
    252 
    253   STRIP_TYPE_NOPS (e);
    254   tree etype = TREE_TYPE (e);
    255 
    256   if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (expr)))
    257     return fold_convert (type, expr);
    258   if (TREE_CODE (TREE_TYPE (expr)) == ERROR_MARK)
    259     return error_mark_node;
    260   if (TREE_CODE (TREE_TYPE (expr)) == VOID_TYPE)
    261     {
    262       error ("void value not ignored as it ought to be");
    263       return error_mark_node;
    264     }
    265 
    266   switch (code)
    267     {
    268     case VOID_TYPE:
    269       return fold_convert (type, e);
    270 
    271     case INTEGER_TYPE:
    272     case ENUMERAL_TYPE:
    273       if (TREE_CODE (etype) == POINTER_TYPE
    274 	  || TREE_CODE (etype) == REFERENCE_TYPE)
    275 	{
    276 	  if (integer_zerop (e))
    277 	    return build_int_cst (type, 0);
    278 
    279 	  /* Convert to an unsigned integer of the correct width first, and
    280 	     from there widen/truncate to the required type.  */
    281 	  tree utype = lang_hooks.types.type_for_size (TYPE_PRECISION (etype),
    282 						       1);
    283 	  ret = fold_build1 (CONVERT_EXPR, utype, e);
    284 	  return fold_convert (type, ret);
    285 	}
    286 
    287       return fold (convert_to_integer (type, e));
    288 
    289     case BOOLEAN_TYPE:
    290       return fold_convert (type, d_truthvalue_conversion (expr));
    291 
    292     case POINTER_TYPE:
    293     case REFERENCE_TYPE:
    294       return fold (convert_to_pointer (type, e));
    295 
    296     case REAL_TYPE:
    297       if (TREE_CODE (etype) == COMPLEX_TYPE && TYPE_IMAGINARY_FLOAT (type))
    298 	e = build1 (IMAGPART_EXPR, TREE_TYPE (etype), e);
    299 
    300       return fold (convert_to_real (type, e));
    301 
    302     case COMPLEX_TYPE:
    303       if (TREE_CODE (etype) == REAL_TYPE && TYPE_IMAGINARY_FLOAT (etype))
    304 	return fold_build2 (COMPLEX_EXPR, type,
    305 			    build_zero_cst (TREE_TYPE (type)),
    306 			    convert (TREE_TYPE (type), expr));
    307 
    308       return fold (convert_to_complex (type, e));
    309 
    310     case VECTOR_TYPE:
    311       return fold (convert_to_vector (type, e));
    312 
    313     case RECORD_TYPE:
    314     case UNION_TYPE:
    315       if (lang_hooks.types_compatible_p (type, TREE_TYPE (expr)))
    316 	return fold_build1 (VIEW_CONVERT_EXPR, type, expr);
    317       break;
    318 
    319     default:
    320       break;
    321     }
    322 
    323   error ("conversion to non-scalar type requested");
    324   return error_mark_node;
    325 }
    326 
    327 /* Return expression EXP, whose type has been converted to TYPE.  */
    328 
    329 tree
    330 d_convert (tree type, tree exp)
    331 {
    332   /* Check this first before retrieving frontend type.  */
    333   if (error_operand_p (type) || error_operand_p (exp))
    334     return error_mark_node;
    335 
    336   Type *totype = TYPE_LANG_FRONTEND (type);
    337   Type *etype = TYPE_LANG_FRONTEND (TREE_TYPE (exp));
    338 
    339   if (totype && etype)
    340     return convert_expr (exp, etype, totype);
    341 
    342   return convert (type, exp);
    343 }
    344 
    345 /* Return expression EXP, whose type has been convert from ETYPE to TOTYPE.  */
    346 
    347 tree
    348 convert_expr (tree exp, Type *etype, Type *totype)
    349 {
    350   tree result = NULL_TREE;
    351 
    352   gcc_assert (etype && totype);
    353   Type *ebtype = etype->toBasetype ();
    354   Type *tbtype = totype->toBasetype ();
    355 
    356   if (same_type_p (etype, totype))
    357     return exp;
    358 
    359   if (error_operand_p (exp))
    360     return exp;
    361 
    362   switch (ebtype->ty)
    363     {
    364     case TY::Tdelegate:
    365       if (tbtype->ty == 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 == 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 TY::Tstruct:
    386       if (tbtype->ty == 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 TY::Tclass:
    404       if (tbtype->ty == 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 () || cdto->isCPPclass ())
    434 	    {
    435 	      /* Downcasting in C++ is a no-op.  */
    436 	      if (cdfrom->isCPPclass () && 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 TY::Tsarray:
    464       if (tbtype->ty == TY::Tpointer)
    465 	{
    466 	  result = build_nop (build_ctype (totype), build_address (exp));
    467 	}
    468       else if (tbtype->ty == TY::Tarray)
    469 	{
    470 	  dinteger_t dim = ebtype->isTypeSArray ()->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 == 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 == 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 == 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 TY::Tarray:
    523       if (tbtype->ty == TY::Tpointer)
    524 	{
    525 	  return d_convert (build_ctype (totype), d_array_ptr (exp));
    526 	}
    527       else if (tbtype->ty == TY::Tarray)
    528 	{
    529 	  /* Assume tvoid->size() == 1.  */
    530 	  dinteger_t fsize = ebtype->nextOf ()->toBasetype ()->size ();
    531 	  dinteger_t tsize = tbtype->nextOf ()->toBasetype ()->size ();
    532 
    533 	  if (fsize != tsize)
    534 	    {
    535 	      /* Conversion requires a reinterpret cast of array.
    536 		 This case should have been lowered in the semantic pass.  */
    537 	      if (tsize != 0 && fsize % tsize == 0)
    538 		{
    539 		  /* Set array dimension to (length * (fsize / tsize)).  */
    540 		  tree newlength = size_mult_expr (d_array_length (exp),
    541 						   size_int (fsize / tsize));
    542 		  return d_array_value (build_ctype (totype), newlength,
    543 					d_array_ptr (exp));
    544 		}
    545 	      else
    546 		gcc_unreachable ();
    547 	    }
    548 	  else
    549 	    {
    550 	      /* Convert from void[] or elements are the same size
    551 		 -- don't change length.  */
    552 	      return build_vconvert (build_ctype (totype), exp);
    553 	    }
    554 	}
    555       else if (tbtype->ty == TY::Tsarray)
    556 	{
    557 	  /* Strings are treated as dynamic arrays in D2.  */
    558 	  if (ebtype->isString () && tbtype->isString ())
    559 	    return indirect_ref (build_ctype (totype), d_array_ptr (exp));
    560 	}
    561       else
    562 	{
    563 	  error ("cannot cast expression of type %qs to %qs",
    564 		 etype->toChars (), totype->toChars ());
    565 	  return error_mark_node;
    566 	}
    567       break;
    568 
    569     case TY::Taarray:
    570       if (tbtype->ty == TY::Taarray)
    571 	return build_vconvert (build_ctype (totype), exp);
    572       /* Can convert associative arrays to void pointers.  */
    573       else if (tbtype->ty == TY::Tpointer && tbtype->nextOf ()->ty == TY::Tvoid)
    574 	return build_vconvert (build_ctype (totype), exp);
    575       /* Else, default conversion, which should product an error.  */
    576       break;
    577 
    578     case TY::Tpointer:
    579       /* Can convert void pointers to associative arrays too.  */
    580       if (tbtype->ty == TY::Taarray && ebtype->nextOf ()->ty == TY::Tvoid)
    581 	return build_vconvert (build_ctype (totype), exp);
    582       break;
    583 
    584     case TY::Tnull:
    585     case TY::Tnoreturn:
    586       /* Casting from `typeof(null)' for `null' expressions, or `typeof(*null)'
    587 	 for `noreturn' expressions is represented as all zeros.  */
    588       result = build_typeof_null_value (totype);
    589 
    590       /* Make sure the expression is still evaluated if necessary.  */
    591       if (TREE_SIDE_EFFECTS (exp))
    592 	result = compound_expr (exp, result);
    593       break;
    594 
    595     case TY::Tvector:
    596       if (tbtype->ty == TY::Tsarray)
    597 	{
    598 	  if (tbtype->size () == ebtype->size ())
    599 	    return build_vconvert (build_ctype (totype), exp);
    600 	}
    601       break;
    602 
    603     default:
    604       /* All casts between imaginary and non-imaginary result in 0.0,
    605 	 except for casts between complex and imaginary types.  */
    606       if (!ebtype->iscomplex () && !tbtype->iscomplex ()
    607 	  && (ebtype->isimaginary () != tbtype->isimaginary ()))
    608 	{
    609 	  warning (OPT_Wcast_result,
    610 		   "cast from %qs to %qs will produce zero result",
    611 		   ebtype->toChars (), tbtype->toChars ());
    612 
    613 	  return compound_expr (exp, build_zero_cst (build_ctype (tbtype)));
    614 	}
    615 
    616       gcc_assert (TREE_CODE (exp) != STRING_CST);
    617       break;
    618     }
    619 
    620   return result ? result : convert (build_ctype (totype), exp);
    621 }
    622 
    623 /* Return a TREE representation of EXPR, whose type has been converted from
    624  * ETYPE to TOTYPE, and is being used in an rvalue context.  */
    625 
    626 tree
    627 convert_for_rvalue (tree expr, Type *etype, Type *totype)
    628 {
    629   tree result = NULL_TREE;
    630 
    631   Type *ebtype = etype->toBasetype ();
    632   Type *tbtype = totype->toBasetype ();
    633 
    634   if (ebtype->ty == TY::Tbool)
    635     {
    636       /* If casting from bool, the result is either 0 or 1, any other value
    637 	 violates @safe code, so enforce that it is never invalid.  */
    638       for (tree ref = expr; TREE_CODE (ref) == COMPONENT_REF;
    639 	   ref = TREE_OPERAND (ref, 0))
    640 	{
    641 	  /* If the expression is a field that's part of a union, reinterpret
    642 	     the boolean as an integer and test the first bit.  The generated
    643 	     code should end up being equivalent to:
    644 		*cast(ubyte *)&expr & 1;  */
    645 	  if (TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 0))) == UNION_TYPE)
    646 	    {
    647 	      machine_mode bool_mode = TYPE_MODE (TREE_TYPE (expr));
    648 	      tree mtype = lang_hooks.types.type_for_mode (bool_mode, 1);
    649 	      result = fold_build2 (BIT_AND_EXPR, mtype,
    650 				    build_vconvert (mtype, expr),
    651 				    build_one_cst (mtype));
    652 	      break;
    653 	    }
    654 	}
    655 
    656       if (result == NULL_TREE)
    657 	result = d_truthvalue_conversion (expr);
    658 
    659       result = convert (build_ctype (tbtype), result);
    660     }
    661 
    662   if (tbtype->ty == TY::Tsarray
    663       && ebtype->ty == TY::Tsarray
    664       && tbtype->nextOf ()->ty == ebtype->nextOf ()->ty
    665       && INDIRECT_REF_P (expr)
    666       && CONVERT_EXPR_CODE_P (TREE_CODE (TREE_OPERAND (expr, 0)))
    667       && TREE_CODE (TREE_OPERAND (TREE_OPERAND (expr, 0), 0)) == ADDR_EXPR)
    668     {
    669       /* If expression is a vector that was casted to an array either by
    670 	 explicit type cast or by taking the vector's `.array' value, strip the
    671 	 reinterpret cast and build a constructor instead.  */
    672       tree ptr = TREE_OPERAND (TREE_OPERAND (expr, 0), 0);
    673 
    674       if (VECTOR_TYPE_P (TREE_TYPE (TREE_TYPE (ptr))))
    675 	{
    676 	  /* Rewrite: `*(Array *)&vector'
    677 		into: `{ vector[0], vector[1], ... }'  */
    678 	  tree array = d_save_expr (TREE_OPERAND (ptr, 0));
    679 	  array = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (expr), array);
    680 
    681 	  uinteger_t dim = tbtype->isTypeSArray ()->dim->toUInteger ();
    682 	  vec <constructor_elt, va_gc> *elms = NULL;
    683 	  for (uinteger_t i = 0; i < dim; i++)
    684 	    {
    685 	      tree index = size_int (i);
    686 	      tree value = build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (array)),
    687 				   array, index, NULL_TREE, NULL_TREE);
    688 	      CONSTRUCTOR_APPEND_ELT (elms, index, value);
    689 	    }
    690 
    691 	  return build_constructor (build_ctype (totype), elms);
    692 	}
    693     }
    694 
    695   return result ? result : convert_expr (expr, etype, totype);
    696 }
    697 
    698 /* Helper for convert_for_assigment and convert_for_argument.
    699    Returns true if EXPR is a va_list static array parameter.  */
    700 
    701 static bool
    702 is_valist_parameter_type (Expression *expr)
    703 {
    704   Declaration *decl = NULL;
    705 
    706   if (VarExp *ve = expr->isVarExp ())
    707     decl = ve->var;
    708   else if (SymOffExp *se = expr->isSymOffExp ())
    709     decl = se->var;
    710 
    711   if (decl != NULL && decl->isParameter () && valist_array_p (decl->type))
    712     return true;
    713 
    714   return false;
    715 }
    716 
    717 /* Helper for convert_for_assigment and convert_for_argument.
    718    Report erroneous uses of assigning or passing a va_list parameter.  */
    719 
    720 static void
    721 check_valist_conversion (Expression *expr, Type *totype, bool in_assignment)
    722 {
    723   /* Parameter symbol and its converted type.  */
    724   Declaration *decl = NULL;
    725   /* Type of parameter when evaluated in the expression.  */
    726   Type *type = NULL;
    727 
    728   if (VarExp *ve = expr->isVarExp ())
    729     {
    730       decl = ve->var;
    731       type = ve->var->type->nextOf ()->pointerTo ();
    732     }
    733   else if (SymOffExp *se = expr->isSymOffExp ())
    734     {
    735       decl = se->var;
    736       type = se->var->type->nextOf ()->pointerTo ()->pointerTo ();
    737     }
    738 
    739   /* Should not be called unless is_valist_parameter_type also matched.  */
    740   gcc_assert (decl != NULL && decl->isParameter ()
    741 	      && valist_array_p (decl->type));
    742 
    743   /* OK if conversion between types is allowed.  */
    744   if (type->implicitConvTo (totype) != MATCH::nomatch)
    745     return;
    746 
    747   if (in_assignment)
    748     {
    749       error_at (make_location_t (expr->loc), "cannot convert parameter %qs "
    750 		"from type %qs to type %qs in assignment",
    751 		expr->toChars(), type->toChars (), totype->toChars ());
    752     }
    753   else
    754     {
    755       error_at (make_location_t (expr->loc), "cannot convert parameter %qs "
    756 		"from type %qs to type %qs in argument passing",
    757 		expr->toChars(), type->toChars (), totype->toChars ());
    758     }
    759 
    760   inform (make_location_t (decl->loc), "parameters of type %<va_list%> "
    761 	  "{aka %qs} are decayed to pointer types, and require %<va_copy%> "
    762 	  "to be converted back into a static array type",
    763 	  decl->type->toChars ());
    764 }
    765 
    766 /* Apply semantics of assignment to a value of type TOTYPE to EXPR
    767    For example: `pointer = array' gets lowered to `pointer = &array[0]'.
    768    If LITERALP is true, then EXPR is a value used in the initialization
    769    of another literal.
    770 
    771    Return a TREE representation of EXPR implicitly converted to TOTYPE
    772    for use in assignment expressions MODIFY_EXPR, INIT_EXPR.  */
    773 
    774 tree
    775 convert_for_assignment (Expression *expr, Type *totype, bool literalp)
    776 {
    777   Type *ebtype = expr->type->toBasetype ();
    778   Type *tbtype = totype->toBasetype ();
    779 
    780   /* Assuming this only has to handle converting a non Tsarray type to
    781      arbitrarily dimensioned Tsarrays.  */
    782   if (tbtype->ty == TY::Tsarray)
    783     {
    784       Type *telem = tbtype->nextOf ()->baseElemOf ();
    785 
    786       if (same_type_p (telem, ebtype))
    787 	{
    788 	  TypeSArray *sa_type = tbtype->isTypeSArray ();
    789 	  uinteger_t count = sa_type->dim->toUInteger ();
    790 
    791 	  tree ctor = build_constructor (build_ctype (totype), NULL);
    792 	  if (count)
    793 	    {
    794 	      vec <constructor_elt, va_gc> *ce = NULL;
    795 	      tree index = build2 (RANGE_EXPR, build_ctype (Type::tsize_t),
    796 				   size_zero_node, size_int (count - 1));
    797 	      tree value = convert_for_assignment (expr, sa_type->next,
    798 						   literalp);
    799 	      /* Can't use VAR_DECLs in CONSTRUCTORS.  */
    800 	      if (VAR_P (value))
    801 		{
    802 		  value = DECL_INITIAL (value);
    803 		  gcc_assert (value);
    804 		}
    805 
    806 	      CONSTRUCTOR_APPEND_ELT (ce, index, value);
    807 	      CONSTRUCTOR_ELTS (ctor) = ce;
    808 	    }
    809 	  TREE_READONLY (ctor) = 1;
    810 	  TREE_CONSTANT (ctor) = 1;
    811 	  return ctor;
    812 	}
    813     }
    814 
    815   /* D Front end uses IntegerExp(0) to mean zero-init an array or structure.  */
    816   if ((tbtype->ty == TY::Tsarray || tbtype->ty == TY::Tstruct)
    817       && ebtype->isintegral ())
    818     {
    819       tree ret = build_expr (expr, false, literalp);
    820       gcc_assert (integer_zerop (ret));
    821       return ret;
    822     }
    823 
    824   /* Assigning a va_list by value or reference, check whether RHS is a parameter
    825      that has has been lowered by declaration_type or parameter_type.  */
    826   if (is_valist_parameter_type (expr))
    827     check_valist_conversion (expr, totype, true);
    828 
    829   return convert_for_rvalue (build_expr (expr, false, literalp),
    830 			     expr->type, totype);
    831 }
    832 
    833 /* Return a TREE representation of EXPR converted to represent
    834    the parameter type ARG.  */
    835 
    836 tree
    837 convert_for_argument (Expression *expr, Parameter *arg)
    838 {
    839   tree targ = build_expr (expr);
    840 
    841   /* Lazy arguments: expr should already be a delegate.  */
    842   if (arg->storageClass & STClazy)
    843     return targ;
    844 
    845   /* Passing a va_list by value, check whether the target requires it to
    846      be decayed to a pointer type.  */
    847   if (valist_array_p (arg->type))
    848     {
    849       if (!POINTER_TYPE_P (TREE_TYPE (targ)))
    850 	return build_address (targ);
    851 
    852       /* Do nothing if the va_list has already been converted.  */
    853       return targ;
    854     }
    855 
    856   /* Passing a va_list by reference, check if types are really compatible
    857      after conversion from static array to pointer type.  */
    858   if (is_valist_parameter_type (expr))
    859     check_valist_conversion (expr, arg->type, false);
    860 
    861   /* Front-end shouldn't automatically take the address of `ref' parameters.  */
    862   if (parameter_reference_p (arg))
    863     return convert (parameter_type (arg), build_address (targ));
    864 
    865   return targ;
    866 }
    867 
    868 /* Perform default promotions for data used in expressions.
    869    Arrays and functions are converted to pointers;
    870    enumeral types or short or char, to int.
    871    In addition, manifest constants symbols are replaced by their values.
    872 
    873    Return truth-value conversion of expression EXPR from value type TYPE.  */
    874 
    875 tree
    876 convert_for_condition (tree expr, Type *type)
    877 {
    878   tree result = NULL_TREE;
    879 
    880   switch (type->toBasetype ()->ty)
    881     {
    882     case TY::Taarray:
    883       /* Checks that aa.ptr !is null.  */
    884       result = component_ref (expr, TYPE_FIELDS (TREE_TYPE (expr)));
    885       break;
    886 
    887     case TY::Tarray:
    888       {
    889 	/* Checks (arr.length || arr.ptr) (i.e arr !is null).  */
    890 	expr = d_save_expr (expr);
    891 	tree len = d_array_length (expr);
    892 	tree ptr = d_array_ptr (expr);
    893 	if (TYPE_MODE (TREE_TYPE (len)) == TYPE_MODE (TREE_TYPE (ptr)))
    894 	  {
    895 	    result = build2 (BIT_IOR_EXPR, TREE_TYPE (len), len,
    896 			     d_convert (TREE_TYPE (len), ptr));
    897 	  }
    898 	else
    899 	  {
    900 	    len = d_truthvalue_conversion (len);
    901 	    ptr = d_truthvalue_conversion (ptr);
    902 	    /* Probably not worth using TRUTH_OROR here.  */
    903 	    result = build2 (TRUTH_OR_EXPR, TREE_TYPE (len), len, ptr);
    904 	  }
    905 	break;
    906       }
    907 
    908     case TY::Tdelegate:
    909       {
    910 	/* Checks (function || object), but what good is it if there is
    911 	   a null function pointer?  */
    912 	tree obj, func;
    913 	if (METHOD_CALL_EXPR (expr))
    914 	  extract_from_method_call (expr, obj, func);
    915 	else
    916 	  {
    917 	    expr = d_save_expr (expr);
    918 	    obj = delegate_object (expr);
    919 	    func = delegate_method (expr);
    920 	  }
    921 
    922 	obj = d_truthvalue_conversion (obj);
    923 	func = d_truthvalue_conversion (func);
    924 	/* Probably not worth using TRUTH_ORIF here.  */
    925 	result = build2 (BIT_IOR_EXPR, TREE_TYPE (obj), obj, func);
    926 	break;
    927       }
    928 
    929     case TY::Tnoreturn:
    930       /* Front-end allows conditionals that never return, represent the
    931 	 conditional result value as all zeros.  */
    932       result = build_zero_cst (d_bool_type);
    933 
    934       /* Make sure the expression is still evaluated if necessary.  */
    935       if (TREE_SIDE_EFFECTS (expr))
    936 	result = compound_expr (expr, result);
    937       break;
    938 
    939     default:
    940       result = convert_for_rvalue (expr, type, type);
    941       break;
    942     }
    943 
    944   return d_truthvalue_conversion (result);
    945 }
    946 
    947 
    948 /* Convert EXP to a dynamic array.
    949    EXP must be a static array or dynamic array.  */
    950 
    951 tree
    952 d_array_convert (Expression *exp)
    953 {
    954   Type *tb = exp->type->toBasetype ();
    955 
    956   if (tb->ty == TY::Tarray)
    957     return build_expr (exp);
    958 
    959   if (tb->ty == TY::Tsarray)
    960     {
    961       Type *totype = tb->nextOf ()->arrayOf ();
    962       return convert_expr (build_expr (exp), exp->type, totype);
    963     }
    964 
    965   /* Invalid type passed.  */
    966   gcc_unreachable ();
    967 }
    968 
    969 /* Convert EXP to a dynamic array, where ETYPE is the element type.
    970    Similar to above, except that EXP is allowed to be an element of an array.
    971    Temporary variables are created inline if EXP is not an lvalue.  */
    972 
    973 tree
    974 d_array_convert (Type *etype, Expression *exp)
    975 {
    976   Type *tb = exp->type->toBasetype ();
    977 
    978   if ((tb->ty != TY::Tarray && tb->ty != TY::Tsarray)
    979       || same_type_p (tb, etype))
    980     {
    981       /* Convert single element to an array.  */
    982       tree expr = build_expr (exp);
    983 
    984       if (!exp->isLvalue ())
    985 	{
    986 	  tree var = build_local_temp (TREE_TYPE (expr));
    987 	  expr = compound_expr (modify_expr (var, expr), var);
    988 	}
    989 
    990       return d_array_value (build_ctype (exp->type->arrayOf ()),
    991 			    size_int (1), build_address (expr));
    992     }
    993   else
    994     return d_array_convert (exp);
    995 }
    996