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