00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "config.h"
00038 #include "system.h"
00039 #include "tree.h"
00040 #include "rtl.h"
00041 #include "expr.h"
00042 #include "cp-tree.h"
00043 #include "tm_p.h"
00044 #include "flags.h"
00045 #include "output.h"
00046 #include "toplev.h"
00047 #include "diagnostic.h"
00048 #include "target.h"
00049 #ifdef SGI_MONGOOSE
00050 #include "defaults.h"
00051 #endif
00052
00053 static tree convert_for_assignment PARAMS ((tree, tree, const char *, tree,
00054 int));
00055 static tree cp_pointer_int_sum PARAMS ((enum tree_code, tree, tree));
00056 static tree rationalize_conditional_expr PARAMS ((enum tree_code, tree));
00057 static int comp_target_parms PARAMS ((tree, tree));
00058 static int comp_ptr_ttypes_real PARAMS ((tree, tree, int));
00059 static int comp_ptr_ttypes_const PARAMS ((tree, tree));
00060 static int comp_ptr_ttypes_reinterpret PARAMS ((tree, tree));
00061 static int comp_except_types PARAMS ((tree, tree, int));
00062 static int comp_array_types PARAMS ((int (*) (tree, tree, int), tree,
00063 tree, int));
00064 static tree common_base_type PARAMS ((tree, tree));
00065 static tree lookup_anon_field PARAMS ((tree, tree));
00066 static tree pointer_diff PARAMS ((tree, tree, tree));
00067 static tree qualify_type_recursive PARAMS ((tree, tree));
00068 static tree get_delta_difference PARAMS ((tree, tree, int));
00069 static int comp_cv_target_types PARAMS ((tree, tree, int));
00070 static void casts_away_constness_r PARAMS ((tree *, tree *));
00071 static int casts_away_constness PARAMS ((tree, tree));
00072 static void maybe_warn_about_returning_address_of_local PARAMS ((tree));
00073 static tree strip_all_pointer_quals PARAMS ((tree));
00074
00075
00076
00077
00078 tree
00079 target_type (type)
00080 tree type;
00081 {
00082 if (TREE_CODE (type) == REFERENCE_TYPE)
00083 type = TREE_TYPE (type);
00084 while (TREE_CODE (type) == POINTER_TYPE
00085 || TREE_CODE (type) == ARRAY_TYPE
00086 || TREE_CODE (type) == FUNCTION_TYPE
00087 || TREE_CODE (type) == METHOD_TYPE
00088 || TREE_CODE (type) == OFFSET_TYPE)
00089 type = TREE_TYPE (type);
00090 return type;
00091 }
00092
00093
00094
00095
00096
00097
00098 tree
00099 require_complete_type (value)
00100 tree value;
00101 {
00102 tree type;
00103
00104 if (processing_template_decl || value == error_mark_node)
00105 return value;
00106
00107 if (TREE_CODE (value) == OVERLOAD)
00108 type = unknown_type_node;
00109 else
00110 type = TREE_TYPE (value);
00111
00112
00113 if (COMPLETE_TYPE_P (type))
00114 return value;
00115
00116
00117
00118
00119 if (TREE_CODE (value) == OFFSET_REF
00120 && current_class_ref != 0
00121 && TREE_OPERAND (value, 0) == current_class_ref)
00122 {
00123 value = resolve_offset_ref (value);
00124 return require_complete_type (value);
00125 }
00126
00127 if (complete_type_or_else (type, value))
00128 return value;
00129 else
00130 return error_mark_node;
00131 }
00132
00133
00134
00135
00136
00137
00138 tree
00139 complete_type (type)
00140 tree type;
00141 {
00142 if (type == NULL_TREE)
00143
00144
00145 return error_mark_node;
00146
00147 if (type == error_mark_node || COMPLETE_TYPE_P (type))
00148 ;
00149 else if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type))
00150 {
00151 tree t = complete_type (TREE_TYPE (type));
00152 if (COMPLETE_TYPE_P (t) && ! processing_template_decl)
00153 layout_type (type);
00154 TYPE_NEEDS_CONSTRUCTING (type)
00155 = TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (t));
00156 TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
00157 = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TYPE_MAIN_VARIANT (t));
00158 }
00159 else if (CLASS_TYPE_P (type) && CLASSTYPE_TEMPLATE_INSTANTIATION (type))
00160 instantiate_class_template (TYPE_MAIN_VARIANT (type));
00161
00162 return type;
00163 }
00164
00165
00166
00167
00168
00169
00170 tree
00171 complete_type_or_diagnostic (type, value, diag_type)
00172 tree type;
00173 tree value;
00174 int diag_type;
00175 {
00176 type = complete_type (type);
00177 if (type == error_mark_node)
00178
00179 return NULL_TREE;
00180 else if (!COMPLETE_TYPE_P (type))
00181 {
00182 cxx_incomplete_type_diagnostic (value, type, diag_type);
00183 return NULL_TREE;
00184 }
00185 else
00186 return type;
00187 }
00188
00189
00190
00191 int
00192 type_unknown_p (exp)
00193 tree exp;
00194 {
00195 return (TREE_CODE (exp) == OVERLOAD
00196 || TREE_CODE (exp) == TREE_LIST
00197 || TREE_TYPE (exp) == unknown_type_node
00198 || (TREE_CODE (TREE_TYPE (exp)) == OFFSET_TYPE
00199 && TREE_TYPE (TREE_TYPE (exp)) == unknown_type_node));
00200 }
00201
00202
00203
00204
00205
00206 static tree
00207 qualify_type_recursive (t1, t2)
00208 tree t1, t2;
00209 {
00210 if ((TYPE_PTR_P (t1) && TYPE_PTR_P (t2))
00211 || (TYPE_PTRMEM_P (t1) && TYPE_PTRMEM_P (t2)))
00212 {
00213 tree tt1;
00214 tree tt2;
00215 tree b1;
00216 int type_quals;
00217 tree tgt;
00218 tree attributes = (*targetm.merge_type_attributes) (t1, t2);
00219
00220 if (TYPE_PTRMEM_P (t1))
00221 {
00222 b1 = TYPE_PTRMEM_CLASS_TYPE (t1);
00223 tt1 = TYPE_PTRMEM_POINTED_TO_TYPE (t1);
00224 tt2 = TYPE_PTRMEM_POINTED_TO_TYPE (t2);
00225 }
00226 else
00227 {
00228 b1 = NULL_TREE;
00229 tt1 = TREE_TYPE (t1);
00230 tt2 = TREE_TYPE (t2);
00231 }
00232
00233 type_quals = (cp_type_quals (tt1) | cp_type_quals (tt2));
00234 tgt = qualify_type_recursive (tt1, tt2);
00235 tgt = cp_build_qualified_type (tgt, type_quals);
00236 if (b1)
00237 t1 = build_ptrmem_type (b1, tgt);
00238 else
00239 t1 = build_pointer_type (tgt);
00240 t1 = build_type_attribute_variant (t1, attributes);
00241 }
00242 return t1;
00243 }
00244
00245
00246
00247
00248
00249
00250
00251
00252 tree
00253 commonparms (p1, p2)
00254 tree p1, p2;
00255 {
00256 tree oldargs = p1, newargs, n;
00257 int i, len;
00258 int any_change = 0;
00259
00260 len = list_length (p1);
00261 newargs = tree_last (p1);
00262
00263 if (newargs == void_list_node)
00264 i = 1;
00265 else
00266 {
00267 i = 0;
00268 newargs = 0;
00269 }
00270
00271 for (; i < len; i++)
00272 newargs = tree_cons (NULL_TREE, NULL_TREE, newargs);
00273
00274 n = newargs;
00275
00276 for (i = 0; p1;
00277 p1 = TREE_CHAIN (p1), p2 = TREE_CHAIN (p2), n = TREE_CHAIN (n), i++)
00278 {
00279 if (TREE_PURPOSE (p1) && !TREE_PURPOSE (p2))
00280 {
00281 TREE_PURPOSE (n) = TREE_PURPOSE (p1);
00282 any_change = 1;
00283 }
00284 else if (! TREE_PURPOSE (p1))
00285 {
00286 if (TREE_PURPOSE (p2))
00287 {
00288 TREE_PURPOSE (n) = TREE_PURPOSE (p2);
00289 any_change = 1;
00290 }
00291 }
00292 else
00293 {
00294 if (1 != simple_cst_equal (TREE_PURPOSE (p1), TREE_PURPOSE (p2)))
00295 any_change = 1;
00296 TREE_PURPOSE (n) = TREE_PURPOSE (p2);
00297 }
00298 if (TREE_VALUE (p1) != TREE_VALUE (p2))
00299 {
00300 any_change = 1;
00301 TREE_VALUE (n) = merge_types (TREE_VALUE (p1), TREE_VALUE (p2));
00302 }
00303 else
00304 TREE_VALUE (n) = TREE_VALUE (p1);
00305 }
00306 if (! any_change)
00307 return oldargs;
00308
00309 return newargs;
00310 }
00311
00312
00313
00314 tree
00315 original_type (t)
00316 tree t;
00317 {
00318 while (TYPE_NAME (t) != NULL_TREE)
00319 {
00320 tree x = TYPE_NAME (t);
00321 if (TREE_CODE (x) != TYPE_DECL)
00322 break;
00323 x = DECL_ORIGINAL_TYPE (x);
00324 if (x == NULL_TREE)
00325 break;
00326 t = x;
00327 }
00328 return t;
00329 }
00330
00331
00332
00333
00334
00335 tree
00336 type_after_usual_arithmetic_conversions (t1, t2)
00337 tree t1;
00338 tree t2;
00339 {
00340 enum tree_code code1 = TREE_CODE (t1);
00341 enum tree_code code2 = TREE_CODE (t2);
00342 tree attributes;
00343
00344
00345 my_friendly_assert (ARITHMETIC_TYPE_P (t1)
00346 || TREE_CODE (t1) == COMPLEX_TYPE
00347 || TREE_CODE (t1) == ENUMERAL_TYPE,
00348 19990725);
00349 my_friendly_assert (ARITHMETIC_TYPE_P (t2)
00350 || TREE_CODE (t2) == COMPLEX_TYPE
00351 || TREE_CODE (t2) == ENUMERAL_TYPE,
00352 19990725);
00353
00354
00355
00356
00357 attributes = (*targetm.merge_type_attributes) (t1, t2);
00358
00359
00360
00361
00362 if (code1 == COMPLEX_TYPE || code2 == COMPLEX_TYPE)
00363 {
00364 tree subtype1 = code1 == COMPLEX_TYPE ? TREE_TYPE (t1) : t1;
00365 tree subtype2 = code2 == COMPLEX_TYPE ? TREE_TYPE (t2) : t2;
00366 tree subtype
00367 = type_after_usual_arithmetic_conversions (subtype1, subtype2);
00368
00369 if (code1 == COMPLEX_TYPE && TREE_TYPE (t1) == subtype)
00370 return build_type_attribute_variant (t1, attributes);
00371 else if (code2 == COMPLEX_TYPE && TREE_TYPE (t2) == subtype)
00372 return build_type_attribute_variant (t2, attributes);
00373 else
00374 return build_type_attribute_variant (build_complex_type (subtype),
00375 attributes);
00376 }
00377
00378
00379 if (code1 == REAL_TYPE && code2 != REAL_TYPE)
00380 return build_type_attribute_variant (t1, attributes);
00381 if (code2 == REAL_TYPE && code1 != REAL_TYPE)
00382 return build_type_attribute_variant (t2, attributes);
00383
00384
00385 if (code1 != REAL_TYPE)
00386 {
00387 t1 = type_promotes_to (t1);
00388 t2 = type_promotes_to (t2);
00389 }
00390
00391
00392 if (TYPE_PRECISION (t1) > TYPE_PRECISION (t2))
00393 return build_type_attribute_variant (t1, attributes);
00394 else if (TYPE_PRECISION (t2) > TYPE_PRECISION (t1))
00395 return build_type_attribute_variant (t2, attributes);
00396
00397
00398 if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
00399 return build_type_attribute_variant (t1, attributes);
00400
00401 if (code1 != REAL_TYPE)
00402 {
00403
00404 if (TYPE_IS_SIZETYPE (t1) > TYPE_IS_SIZETYPE (t2))
00405 return build_type_attribute_variant (t1, attributes);
00406 if (TYPE_IS_SIZETYPE (t2) > TYPE_IS_SIZETYPE (t1))
00407 return build_type_attribute_variant (t2, attributes);
00408
00409
00410
00411 if (same_type_p (TYPE_MAIN_VARIANT (t1), long_long_unsigned_type_node)
00412 || same_type_p (TYPE_MAIN_VARIANT (t2), long_long_unsigned_type_node))
00413 return build_type_attribute_variant (long_long_unsigned_type_node,
00414 attributes);
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425 if (same_type_p (TYPE_MAIN_VARIANT (t1), long_long_integer_type_node)
00426 || same_type_p (TYPE_MAIN_VARIANT (t2), long_long_integer_type_node))
00427 {
00428 tree t = ((TREE_UNSIGNED (t1) || TREE_UNSIGNED (t2))
00429 ? long_long_unsigned_type_node
00430 : long_long_integer_type_node);
00431 return build_type_attribute_variant (t, attributes);
00432 }
00433
00434
00435 if (same_type_p (TYPE_MAIN_VARIANT (t1), long_unsigned_type_node)
00436 || same_type_p (TYPE_MAIN_VARIANT (t2), long_unsigned_type_node))
00437 return build_type_attribute_variant (long_unsigned_type_node,
00438 attributes);
00439 if (same_type_p (TYPE_MAIN_VARIANT (t1), long_integer_type_node)
00440 || same_type_p (TYPE_MAIN_VARIANT (t2), long_integer_type_node))
00441 {
00442 tree t = ((TREE_UNSIGNED (t1) || TREE_UNSIGNED (t2))
00443 ? long_unsigned_type_node : long_integer_type_node);
00444 return build_type_attribute_variant (t, attributes);
00445 }
00446
00447 if (TREE_UNSIGNED (t1))
00448 return build_type_attribute_variant (t1, attributes);
00449 else
00450 return build_type_attribute_variant (t2, attributes);
00451 }
00452 else
00453 {
00454 if (same_type_p (TYPE_MAIN_VARIANT (t1), long_double_type_node)
00455 || same_type_p (TYPE_MAIN_VARIANT (t2), long_double_type_node))
00456 return build_type_attribute_variant (long_double_type_node,
00457 attributes);
00458 if (same_type_p (TYPE_MAIN_VARIANT (t1), double_type_node)
00459 || same_type_p (TYPE_MAIN_VARIANT (t2), double_type_node))
00460 return build_type_attribute_variant (double_type_node,
00461 attributes);
00462 if (same_type_p (TYPE_MAIN_VARIANT (t1), float_type_node)
00463 || same_type_p (TYPE_MAIN_VARIANT (t2), float_type_node))
00464 return build_type_attribute_variant (float_type_node,
00465 attributes);
00466
00467
00468
00469
00470
00471
00472 return build_type_attribute_variant (t1, attributes);
00473 }
00474 }
00475
00476
00477
00478
00479
00480 tree
00481 composite_pointer_type (t1, t2, arg1, arg2, location)
00482 tree t1;
00483 tree t2;
00484 tree arg1;
00485 tree arg2;
00486 const char* location;
00487 {
00488 tree result_type;
00489 tree attributes;
00490
00491
00492
00493
00494
00495 if (null_ptr_cst_p (arg1))
00496 return t2;
00497 if (null_ptr_cst_p (arg2))
00498 return t1;
00499
00500
00501
00502 if (TYPE_PTRMEMFUNC_P (t1))
00503 t1 = TYPE_PTRMEMFUNC_FN_TYPE (t1);
00504 if (TYPE_PTRMEMFUNC_P (t2))
00505 t2 = TYPE_PTRMEMFUNC_FN_TYPE (t2);
00506
00507
00508 attributes = (*targetm.merge_type_attributes) (t1, t2);
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520 if (VOID_TYPE_P (TREE_TYPE (t2)))
00521 {
00522 tree t;
00523 t = t1;
00524 t1 = t2;
00525 t2 = t;
00526 }
00527
00528 if (VOID_TYPE_P (TREE_TYPE (t1)))
00529 {
00530 if (pedantic && TYPE_PTRFN_P (t2))
00531 pedwarn ("ISO C++ forbids %s between pointer of type `void *' and pointer-to-function", location);
00532 t1 = TREE_TYPE (t1);
00533 t2 = TREE_TYPE (t2);
00534 result_type = cp_build_qualified_type (void_type_node,
00535 (cp_type_quals (t1)
00536 | cp_type_quals (t2)));
00537 result_type = build_pointer_type (result_type);
00538 }
00539 else
00540 {
00541 tree full1 = qualify_type_recursive (t1, t2);
00542 tree full2 = qualify_type_recursive (t2, t1);
00543
00544 int val = comp_target_types (full1, full2, 1);
00545
00546 if (val > 0)
00547 result_type = full1;
00548 else if (val < 0)
00549 result_type = full2;
00550 else
00551 {
00552 pedwarn ("%s between distinct pointer types `%T' and `%T' lacks a cast",
00553 location, t1, t2);
00554 result_type = ptr_type_node;
00555 }
00556 }
00557
00558 return build_type_attribute_variant (result_type, attributes);
00559 }
00560
00561
00562
00563
00564
00565
00566
00567
00568 tree
00569 merge_types (t1, t2)
00570 tree t1, t2;
00571 {
00572 register enum tree_code code1;
00573 register enum tree_code code2;
00574 tree attributes;
00575
00576
00577 if (t1 == t2)
00578 return t1;
00579 if (original_type (t1) == original_type (t2))
00580 return t1;
00581
00582
00583 if (t1 == error_mark_node)
00584 return t2;
00585 if (t2 == error_mark_node)
00586 return t1;
00587
00588
00589 attributes = (*targetm.merge_type_attributes) (t1, t2);
00590
00591
00592
00593 if (TYPE_PTRMEMFUNC_P (t1))
00594 t1 = TYPE_PTRMEMFUNC_FN_TYPE (t1);
00595 if (TYPE_PTRMEMFUNC_P (t2))
00596 t2 = TYPE_PTRMEMFUNC_FN_TYPE (t2);
00597
00598 code1 = TREE_CODE (t1);
00599 code2 = TREE_CODE (t2);
00600
00601 switch (code1)
00602 {
00603 case POINTER_TYPE:
00604 case REFERENCE_TYPE:
00605
00606 {
00607 tree target = merge_types (TREE_TYPE (t1), TREE_TYPE (t2));
00608 int quals = cp_type_quals (t1);
00609
00610 if (code1 == POINTER_TYPE)
00611 t1 = build_pointer_type (target);
00612 else
00613 t1 = build_reference_type (target);
00614 t1 = build_type_attribute_variant (t1, attributes);
00615 t1 = cp_build_qualified_type (t1, quals);
00616
00617 if (TREE_CODE (target) == METHOD_TYPE)
00618 t1 = build_ptrmemfunc_type (t1);
00619
00620 return t1;
00621 }
00622
00623 case OFFSET_TYPE:
00624 {
00625 tree base = TYPE_OFFSET_BASETYPE (t1);
00626 tree target = merge_types (TREE_TYPE (t1), TREE_TYPE (t2));
00627 t1 = build_offset_type (base, target);
00628 break;
00629 }
00630
00631 case ARRAY_TYPE:
00632 {
00633 tree elt = merge_types (TREE_TYPE (t1), TREE_TYPE (t2));
00634
00635 if (elt == TREE_TYPE (t1) && TYPE_DOMAIN (t1))
00636 return build_type_attribute_variant (t1, attributes);
00637 if (elt == TREE_TYPE (t2) && TYPE_DOMAIN (t2))
00638 return build_type_attribute_variant (t2, attributes);
00639
00640 t1 = build_cplus_array_type
00641 (elt, TYPE_DOMAIN (TYPE_DOMAIN (t1) ? t1 : t2));
00642 break;
00643 }
00644
00645 case FUNCTION_TYPE:
00646
00647
00648 {
00649 tree valtype = merge_types (TREE_TYPE (t1), TREE_TYPE (t2));
00650 tree p1 = TYPE_ARG_TYPES (t1);
00651 tree p2 = TYPE_ARG_TYPES (t2);
00652 tree rval, raises;
00653
00654
00655 if (valtype == TREE_TYPE (t1) && ! p2)
00656 return build_type_attribute_variant (t1, attributes);
00657 if (valtype == TREE_TYPE (t2) && ! p1)
00658 return build_type_attribute_variant (t2, attributes);
00659
00660
00661 if (p1 == NULL_TREE || TREE_VALUE (p1) == void_type_node)
00662 {
00663 rval = build_function_type (valtype, p2);
00664 if ((raises = TYPE_RAISES_EXCEPTIONS (t2)))
00665 rval = build_exception_variant (rval, raises);
00666 return build_type_attribute_variant (rval, attributes);
00667 }
00668 raises = TYPE_RAISES_EXCEPTIONS (t1);
00669 if (p2 == NULL_TREE || TREE_VALUE (p2) == void_type_node)
00670 {
00671 rval = build_function_type (valtype, p1);
00672 if (raises)
00673 rval = build_exception_variant (rval, raises);
00674 return build_type_attribute_variant (rval, attributes);
00675 }
00676
00677 rval = build_function_type (valtype, commonparms (p1, p2));
00678 t1 = build_exception_variant (rval, raises);
00679 break;
00680 }
00681
00682 case METHOD_TYPE:
00683 {
00684
00685
00686 tree basetype = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t2)));
00687 tree raises = TYPE_RAISES_EXCEPTIONS (t1);
00688 tree t3;
00689
00690
00691
00692
00693 t1 = build_function_type (TREE_TYPE (t1),
00694 TREE_CHAIN (TYPE_ARG_TYPES (t1)));
00695 t2 = build_function_type (TREE_TYPE (t2),
00696 TREE_CHAIN (TYPE_ARG_TYPES (t2)));
00697 t3 = merge_types (t1, t2);
00698 t3 = build_cplus_method_type (basetype, TREE_TYPE (t3),
00699 TYPE_ARG_TYPES (t3));
00700 t1 = build_exception_variant (t3, raises);
00701 break;
00702 }
00703
00704 default:;
00705 }
00706 return build_type_attribute_variant (t1, attributes);
00707 }
00708
00709
00710
00711
00712
00713
00714
00715
00716 tree
00717 common_type (t1, t2)
00718 tree t1, t2;
00719 {
00720 enum tree_code code1;
00721 enum tree_code code2;
00722
00723
00724 if (t1 == error_mark_node || t2 == error_mark_node)
00725 return error_mark_node;
00726
00727 code1 = TREE_CODE (t1);
00728 code2 = TREE_CODE (t2);
00729
00730 if ((ARITHMETIC_TYPE_P (t1) || code1 == ENUMERAL_TYPE
00731 || code1 == COMPLEX_TYPE)
00732 && (ARITHMETIC_TYPE_P (t2) || code2 == ENUMERAL_TYPE
00733 || code2 == COMPLEX_TYPE))
00734 return type_after_usual_arithmetic_conversions (t1, t2);
00735
00736 else if ((TYPE_PTR_P (t1) && TYPE_PTR_P (t2))
00737 || (TYPE_PTRMEM_P (t1) && TYPE_PTRMEM_P (t2))
00738 || (TYPE_PTRMEMFUNC_P (t1) && TYPE_PTRMEMFUNC_P (t2)))
00739 return composite_pointer_type (t1, t2, error_mark_node, error_mark_node,
00740 "conversion");
00741
00742 else
00743 abort ();
00744 }
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761 static int
00762 comp_except_types (a, b, exact)
00763 tree a, b;
00764 int exact;
00765 {
00766 if (same_type_p (a, b))
00767 return 1;
00768 else if (!exact)
00769 {
00770 if (cp_type_quals (a) || cp_type_quals (b))
00771 return 0;
00772
00773 if (TREE_CODE (a) == POINTER_TYPE
00774 && TREE_CODE (b) == POINTER_TYPE)
00775 {
00776 a = TREE_TYPE (a);
00777 b = TREE_TYPE (b);
00778 if (cp_type_quals (a) || cp_type_quals (b))
00779 return 0;
00780 }
00781
00782 if (TREE_CODE (a) != RECORD_TYPE
00783 || TREE_CODE (b) != RECORD_TYPE)
00784 return 0;
00785
00786 if (ACCESSIBLY_UNIQUELY_DERIVED_P (a, b))
00787 return 2;
00788 }
00789 return 0;
00790 }
00791
00792
00793
00794
00795
00796
00797
00798 int
00799 comp_except_specs (t1, t2, exact)
00800 tree t1, t2;
00801 int exact;
00802 {
00803 tree probe;
00804 tree base;
00805 int length = 0;
00806
00807 if (t1 == t2)
00808 return 1;
00809
00810 if (t1 == NULL_TREE)
00811 return t2 == NULL_TREE || !exact;
00812 if (!TREE_VALUE (t1))
00813 return t2 != NULL_TREE && !TREE_VALUE (t2);
00814 if (t2 == NULL_TREE)
00815 return 0;
00816 if (TREE_VALUE (t1) && !TREE_VALUE (t2))
00817 return !exact;
00818
00819
00820
00821
00822
00823 for (base = t1; t2 != NULL_TREE; t2 = TREE_CHAIN (t2))
00824 {
00825 for (probe = base; probe != NULL_TREE; probe = TREE_CHAIN (probe))
00826 {
00827 tree a = TREE_VALUE (probe);
00828 tree b = TREE_VALUE (t2);
00829
00830 if (comp_except_types (a, b, exact))
00831 {
00832 if (probe == base && exact)
00833 base = TREE_CHAIN (probe);
00834 length++;
00835 break;
00836 }
00837 }
00838 if (probe == NULL_TREE)
00839 return 0;
00840 }
00841 return !exact || base == NULL_TREE || length == list_length (t1);
00842 }
00843
00844
00845
00846
00847 static int
00848 comp_array_types (cmp, t1, t2, strict)
00849 register int (*cmp) PARAMS ((tree, tree, int));
00850 tree t1, t2;
00851 int strict;
00852 {
00853 tree d1;
00854 tree d2;
00855
00856 if (t1 == t2)
00857 return 1;
00858
00859
00860 if (!(TREE_TYPE (t1) == TREE_TYPE (t2)
00861 || (*cmp) (TREE_TYPE (t1), TREE_TYPE (t2),
00862 strict & ~COMPARE_REDECLARATION)))
00863 return 0;
00864
00865 d1 = TYPE_DOMAIN (t1);
00866 d2 = TYPE_DOMAIN (t2);
00867
00868 if (d1 == d2)
00869 return 1;
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883 if (!d1 || !d2)
00884 return strict & COMPARE_REDECLARATION;
00885
00886
00887 return (cp_tree_equal (TYPE_MIN_VALUE (d1),
00888 TYPE_MIN_VALUE (d2))
00889 && cp_tree_equal (TYPE_MAX_VALUE (d1),
00890 TYPE_MAX_VALUE (d2)));
00891 }
00892
00893
00894
00895
00896
00897 int
00898 comptypes (t1, t2, strict)
00899 tree t1;
00900 tree t2;
00901 int strict;
00902 {
00903 int attrval, val;
00904 int orig_strict = strict;
00905
00906
00907
00908
00909
00910
00911
00912
00913 strict &= ~COMPARE_REDECLARATION;
00914
00915
00916 if (t1 == t2)
00917 return 1;
00918
00919
00920 my_friendly_assert (t1 != error_mark_node, 307);
00921
00922 if (t2 == error_mark_node)
00923 return 0;
00924
00925
00926
00927 if (TREE_CODE (t1) == INTEGER_TYPE && TYPE_IS_SIZETYPE (t1)
00928 && TYPE_DOMAIN (t1) != 0)
00929 t1 = TYPE_DOMAIN (t1);
00930
00931 if (TREE_CODE (t2) == INTEGER_TYPE && TYPE_IS_SIZETYPE (t2)
00932 && TYPE_DOMAIN (t2) != 0)
00933 t2 = TYPE_DOMAIN (t2);
00934
00935 if (strict & COMPARE_RELAXED)
00936 {
00937
00938
00939 if (TREE_CODE (t1) == ENUMERAL_TYPE)
00940 t1 = c_common_type_for_size (TYPE_PRECISION (t1), 1);
00941 if (TREE_CODE (t2) == ENUMERAL_TYPE)
00942 t2 = c_common_type_for_size (TYPE_PRECISION (t2), 1);
00943
00944 if (t1 == t2)
00945 return 1;
00946 }
00947
00948 if (TYPE_PTRMEMFUNC_P (t1))
00949 t1 = TYPE_PTRMEMFUNC_FN_TYPE (t1);
00950 if (TYPE_PTRMEMFUNC_P (t2))
00951 t2 = TYPE_PTRMEMFUNC_FN_TYPE (t2);
00952
00953
00954 if (TREE_CODE (t1) != TREE_CODE (t2))
00955 return 0;
00956
00957
00958 if (cp_type_quals (t1) != cp_type_quals (t2))
00959 return 0;
00960 if (strict == COMPARE_STRICT
00961 && TYPE_FOR_JAVA (t1) != TYPE_FOR_JAVA (t2))
00962 return 0;
00963
00964
00965
00966
00967
00968 if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
00969 return 1;
00970
00971 if (strict & COMPARE_NO_ATTRIBUTES)
00972 attrval = 1;
00973
00974 else if (! (attrval = (*targetm.comp_type_attributes) (t1, t2)))
00975 return 0;
00976
00977
00978 val = 0;
00979
00980 switch (TREE_CODE (t1))
00981 {
00982 case TEMPLATE_TEMPLATE_PARM:
00983 case BOUND_TEMPLATE_TEMPLATE_PARM:
00984 if (TEMPLATE_TYPE_IDX (t1) != TEMPLATE_TYPE_IDX (t2)
00985 || TEMPLATE_TYPE_LEVEL (t1) != TEMPLATE_TYPE_LEVEL (t2))
00986 return 0;
00987 if (! comp_template_parms
00988 (DECL_TEMPLATE_PARMS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (t1)),
00989 DECL_TEMPLATE_PARMS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (t2))))
00990 return 0;
00991 if (TREE_CODE (t1) == TEMPLATE_TEMPLATE_PARM)
00992 return 1;
00993
00994 strict = COMPARE_STRICT;
00995
00996
00997 case RECORD_TYPE:
00998 case UNION_TYPE:
00999 if (TYPE_TEMPLATE_INFO (t1) && TYPE_TEMPLATE_INFO (t2)
01000 && (TYPE_TI_TEMPLATE (t1) == TYPE_TI_TEMPLATE (t2)
01001 || TREE_CODE (t1) == BOUND_TEMPLATE_TEMPLATE_PARM))
01002 val = comp_template_args (TYPE_TI_ARGS (t1),
01003 TYPE_TI_ARGS (t2));
01004 look_hard:
01005 if ((strict & COMPARE_BASE) && DERIVED_FROM_P (t1, t2))
01006 val = 1;
01007 else if ((strict & COMPARE_RELAXED) && DERIVED_FROM_P (t2, t1))
01008 val = 1;
01009 break;
01010
01011 case OFFSET_TYPE:
01012 val = (comptypes (build_pointer_type (TYPE_OFFSET_BASETYPE (t1)),
01013 build_pointer_type (TYPE_OFFSET_BASETYPE (t2)), strict)
01014 && comptypes (TREE_TYPE (t1), TREE_TYPE (t2), strict));
01015 break;
01016
01017 case POINTER_TYPE:
01018 case REFERENCE_TYPE:
01019 t1 = TREE_TYPE (t1);
01020 t2 = TREE_TYPE (t2);
01021
01022
01023 val = comptypes (t1, t2, strict);
01024 if (val)
01025 break;
01026 if (TREE_CODE (t1) == RECORD_TYPE
01027 && TREE_CODE (t2) == RECORD_TYPE)
01028 goto look_hard;
01029 break;
01030
01031 case METHOD_TYPE:
01032 case FUNCTION_TYPE:
01033 val = ((TREE_TYPE (t1) == TREE_TYPE (t2)
01034 || comptypes (TREE_TYPE (t1), TREE_TYPE (t2), strict))
01035 && compparms (TYPE_ARG_TYPES (t1), TYPE_ARG_TYPES (t2)));
01036 break;
01037
01038 case ARRAY_TYPE:
01039
01040
01041
01042 val = comp_array_types (comptypes, t1, t2, orig_strict);
01043 break;
01044
01045 case TEMPLATE_TYPE_PARM:
01046 return TEMPLATE_TYPE_IDX (t1) == TEMPLATE_TYPE_IDX (t2)
01047 && TEMPLATE_TYPE_LEVEL (t1) == TEMPLATE_TYPE_LEVEL (t2);
01048
01049 case TYPENAME_TYPE:
01050 if (cp_tree_equal (TYPENAME_TYPE_FULLNAME (t1),
01051 TYPENAME_TYPE_FULLNAME (t2)) < 1)
01052 return 0;
01053 return same_type_p (TYPE_CONTEXT (t1), TYPE_CONTEXT (t2));
01054
01055 case UNBOUND_CLASS_TEMPLATE:
01056 if (cp_tree_equal (TYPE_IDENTIFIER (t1),
01057 TYPE_IDENTIFIER (t2)) < 1)
01058 return 0;
01059 return same_type_p (TYPE_CONTEXT (t1), TYPE_CONTEXT (t2));
01060
01061 case COMPLEX_TYPE:
01062 return same_type_p (TREE_TYPE (t1), TREE_TYPE (t2));
01063
01064 default:
01065 break;
01066 }
01067 return attrval == 2 && val == 1 ? 2 : val;
01068 }
01069
01070
01071
01072
01073 static int
01074 comp_cv_target_types (ttl, ttr, nptrs)
01075 tree ttl, ttr;
01076 int nptrs;
01077 {
01078 int t;
01079
01080 if (!at_least_as_qualified_p (ttl, ttr)
01081 && !at_least_as_qualified_p (ttr, ttl))
01082
01083 return 0;
01084
01085 if (TYPE_MAIN_VARIANT (ttl) == TYPE_MAIN_VARIANT (ttr))
01086 return more_qualified_p (ttr, ttl) ? -1 : 1;
01087
01088 t = comp_target_types (ttl, ttr, nptrs);
01089 if ((t == 1 && at_least_as_qualified_p (ttl, ttr))
01090 || (t == -1 && at_least_as_qualified_p (ttr, ttl)))
01091 return t;
01092
01093 return 0;
01094 }
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108 int
01109 comp_target_types (ttl, ttr, nptrs)
01110 tree ttl, ttr;
01111 int nptrs;
01112 {
01113 ttl = TYPE_MAIN_VARIANT (ttl);
01114 ttr = TYPE_MAIN_VARIANT (ttr);
01115 if (same_type_p (ttl, ttr))
01116 return 1;
01117
01118 if (TREE_CODE (ttr) != TREE_CODE (ttl))
01119 return 0;
01120
01121 if ((TREE_CODE (ttr) == POINTER_TYPE
01122 || TREE_CODE (ttr) == REFERENCE_TYPE)
01123
01124
01125
01126
01127 && nptrs > 0)
01128 {
01129 int is_ptr = TREE_CODE (ttr) == POINTER_TYPE;
01130
01131 ttl = TREE_TYPE (ttl);
01132 ttr = TREE_TYPE (ttr);
01133
01134 if (is_ptr)
01135 {
01136 if (TREE_CODE (ttl) == UNKNOWN_TYPE
01137 || TREE_CODE (ttr) == UNKNOWN_TYPE)
01138 return 1;
01139 else if (TREE_CODE (ttl) == VOID_TYPE
01140 && TREE_CODE (ttr) != FUNCTION_TYPE
01141 && TREE_CODE (ttr) != METHOD_TYPE
01142 && TREE_CODE (ttr) != OFFSET_TYPE)
01143 return 1;
01144 else if (TREE_CODE (ttr) == VOID_TYPE
01145 && TREE_CODE (ttl) != FUNCTION_TYPE
01146 && TREE_CODE (ttl) != METHOD_TYPE
01147 && TREE_CODE (ttl) != OFFSET_TYPE)
01148 return -1;
01149 else if (TREE_CODE (ttl) == POINTER_TYPE
01150 || TREE_CODE (ttl) == ARRAY_TYPE)
01151 {
01152 if (comp_ptr_ttypes (ttl, ttr))
01153 return 1;
01154 else if (comp_ptr_ttypes (ttr, ttl))
01155 return -1;
01156 return 0;
01157 }
01158 }
01159
01160
01161
01162 if (TREE_CODE (ttl) == FUNCTION_TYPE || TREE_CODE (ttl) == METHOD_TYPE)
01163 return comp_target_types (ttl, ttr, nptrs - 1);
01164
01165 return comp_cv_target_types (ttl, ttr, nptrs - 1);
01166 }
01167
01168 if (TREE_CODE (ttr) == ARRAY_TYPE)
01169 return comp_array_types (comp_target_types, ttl, ttr, COMPARE_STRICT);
01170 else if (TREE_CODE (ttr) == FUNCTION_TYPE || TREE_CODE (ttr) == METHOD_TYPE)
01171 {
01172 tree argsl, argsr;
01173 int saw_contra = 0;
01174
01175 if (pedantic)
01176 {
01177 if (!same_type_p (TREE_TYPE (ttl), TREE_TYPE (ttr)))
01178 return 0;
01179 }
01180 else
01181 {
01182 switch (comp_target_types (TREE_TYPE (ttl), TREE_TYPE (ttr), -1))
01183 {
01184 case 0:
01185 return 0;
01186 case -1:
01187 saw_contra = 1;
01188 }
01189 }
01190
01191 argsl = TYPE_ARG_TYPES (ttl);
01192 argsr = TYPE_ARG_TYPES (ttr);
01193
01194
01195 if (TREE_CODE (ttr) == METHOD_TYPE)
01196 {
01197 tree tl = TYPE_METHOD_BASETYPE (ttl);
01198 tree tr = TYPE_METHOD_BASETYPE (ttr);
01199
01200 if (!same_or_base_type_p (tr, tl))
01201 {
01202 if (same_or_base_type_p (tl, tr))
01203 saw_contra = 1;
01204 else
01205 return 0;
01206 }
01207
01208 argsl = TREE_CHAIN (argsl);
01209 argsr = TREE_CHAIN (argsr);
01210 }
01211
01212 switch (comp_target_parms (argsl, argsr))
01213 {
01214 case 0:
01215 return 0;
01216 case -1:
01217 saw_contra = 1;
01218 }
01219
01220 return saw_contra ? -1 : 1;
01221 }
01222
01223 else if (TREE_CODE (ttr) == OFFSET_TYPE)
01224 {
01225 int base;
01226
01227
01228
01229
01230 if (same_or_base_type_p (TYPE_OFFSET_BASETYPE (ttr),
01231 TYPE_OFFSET_BASETYPE (ttl)))
01232 base = 1;
01233 else if (same_or_base_type_p (TYPE_OFFSET_BASETYPE (ttl),
01234 TYPE_OFFSET_BASETYPE (ttr)))
01235 {
01236 tree tmp = ttl;
01237 ttl = ttr;
01238 ttr = tmp;
01239 base = -1;
01240 }
01241 else
01242 return 0;
01243
01244 ttl = TREE_TYPE (ttl);
01245 ttr = TREE_TYPE (ttr);
01246
01247 if (TREE_CODE (ttl) == POINTER_TYPE
01248 || TREE_CODE (ttl) == ARRAY_TYPE)
01249 {
01250 if (comp_ptr_ttypes (ttl, ttr))
01251 return base;
01252 return 0;
01253 }
01254 else
01255 {
01256 if (comp_cv_target_types (ttl, ttr, nptrs) == 1)
01257 return base;
01258 return 0;
01259 }
01260 }
01261 else if (IS_AGGR_TYPE (ttl))
01262 {
01263 if (nptrs < 0)
01264 return 0;
01265 if (same_or_base_type_p (build_pointer_type (ttl),
01266 build_pointer_type (ttr)))
01267 return 1;
01268 if (same_or_base_type_p (build_pointer_type (ttr),
01269 build_pointer_type (ttl)))
01270 return -1;
01271 return 0;
01272 }
01273
01274 return 0;
01275 }
01276
01277
01278
01279 int
01280 at_least_as_qualified_p (type1, type2)
01281 tree type1;
01282 tree type2;
01283 {
01284
01285 return ((cp_type_quals (type1) & cp_type_quals (type2))
01286 == cp_type_quals (type2));
01287 }
01288
01289
01290
01291 int
01292 more_qualified_p (type1, type2)
01293 tree type1;
01294 tree type2;
01295 {
01296 return (cp_type_quals (type1) != cp_type_quals (type2)
01297 && at_least_as_qualified_p (type1, type2));
01298 }
01299
01300
01301
01302
01303 int
01304 comp_cv_qualification (type1, type2)
01305 tree type1;
01306 tree type2;
01307 {
01308 if (cp_type_quals (type1) == cp_type_quals (type2))
01309 return 0;
01310
01311 if (at_least_as_qualified_p (type1, type2))
01312 return 1;
01313
01314 else if (at_least_as_qualified_p (type2, type1))
01315 return -1;
01316
01317 return 0;
01318 }
01319
01320
01321
01322
01323
01324 int
01325 comp_cv_qual_signature (type1, type2)
01326 tree type1;
01327 tree type2;
01328 {
01329 if (comp_ptr_ttypes_real (type2, type1, -1))
01330 return 1;
01331 else if (comp_ptr_ttypes_real (type1, type2, -1))
01332 return -1;
01333 else
01334 return 0;
01335 }
01336
01337
01338
01339
01340
01341 static tree
01342 common_base_type (tt1, tt2)
01343 tree tt1, tt2;
01344 {
01345 tree best = NULL_TREE;
01346 int i;
01347
01348
01349 if (UNIQUELY_DERIVED_FROM_P (tt1, tt2))
01350 return tt1;
01351 if (UNIQUELY_DERIVED_FROM_P (tt2, tt1))
01352 return tt2;
01353
01354
01355
01356 for (i = CLASSTYPE_N_BASECLASSES (tt1)-1; i >= 0; i--)
01357 {
01358 tree basetype = TYPE_BINFO_BASETYPE (tt1, i);
01359 tree trial = common_base_type (basetype, tt2);
01360 if (trial)
01361 {
01362 if (trial == error_mark_node)
01363 return trial;
01364 if (best == NULL_TREE)
01365 best = trial;
01366 else if (best != trial)
01367 return error_mark_node;
01368 }
01369 }
01370
01371
01372 for (i = CLASSTYPE_N_BASECLASSES (tt2)-1; i >= 0; i--)
01373 {
01374 tree basetype = TYPE_BINFO_BASETYPE (tt2, i);
01375 tree trial = common_base_type (tt1, basetype);
01376 if (trial)
01377 {
01378 if (trial == error_mark_node)
01379 return trial;
01380 if (best == NULL_TREE)
01381 best = trial;
01382 else if (best != trial)
01383 return error_mark_node;
01384 }
01385 }
01386 return best;
01387 }
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398 int
01399 compparms (parms1, parms2)
01400 tree parms1, parms2;
01401 {
01402 register tree t1 = parms1, t2 = parms2;
01403
01404
01405
01406
01407 while (1)
01408 {
01409 if (t1 == 0 && t2 == 0)
01410 return 1;
01411
01412
01413 if (t1 == 0 || t2 == 0)
01414 return 0;
01415 if (!same_type_p (TREE_VALUE (t2), TREE_VALUE (t1)))
01416 return 0;
01417
01418 t1 = TREE_CHAIN (t1);
01419 t2 = TREE_CHAIN (t2);
01420 }
01421 }
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432 static int
01433 comp_target_parms (parms1, parms2)
01434 tree parms1, parms2;
01435 {
01436 register tree t1 = parms1, t2 = parms2;
01437 int warn_contravariance = 0;
01438
01439
01440
01441
01442
01443 if (t1 == 0 && t2 != 0)
01444 {
01445 pedwarn ("ISO C++ prohibits conversion from `%#T' to `(...)'",
01446 parms2);
01447 return self_promoting_args_p (t2);
01448 }
01449 if (t2 == 0)
01450 return self_promoting_args_p (t1);
01451
01452 for (; t1 || t2; t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2))
01453 {
01454 tree p1, p2;
01455
01456
01457
01458 if (t1 == 0 || t2 == 0)
01459 return 0;
01460 p1 = TREE_VALUE (t1);
01461 p2 = TREE_VALUE (t2);
01462 if (same_type_p (p1, p2))
01463 continue;
01464
01465 if (pedantic)
01466 return 0;
01467
01468 if ((TREE_CODE (p1) == POINTER_TYPE && TREE_CODE (p2) == POINTER_TYPE)
01469 || (TREE_CODE (p1) == REFERENCE_TYPE
01470 && TREE_CODE (p2) == REFERENCE_TYPE))
01471 {
01472
01473
01474 if (TREE_TYPE (p1) == void_type_node)
01475 continue;
01476 if (TREE_TYPE (p2) == void_type_node)
01477 {
01478 warn_contravariance = 1;
01479 continue;
01480 }
01481 if (IS_AGGR_TYPE (TREE_TYPE (p1))
01482 && !same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (p1),
01483 TREE_TYPE (p2)))
01484 return 0;
01485 }
01486
01487 if (comp_target_types (p2, p1, 1) <= 0)
01488 {
01489 if (comp_target_types (p1, p2, 1) > 0)
01490 {
01491 warn_contravariance = 1;
01492 continue;
01493 }
01494 return 0;
01495 }
01496 }
01497 return warn_contravariance ? -1 : 1;
01498 }
01499
01500 tree
01501 cxx_sizeof_or_alignof_type (type, op, complain)
01502 tree type;
01503 enum tree_code op;
01504 int complain;
01505 {
01506 enum tree_code type_code;
01507 tree value;
01508 const char *op_name;
01509
01510 my_friendly_assert (op == SIZEOF_EXPR || op == ALIGNOF_EXPR, 20020720);
01511 if (processing_template_decl)
01512 return build_min_nt (op, type);
01513
01514 op_name = operator_name_info[(int) op].name;
01515
01516 if (TREE_CODE (type) == REFERENCE_TYPE)
01517 type = TREE_TYPE (type);
01518 type_code = TREE_CODE (type);
01519
01520 if (type_code == METHOD_TYPE)
01521 {
01522 if (complain && (pedantic || warn_pointer_arith))
01523 pedwarn ("invalid application of `%s' to a member function", op_name);
01524 value = size_one_node;
01525 }
01526 else if (type_code == OFFSET_TYPE)
01527 {
01528 if (complain)
01529 error ("invalid application of `%s' to non-static member", op_name);
01530 value = size_zero_node;
01531 }
01532 else
01533 value = c_sizeof_or_alignof_type (complete_type (type), op, complain);
01534
01535 return value;
01536 }
01537
01538 tree
01539 expr_sizeof (e)
01540 tree e;
01541 {
01542 if (processing_template_decl)
01543 return build_min_nt (SIZEOF_EXPR, e);
01544
01545 if (TREE_CODE (e) == COMPONENT_REF
01546 && DECL_C_BIT_FIELD (TREE_OPERAND (e, 1)))
01547 error ("sizeof applied to a bit-field");
01548 if (is_overloaded_fn (e))
01549 {
01550 pedwarn ("ISO C++ forbids applying `sizeof' to an expression of function type");
01551 return c_sizeof (char_type_node);
01552 }
01553 else if (type_unknown_p (e))
01554 {
01555 cxx_incomplete_type_error (e, TREE_TYPE (e));
01556 return c_sizeof (char_type_node);
01557 }
01558
01559
01560
01561 else if (TREE_CODE (e) == OFFSET_REF)
01562 e = resolve_offset_ref (e);
01563
01564 if (e == error_mark_node)
01565 return e;
01566
01567 return cxx_sizeof (TREE_TYPE (e));
01568 }
01569
01570
01571
01572
01573
01574
01575
01576
01577 tree
01578 decay_conversion (exp)
01579 tree exp;
01580 {
01581 register tree type;
01582 register enum tree_code code;
01583
01584 if (TREE_CODE (exp) == OFFSET_REF)
01585 exp = resolve_offset_ref (exp);
01586
01587 type = TREE_TYPE (exp);
01588 code = TREE_CODE (type);
01589
01590 if (code == REFERENCE_TYPE)
01591 {
01592 exp = convert_from_reference (exp);
01593 type = TREE_TYPE (exp);
01594 code = TREE_CODE (type);
01595 }
01596
01597 if (type == error_mark_node)
01598 return error_mark_node;
01599
01600 if (type_unknown_p (exp))
01601 {
01602 cxx_incomplete_type_error (exp, TREE_TYPE (exp));
01603 return error_mark_node;
01604 }
01605
01606
01607 if (TREE_CODE (exp) == CONST_DECL)
01608 exp = DECL_INITIAL (exp);
01609
01610
01611
01612
01613 else if (code != ARRAY_TYPE)
01614 {
01615 exp = decl_constant_value (exp);
01616 type = TREE_TYPE (exp);
01617 }
01618
01619
01620
01621
01622 if (code == VOID_TYPE)
01623 {
01624 error ("void value not ignored as it ought to be");
01625 return error_mark_node;
01626 }
01627 if (code == METHOD_TYPE)
01628 abort ();
01629 if (code == FUNCTION_TYPE || is_overloaded_fn (exp))
01630 return build_unary_op (ADDR_EXPR, exp, 0);
01631 if (code == ARRAY_TYPE)
01632 {
01633 register tree adr;
01634 tree ptrtype;
01635
01636 if (TREE_CODE (exp) == INDIRECT_REF)
01637 {
01638
01639
01640 tree inner = TREE_OPERAND (exp, 0);
01641 if (TREE_CODE (TREE_TYPE (inner)) == REFERENCE_TYPE)
01642 {
01643 inner = build1 (CONVERT_EXPR,
01644 build_pointer_type (TREE_TYPE
01645 (TREE_TYPE (inner))),
01646 inner);
01647 TREE_CONSTANT (inner) = TREE_CONSTANT (TREE_OPERAND (inner, 0));
01648 }
01649 return cp_convert (build_pointer_type (TREE_TYPE (type)), inner);
01650 }
01651
01652 if (TREE_CODE (exp) == COMPOUND_EXPR)
01653 {
01654 tree op1 = decay_conversion (TREE_OPERAND (exp, 1));
01655 return build (COMPOUND_EXPR, TREE_TYPE (op1),
01656 TREE_OPERAND (exp, 0), op1);
01657 }
01658
01659 if (!lvalue_p (exp)
01660 && ! (TREE_CODE (exp) == CONSTRUCTOR && TREE_STATIC (exp)))
01661 {
01662 error ("invalid use of non-lvalue array");
01663 return error_mark_node;
01664 }
01665
01666 ptrtype = build_pointer_type (TREE_TYPE (type));
01667
01668 if (TREE_CODE (exp) == VAR_DECL)
01669 {
01670
01671
01672
01673
01674 adr = build1 (ADDR_EXPR, ptrtype, exp);
01675 if (!cxx_mark_addressable (exp))
01676 return error_mark_node;
01677 TREE_CONSTANT (adr) = staticp (exp);
01678 TREE_SIDE_EFFECTS (adr) = 0;
01679 return adr;
01680 }
01681
01682
01683 adr = build_unary_op (ADDR_EXPR, exp, 1);
01684 return cp_convert (ptrtype, adr);
01685 }
01686
01687
01688
01689 if (! CLASS_TYPE_P (type))
01690 exp = cp_convert (TYPE_MAIN_VARIANT (type), exp);
01691
01692 return exp;
01693 }
01694
01695 tree
01696 default_conversion (exp)
01697 tree exp;
01698 {
01699 tree type;
01700 enum tree_code code;
01701
01702 exp = decay_conversion (exp);
01703
01704 type = TREE_TYPE (exp);
01705 code = TREE_CODE (type);
01706
01707 if (INTEGRAL_CODE_P (code))
01708 {
01709 tree t = type_promotes_to (type);
01710 if (t != type)
01711 return cp_convert (t, exp);
01712 }
01713
01714 return exp;
01715 }
01716
01717
01718
01719
01720 tree
01721 inline_conversion (exp)
01722 tree exp;
01723 {
01724 if (TREE_CODE (exp) == FUNCTION_DECL)
01725 exp = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (exp)), exp);
01726
01727 return exp;
01728 }
01729
01730
01731
01732
01733 int
01734 string_conv_p (totype, exp, warn)
01735 tree totype, exp;
01736 int warn;
01737 {
01738 tree t;
01739
01740 if (! flag_const_strings || TREE_CODE (totype) != POINTER_TYPE)
01741 return 0;
01742
01743 t = TREE_TYPE (totype);
01744 if (!same_type_p (t, char_type_node)
01745 && !same_type_p (t, wchar_type_node))
01746 return 0;
01747
01748 if (TREE_CODE (exp) == STRING_CST)
01749 {
01750
01751 if (!same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (exp))), t))
01752 return 0;
01753 }
01754 else
01755 {
01756
01757 t = build_pointer_type (build_qualified_type (t, TYPE_QUAL_CONST));
01758 if (!same_type_p (TREE_TYPE (exp), t))
01759 return 0;
01760 STRIP_NOPS (exp);
01761 if (TREE_CODE (exp) != ADDR_EXPR
01762 || TREE_CODE (TREE_OPERAND (exp, 0)) != STRING_CST)
01763 return 0;
01764 }
01765
01766
01767 if (warn && warn_write_strings)
01768 warning ("deprecated conversion from string constant to `%T'", totype);
01769
01770 return 1;
01771 }
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781 static tree
01782 rationalize_conditional_expr (code, t)
01783 enum tree_code code;
01784 tree t;
01785 {
01786
01787
01788
01789 if (TREE_CODE (t) == MIN_EXPR || TREE_CODE (t) == MAX_EXPR)
01790 {
01791 return
01792 build_conditional_expr (build_x_binary_op ((TREE_CODE (t) == MIN_EXPR
01793 ? LE_EXPR : GE_EXPR),
01794 TREE_OPERAND (t, 0),
01795 TREE_OPERAND (t, 1)),
01796 build_unary_op (code, TREE_OPERAND (t, 0), 0),
01797 build_unary_op (code, TREE_OPERAND (t, 1), 0));
01798 }
01799
01800 return
01801 build_conditional_expr (TREE_OPERAND (t, 0),
01802 build_unary_op (code, TREE_OPERAND (t, 1), 0),
01803 build_unary_op (code, TREE_OPERAND (t, 2), 0));
01804 }
01805
01806
01807
01808
01809
01810
01811 static tree
01812 lookup_anon_field (t, type)
01813 tree t, type;
01814 {
01815 tree field;
01816
01817 for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field))
01818 {
01819 if (TREE_STATIC (field))
01820 continue;
01821 if (TREE_CODE (field) != FIELD_DECL || DECL_ARTIFICIAL (field))
01822 continue;
01823
01824
01825 if (DECL_NAME (field) == NULL_TREE
01826 && type == TYPE_MAIN_VARIANT (TREE_TYPE (field)))
01827 {
01828 return field;
01829 }
01830
01831
01832 if (DECL_NAME (field) == NULL_TREE
01833 && ANON_AGGR_TYPE_P (TREE_TYPE (field)))
01834 {
01835 tree subfield = lookup_anon_field (TREE_TYPE (field), type);
01836 if (subfield)
01837 return subfield;
01838 }
01839 }
01840 return NULL_TREE;
01841 }
01842
01843
01844
01845
01846
01847
01848
01849
01850
01851
01852
01853
01854
01855 tree
01856 build_class_member_access_expr (tree object, tree member,
01857 tree access_path, bool preserve_reference)
01858 {
01859 tree object_type;
01860 tree member_scope;
01861 tree result = NULL_TREE;
01862
01863 if (object == error_mark_node || member == error_mark_node)
01864 return error_mark_node;
01865
01866 my_friendly_assert (DECL_P (member) || BASELINK_P (member),
01867 20020801);
01868
01869
01870
01871
01872 if (TREE_CODE (object) == COMPOUND_EXPR)
01873 {
01874 result = build_class_member_access_expr (TREE_OPERAND (object, 1),
01875 member, access_path,
01876 preserve_reference);
01877 return build (COMPOUND_EXPR, TREE_TYPE (result),
01878 TREE_OPERAND (object, 0), result);
01879 }
01880 else if (TREE_CODE (object) == COND_EXPR)
01881 return (build_conditional_expr
01882 (TREE_OPERAND (object, 0),
01883 build_class_member_access_expr (TREE_OPERAND (object, 1),
01884 member, access_path,
01885 preserve_reference),
01886 build_class_member_access_expr (TREE_OPERAND (object, 2),
01887 member, access_path,
01888 preserve_reference)));
01889
01890
01891
01892
01893
01894 object_type = TREE_TYPE (object);
01895 if (!complete_type_or_else (object_type, object))
01896 return error_mark_node;
01897 if (!CLASS_TYPE_P (object_type))
01898 {
01899 error ("request for member `%D' in `%E', which is of non-class type `%T'",
01900 member, object, object_type);
01901 return error_mark_node;
01902 }
01903
01904
01905
01906
01907 if (DECL_P (member))
01908 {
01909 member_scope = DECL_CLASS_CONTEXT (member);
01910 mark_used (member);
01911 if (TREE_DEPRECATED (member))
01912 warn_deprecated_use (member);
01913 }
01914 else
01915 member_scope = BINFO_TYPE (BASELINK_BINFO (member));
01916
01917
01918
01919 while (ANON_AGGR_TYPE_P (member_scope)
01920 && !same_type_ignoring_top_level_qualifiers_p (member_scope,
01921 object_type))
01922 member_scope = TYPE_CONTEXT (member_scope);
01923 if (!member_scope || !DERIVED_FROM_P (member_scope, object_type))
01924 {
01925 error ("`%D' is not a member of `%T'", member, object_type);
01926 return error_mark_node;
01927 }
01928
01929
01930
01931 if (TREE_CODE (member) == VAR_DECL)
01932 {
01933
01934 result = member;
01935
01936 if (TREE_SIDE_EFFECTS (object))
01937 result = build (COMPOUND_EXPR, TREE_TYPE (result), object, result);
01938 }
01939 else if (TREE_CODE (member) == FIELD_DECL)
01940 {
01941
01942 bool null_object_p;
01943 int type_quals;
01944 tree member_type;
01945
01946 null_object_p = (TREE_CODE (object) == INDIRECT_REF
01947 && integer_zerop (TREE_OPERAND (object, 0)));
01948
01949
01950 if (!same_type_p (TYPE_MAIN_VARIANT (object_type),
01951 TYPE_MAIN_VARIANT (member_scope)))
01952 {
01953 tree binfo;
01954 base_kind kind;
01955
01956 binfo = lookup_base (access_path ? access_path : object_type,
01957 member_scope, ba_ignore, &kind);
01958 if (binfo == error_mark_node)
01959 return error_mark_node;
01960
01961
01962
01963
01964 if (null_object_p && kind == bk_via_virtual)
01965 {
01966 error ("invalid access to non-static data member `%D' of NULL object",
01967 member);
01968 error ("(perhaps the `offsetof' macro was used incorrectly)");
01969 return error_mark_node;
01970 }
01971
01972
01973 object = build_base_path (PLUS_EXPR, object, binfo,
01974 1);
01975
01976
01977 my_friendly_assert (object != error_mark_node,
01978 20020801);
01979 }
01980
01981
01982
01983
01984
01985 if (null_object_p && CLASSTYPE_NON_POD_P (object_type))
01986 {
01987 warning ("invalid access to non-static data member `%D' of NULL object",
01988 member);
01989 warning ("(perhaps the `offsetof' macro was used incorrectly)");
01990 }
01991
01992
01993
01994
01995
01996 if (ANON_AGGR_TYPE_P (DECL_CONTEXT (member))
01997
01998
01999
02000
02001
02002
02003 && (!same_type_ignoring_top_level_qualifiers_p
02004 (TREE_TYPE (object), DECL_CONTEXT (member))))
02005 {
02006 tree anonymous_union;
02007
02008 anonymous_union = lookup_anon_field (TREE_TYPE (object),
02009 DECL_CONTEXT (member));
02010 object = build_class_member_access_expr (object,
02011 anonymous_union,
02012 NULL_TREE,
02013 preserve_reference);
02014 }
02015
02016
02017 type_quals = TYPE_UNQUALIFIED;
02018 member_type = TREE_TYPE (member);
02019 if (TREE_CODE (member_type) != REFERENCE_TYPE)
02020 {
02021 type_quals = (cp_type_quals (member_type)
02022 | cp_type_quals (object_type));
02023
02024
02025
02026
02027 if (DECL_MUTABLE_P (member))
02028 type_quals &= ~TYPE_QUAL_CONST;
02029 member_type = cp_build_qualified_type (member_type, type_quals);
02030 }
02031
02032 result = fold (build (COMPONENT_REF, member_type, object, member));
02033
02034
02035
02036
02037 if (type_quals & TYPE_QUAL_CONST)
02038 TREE_READONLY (result) = 1;
02039 else if (type_quals & TYPE_QUAL_VOLATILE)
02040 TREE_THIS_VOLATILE (result) = 1;
02041 }
02042 else if (BASELINK_P (member))
02043 {
02044
02045 tree functions;
02046
02047
02048
02049
02050 functions = BASELINK_FUNCTIONS (member);
02051 if (TREE_CODE (functions) == FUNCTION_DECL
02052 && DECL_STATIC_FUNCTION_P (functions))
02053 {
02054
02055 result = functions;
02056 mark_used (result);
02057
02058 if (TREE_SIDE_EFFECTS (object))
02059 result = build (COMPOUND_EXPR, TREE_TYPE (result),
02060 object, result);
02061 }
02062 else
02063
02064
02065 result = build (COMPONENT_REF, unknown_type_node, object, member);
02066 }
02067 else if (TREE_CODE (member) == CONST_DECL)
02068 {
02069
02070 result = member;
02071
02072 if (TREE_SIDE_EFFECTS (object))
02073 result = build (COMPOUND_EXPR, TREE_TYPE (result),
02074 object, result);
02075 }
02076 else
02077 {
02078 error ("invalid use of `%D'", member);
02079 return error_mark_node;
02080 }
02081
02082 if (!preserve_reference)
02083
02084
02085
02086
02087 result = convert_from_reference (result);
02088
02089 return result;
02090 }
02091
02092
02093
02094
02095
02096
02097
02098
02099
02100 tree
02101 finish_class_member_access_expr (tree object, tree name)
02102 {
02103 tree object_type;
02104 tree member;
02105 tree access_path = NULL_TREE;
02106
02107 if (object == error_mark_node || name == error_mark_node)
02108 return error_mark_node;
02109
02110 if (processing_template_decl)
02111 return build_min_nt (COMPONENT_REF, object, name);
02112
02113 if (TREE_CODE (object) == OFFSET_REF)
02114 object = resolve_offset_ref (object);
02115
02116 object_type = TREE_TYPE (object);
02117 if (TREE_CODE (object_type) == REFERENCE_TYPE)
02118 {
02119 object = convert_from_reference (object);
02120 object_type = TREE_TYPE (object);
02121 }
02122
02123
02124
02125
02126
02127 if (!complete_type_or_else (object_type, object))
02128 return error_mark_node;
02129 if (!CLASS_TYPE_P (object_type))
02130 {
02131 error ("request for member `%D' in `%E', which is of non-class type `%T'",
02132 name, object, object_type);
02133 return error_mark_node;
02134 }
02135
02136 if (BASELINK_P (name))
02137 {
02138
02139 my_friendly_assert ((TREE_CODE (BASELINK_FUNCTIONS (name))
02140 == TEMPLATE_ID_EXPR),
02141 20020805);
02142 member = name;
02143 }
02144 else
02145 {
02146 bool is_template_id = false;
02147 tree template_args = NULL_TREE;
02148
02149 if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
02150 {
02151 is_template_id = true;
02152 template_args = TREE_OPERAND (name, 1);
02153 name = TREE_OPERAND (name, 0);
02154 }
02155
02156 if (TREE_CODE (name) == SCOPE_REF)
02157 {
02158 tree scope;
02159
02160
02161
02162
02163
02164 scope = TREE_OPERAND (name, 0);
02165 name = TREE_OPERAND (name, 1);
02166 my_friendly_assert ((CLASS_TYPE_P (scope)
02167 || TREE_CODE (scope) == NAMESPACE_DECL),
02168 20020804);
02169 my_friendly_assert ((TREE_CODE (name) == IDENTIFIER_NODE
02170 || TREE_CODE (name) == BIT_NOT_EXPR),
02171 20020804);
02172
02173
02174
02175 if (TREE_CODE (scope) == NAMESPACE_DECL)
02176 {
02177 error ("`%D::%D' is not a member of `%T'",
02178 scope, name, object_type);
02179 return error_mark_node;
02180 }
02181
02182
02183 access_path = lookup_base (object_type, scope, ba_check, NULL);
02184 if (!access_path || access_path == error_mark_node)
02185 return error_mark_node;
02186
02187
02188 member = lookup_member (access_path, name, 1,
02189 0);
02190 if (member == NULL_TREE)
02191 {
02192 error ("'%D' has no member named '%E'", object_type, name);
02193 return error_mark_node;
02194 }
02195 else if (member == error_mark_node)
02196 return error_mark_node;
02197 }
02198 else if (TREE_CODE (name) == BIT_NOT_EXPR)
02199 {
02200
02201 if (TYPE_IDENTIFIER (object_type) != TREE_OPERAND (name, 0))
02202 {
02203 error ("destructor specifier `%T::~%T' must have matching names",
02204 object_type, TREE_OPERAND (name, 0));
02205 return error_mark_node;
02206 }
02207 if (! TYPE_HAS_DESTRUCTOR (object_type))
02208 {
02209 error ("type `%T' has no destructor", object_type);
02210 return error_mark_node;
02211 }
02212 member = CLASSTYPE_DESTRUCTORS (object_type);
02213 }
02214 else if (TREE_CODE (name) == IDENTIFIER_NODE)
02215 {
02216
02217 member = lookup_member (object_type, name, 1,
02218 0);
02219 if (member == NULL_TREE)
02220 {
02221 error ("'%D' has no member named '%E'", object_type, name);
02222 return error_mark_node;
02223 }
02224 else if (member == error_mark_node)
02225 return error_mark_node;
02226 }
02227 else
02228 {
02229
02230
02231
02232
02233 error ("invalid use of `%D'", name);
02234 return error_mark_node;
02235 }
02236
02237 if (is_template_id)
02238 {
02239 tree template = member;
02240
02241 if (BASELINK_P (template))
02242 BASELINK_FUNCTIONS (template)
02243 = build_nt (TEMPLATE_ID_EXPR,
02244 BASELINK_FUNCTIONS (template),
02245 template_args);
02246 else
02247 {
02248 error ("`%D' is not a member template function", name);
02249 return error_mark_node;
02250 }
02251 }
02252 }
02253
02254 return build_class_member_access_expr (object, member, access_path,
02255 false);
02256 }
02257
02258
02259
02260
02261
02262
02263
02264
02265 tree
02266 build_ptrmemfunc_access_expr (tree ptrmem, tree member_name)
02267 {
02268 tree ptrmem_type;
02269 tree member;
02270 tree member_type;
02271
02272
02273
02274
02275
02276 ptrmem_type = TREE_TYPE (ptrmem);
02277 my_friendly_assert (TYPE_PTRMEMFUNC_P (ptrmem_type), 20020804);
02278 member = lookup_member (ptrmem_type, member_name, 0,
02279 0);
02280 member_type = cp_build_qualified_type (TREE_TYPE (member),
02281 cp_type_quals (ptrmem_type));
02282 return fold (build (COMPONENT_REF, member_type, ptrmem, member));
02283 }
02284
02285
02286
02287
02288
02289
02290
02291
02292 tree
02293 build_x_indirect_ref (ptr, errorstring)
02294 tree ptr;
02295 const char *errorstring;
02296 {
02297 tree rval;
02298
02299 if (processing_template_decl)
02300 return build_min_nt (INDIRECT_REF, ptr);
02301
02302 rval = build_opfncall (INDIRECT_REF, LOOKUP_NORMAL, ptr, NULL_TREE,
02303 NULL_TREE);
02304 if (rval)
02305 return rval;
02306 return build_indirect_ref (ptr, errorstring);
02307 }
02308
02309 tree
02310 build_indirect_ref (ptr, errorstring)
02311 tree ptr;
02312 const char *errorstring;
02313 {
02314 register tree pointer, type;
02315
02316 if (ptr == error_mark_node)
02317 return error_mark_node;
02318
02319 if (ptr == current_class_ptr)
02320 return current_class_ref;
02321
02322 pointer = (TREE_CODE (TREE_TYPE (ptr)) == REFERENCE_TYPE
02323 ? ptr : default_conversion (ptr));
02324 type = TREE_TYPE (pointer);
02325
02326 if (TYPE_PTR_P (type) || TREE_CODE (type) == REFERENCE_TYPE)
02327 {
02328
02329
02330
02331
02332
02333
02334
02335
02336 tree t = canonical_type_variant (TREE_TYPE (type));
02337
02338 if (VOID_TYPE_P (t))
02339 {
02340
02341
02342 error ("`%T' is not a pointer-to-object type", type);
02343 return error_mark_node;
02344 }
02345 else if (TREE_CODE (pointer) == ADDR_EXPR
02346 && !flag_volatile
02347 && same_type_p (t, TREE_TYPE (TREE_OPERAND (pointer, 0))))
02348
02349
02350 return TREE_OPERAND (pointer, 0);
02351 else
02352 {
02353 tree ref = build1 (INDIRECT_REF, t, pointer);
02354
02355
02356
02357
02358 TREE_READONLY (ref) = CP_TYPE_CONST_P (t);
02359 TREE_THIS_VOLATILE (ref) = CP_TYPE_VOLATILE_P (t);
02360 TREE_SIDE_EFFECTS (ref)
02361 = (TREE_THIS_VOLATILE (ref) || TREE_SIDE_EFFECTS (pointer)
02362 || flag_volatile);
02363 return ref;
02364 }
02365 }
02366
02367
02368 else if (TYPE_PTRMEM_P (type) || TYPE_PTRMEMFUNC_P (type))
02369 error ("invalid use of `%s' on pointer to member", errorstring);
02370 else if (pointer != error_mark_node)
02371 {
02372 if (errorstring)
02373 error ("invalid type argument of `%s'", errorstring);
02374 else
02375 error ("invalid type argument");
02376 }
02377 return error_mark_node;
02378 }
02379
02380
02381
02382
02383
02384
02385
02386
02387
02388
02389
02390
02391
02392
02393 tree
02394 build_array_ref (array, idx)
02395 tree array, idx;
02396 {
02397 if (idx == 0)
02398 {
02399 error ("subscript missing in array reference");
02400 return error_mark_node;
02401 }
02402
02403 if (TREE_TYPE (array) == error_mark_node
02404 || TREE_TYPE (idx) == error_mark_node)
02405 return error_mark_node;
02406
02407
02408
02409 switch (TREE_CODE (array))
02410 {
02411 case COMPOUND_EXPR:
02412 {
02413 tree value = build_array_ref (TREE_OPERAND (array, 1), idx);
02414 return build (COMPOUND_EXPR, TREE_TYPE (value),
02415 TREE_OPERAND (array, 0), value);
02416 }
02417
02418 case COND_EXPR:
02419 return build_conditional_expr
02420 (TREE_OPERAND (array, 0),
02421 build_array_ref (TREE_OPERAND (array, 1), idx),
02422 build_array_ref (TREE_OPERAND (array, 2), idx));
02423
02424 default:
02425 break;
02426 }
02427
02428 if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE
02429 && TREE_CODE (array) != INDIRECT_REF)
02430 {
02431 tree rval, type;
02432
02433
02434
02435
02436
02437
02438
02439 if (warn_char_subscripts
02440 && TYPE_MAIN_VARIANT (TREE_TYPE (idx)) == char_type_node)
02441 warning ("array subscript has type `char'");
02442
02443
02444 idx = default_conversion (idx);
02445
02446 if (TREE_CODE (TREE_TYPE (idx)) != INTEGER_TYPE)
02447 {
02448 error ("array subscript is not an integer");
02449 return error_mark_node;
02450 }
02451
02452
02453
02454
02455
02456 if (TREE_CODE (idx) != INTEGER_CST
02457 || (COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (array)))
02458 && (TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))))
02459 != INTEGER_CST)))
02460 {
02461 if (!cxx_mark_addressable (array))
02462 return error_mark_node;
02463 }
02464
02465
02466
02467
02468
02469 if (TREE_CODE (idx) == INTEGER_CST
02470 && TYPE_VALUES (TREE_TYPE (array))
02471 && ! int_fits_type_p (idx, TYPE_VALUES (TREE_TYPE (array))))
02472 {
02473 if (!cxx_mark_addressable (array))
02474 return error_mark_node;
02475 }
02476
02477 if (pedantic && !lvalue_p (array))
02478 pedwarn ("ISO C++ forbids subscripting non-lvalue array");
02479
02480
02481
02482
02483 if (extra_warnings)
02484 {
02485 tree foo = array;
02486 while (TREE_CODE (foo) == COMPONENT_REF)
02487 foo = TREE_OPERAND (foo, 0);
02488 if (TREE_CODE (foo) == VAR_DECL && DECL_REGISTER (foo))
02489 warning ("subscripting array declared `register'");
02490 }
02491
02492 type = TREE_TYPE (TREE_TYPE (array));
02493 rval = build (ARRAY_REF, type, array, idx);
02494
02495
02496 TREE_READONLY (rval)
02497 |= (CP_TYPE_CONST_P (type) | TREE_READONLY (array));
02498 TREE_SIDE_EFFECTS (rval)
02499 |= (CP_TYPE_VOLATILE_P (type) | TREE_SIDE_EFFECTS (array));
02500 TREE_THIS_VOLATILE (rval)
02501 |= (CP_TYPE_VOLATILE_P (type) | TREE_THIS_VOLATILE (array));
02502 return require_complete_type (fold (rval));
02503 }
02504
02505 {
02506 tree ar = default_conversion (array);
02507 tree ind = default_conversion (idx);
02508
02509
02510 if (TREE_CODE (TREE_TYPE (ar)) == INTEGER_TYPE)
02511 {
02512 tree temp = ar;
02513 ar = ind;
02514 ind = temp;
02515 }
02516
02517 if (ar == error_mark_node)
02518 return ar;
02519
02520 if (TREE_CODE (TREE_TYPE (ar)) != POINTER_TYPE)
02521 {
02522 error ("subscripted value is neither array nor pointer");
02523 return error_mark_node;
02524 }
02525 if (TREE_CODE (TREE_TYPE (ind)) != INTEGER_TYPE)
02526 {
02527 error ("array subscript is not an integer");
02528 return error_mark_node;
02529 }
02530
02531 return build_indirect_ref (cp_build_binary_op (PLUS_EXPR, ar, ind),
02532 "array indexing");
02533 }
02534 }
02535
02536
02537
02538
02539
02540
02541
02542
02543
02544
02545
02546 tree
02547 get_member_function_from_ptrfunc (instance_ptrptr, function)
02548 tree *instance_ptrptr;
02549 tree function;
02550 {
02551 if (TREE_CODE (function) == OFFSET_REF)
02552 function = TREE_OPERAND (function, 1);
02553
02554 if (TYPE_PTRMEMFUNC_P (TREE_TYPE (function)))
02555 {
02556 tree idx, delta, e1, e2, e3, vtbl, basetype;
02557 tree fntype = TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (function));
02558
02559 tree instance_ptr = *instance_ptrptr;
02560 tree instance_save_expr = 0;
02561 if (instance_ptr == error_mark_node)
02562 {
02563 if (TREE_CODE (function) == PTRMEM_CST)
02564 {
02565
02566
02567
02568 e1 = build_addr_func (PTRMEM_CST_MEMBER (function));
02569 e1 = convert (fntype, e1);
02570 return e1;
02571 }
02572 else
02573 {
02574 error ("object missing in use of `%E'", function);
02575 return error_mark_node;
02576 }
02577 }
02578
02579 if (TREE_SIDE_EFFECTS (instance_ptr))
02580 instance_ptr = instance_save_expr = save_expr (instance_ptr);
02581
02582 if (TREE_SIDE_EFFECTS (function))
02583 function = save_expr (function);
02584
02585
02586 e3 = PFN_FROM_PTRMEMFUNC (function);
02587 delta = build_ptrmemfunc_access_expr (function, delta_identifier);
02588 idx = build1 (NOP_EXPR, vtable_index_type, e3);
02589 switch (TARGET_PTRMEMFUNC_VBIT_LOCATION)
02590 {
02591 case ptrmemfunc_vbit_in_pfn:
02592 e1 = cp_build_binary_op (BIT_AND_EXPR, idx, integer_one_node);
02593 idx = cp_build_binary_op (MINUS_EXPR, idx, integer_one_node);
02594 break;
02595
02596 case ptrmemfunc_vbit_in_delta:
02597 e1 = cp_build_binary_op (BIT_AND_EXPR, delta, integer_one_node);
02598 delta = cp_build_binary_op (RSHIFT_EXPR, delta, integer_one_node);
02599 break;
02600
02601 default:
02602 abort ();
02603 }
02604
02605
02606
02607 basetype = TYPE_METHOD_BASETYPE (TREE_TYPE (fntype));
02608 basetype = lookup_base (TREE_TYPE (TREE_TYPE (instance_ptr)),
02609 basetype, ba_check, NULL);
02610 instance_ptr = build_base_path (PLUS_EXPR, instance_ptr, basetype, 1);
02611 if (instance_ptr == error_mark_node)
02612 return error_mark_node;
02613
02614 instance_ptr = build (PLUS_EXPR, TREE_TYPE (instance_ptr),
02615 instance_ptr, delta);
02616
02617
02618 *instance_ptrptr = instance_ptr;
02619
02620
02621 vtbl = build1 (NOP_EXPR, build_pointer_type (vtbl_ptr_type_node),
02622 instance_ptr);
02623 vtbl = build_indirect_ref (vtbl, NULL);
02624
02625
02626 e2 = fold (build (PLUS_EXPR, TREE_TYPE (vtbl), vtbl, idx));
02627 e2 = build_indirect_ref (e2, NULL);
02628 TREE_CONSTANT (e2) = 1;
02629
02630
02631
02632 if (TARGET_VTABLE_USES_DESCRIPTORS)
02633 e2 = build1 (NOP_EXPR, TREE_TYPE (e2),
02634 build_unary_op (ADDR_EXPR, e2, 1));
02635
02636 TREE_TYPE (e2) = TREE_TYPE (e3);
02637 e1 = build_conditional_expr (e1, e2, e3);
02638
02639
02640
02641 if (instance_save_expr)
02642 e1 = build (COMPOUND_EXPR, TREE_TYPE (e1),
02643 instance_save_expr, e1);
02644
02645 function = e1;
02646 }
02647 return function;
02648 }
02649
02650 tree
02651 build_function_call_real (function, params, flags)
02652 tree function, params;
02653 int flags;
02654 {
02655 register tree fntype, fndecl;
02656 register tree coerced_params;
02657 tree result;
02658 tree name = NULL_TREE, assembler_name = NULL_TREE;
02659 int is_method;
02660 tree original = function;
02661
02662
02663
02664 if (TREE_CODE (function) == NOP_EXPR
02665 && TREE_TYPE (function) == TREE_TYPE (TREE_OPERAND (function, 0)))
02666 function = TREE_OPERAND (function, 0);
02667
02668 if (TREE_CODE (function) == FUNCTION_DECL)
02669 {
02670 name = DECL_NAME (function);
02671 assembler_name = DECL_ASSEMBLER_NAME (function);
02672
02673 mark_used (function);
02674 fndecl = function;
02675
02676
02677 if (pedantic && DECL_MAIN_P (function))
02678 pedwarn ("ISO C++ forbids calling `::main' from within program");
02679
02680
02681
02682
02683
02684 if (DECL_INLINE (function))
02685 function = inline_conversion (function);
02686 else
02687 function = build_addr_func (function);
02688 }
02689 else
02690 {
02691 fndecl = NULL_TREE;
02692
02693 function = build_addr_func (function);
02694 }
02695
02696 if (function == error_mark_node)
02697 return error_mark_node;
02698
02699 fntype = TREE_TYPE (function);
02700
02701 if (TYPE_PTRMEMFUNC_P (fntype))
02702 {
02703 error ("must use .* or ->* to call pointer-to-member function in `%E (...)'",
02704 original);
02705 return error_mark_node;
02706 }
02707
02708 is_method = (TREE_CODE (fntype) == POINTER_TYPE
02709 && TREE_CODE (TREE_TYPE (fntype)) == METHOD_TYPE);
02710
02711 if (!((TREE_CODE (fntype) == POINTER_TYPE
02712 && TREE_CODE (TREE_TYPE (fntype)) == FUNCTION_TYPE)
02713 || is_method
02714 || TREE_CODE (function) == TEMPLATE_ID_EXPR))
02715 {
02716 error ("`%E' cannot be used as a function", original);
02717 return error_mark_node;
02718 }
02719
02720
02721 fntype = TREE_TYPE (fntype);
02722
02723
02724
02725
02726 if (flags & LOOKUP_COMPLAIN)
02727 coerced_params = convert_arguments (TYPE_ARG_TYPES (fntype),
02728 params, fndecl, LOOKUP_NORMAL);
02729 else
02730 coerced_params = convert_arguments (TYPE_ARG_TYPES (fntype),
02731 params, fndecl, 0);
02732
02733 if (coerced_params == error_mark_node)
02734 {
02735 if (flags & LOOKUP_SPECULATIVELY)
02736 return NULL_TREE;
02737 else
02738 return error_mark_node;
02739 }
02740
02741
02742
02743 if (warn_format)
02744 check_function_format (NULL, TYPE_ATTRIBUTES (fntype), coerced_params);
02745
02746
02747
02748
02749
02750 if (TREE_CODE (function) == ADDR_EXPR
02751 && TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL
02752 && DECL_BUILT_IN (TREE_OPERAND (function, 0)))
02753 {
02754 result = expand_tree_builtin (TREE_OPERAND (function, 0),
02755 params, coerced_params);
02756 if (result)
02757 return result;
02758 }
02759
02760 return build_cxx_call (function, params, coerced_params);
02761 }
02762
02763 tree
02764 build_function_call (function, params)
02765 tree function, params;
02766 {
02767 return build_function_call_real (function, params, LOOKUP_NORMAL);
02768 }
02769
02770
02771
02772
02773
02774
02775
02776
02777
02778
02779
02780
02781
02782
02783
02784
02785
02786
02787 tree
02788 convert_arguments (typelist, values, fndecl, flags)
02789 tree typelist, values, fndecl;
02790 int flags;
02791 {
02792 register tree typetail, valtail;
02793 register tree result = NULL_TREE;
02794 const char *called_thing = 0;
02795 int i = 0;
02796
02797
02798 flags |= LOOKUP_ONLYCONVERTING;
02799
02800 if (fndecl)
02801 {
02802 if (TREE_CODE (TREE_TYPE (fndecl)) == METHOD_TYPE)
02803 {
02804 if (DECL_NAME (fndecl) == NULL_TREE
02805 || IDENTIFIER_HAS_TYPE_VALUE (DECL_NAME (fndecl)))
02806 called_thing = "constructor";
02807 else
02808 called_thing = "member function";
02809 }
02810 else
02811 called_thing = "function";
02812 }
02813
02814 for (valtail = values, typetail = typelist;
02815 valtail;
02816 valtail = TREE_CHAIN (valtail), i++)
02817 {
02818 register tree type = typetail ? TREE_VALUE (typetail) : 0;
02819 register tree val = TREE_VALUE (valtail);
02820
02821 if (val == error_mark_node)
02822 return error_mark_node;
02823
02824 if (type == void_type_node)
02825 {
02826 if (fndecl)
02827 {
02828 cp_error_at ("too many arguments to %s `%+#D'", called_thing,
02829 fndecl);
02830 error ("at this point in file");
02831 }
02832 else
02833 error ("too many arguments to function");
02834
02835
02836 if (result)
02837 TREE_TYPE (tree_last (result)) = error_mark_node;
02838 break;
02839 }
02840
02841 if (TREE_CODE (val) == OFFSET_REF)
02842 val = resolve_offset_ref (val);
02843
02844
02845
02846 if (TREE_CODE (val) == NOP_EXPR
02847 && TREE_TYPE (val) == TREE_TYPE (TREE_OPERAND (val, 0))
02848 && (type == 0 || TREE_CODE (type) != REFERENCE_TYPE))
02849 val = TREE_OPERAND (val, 0);
02850
02851 if (type == 0 || TREE_CODE (type) != REFERENCE_TYPE)
02852 {
02853 if (TREE_CODE (TREE_TYPE (val)) == ARRAY_TYPE
02854 || TREE_CODE (TREE_TYPE (val)) == FUNCTION_TYPE
02855 || TREE_CODE (TREE_TYPE (val)) == METHOD_TYPE)
02856 val = default_conversion (val);
02857 }
02858
02859 if (val == error_mark_node)
02860 return error_mark_node;
02861
02862 if (type != 0)
02863 {
02864
02865 tree parmval;
02866
02867 if (!COMPLETE_TYPE_P (complete_type (type)))
02868 {
02869 error ("parameter type of called function is incomplete");
02870 parmval = val;
02871 }
02872 else
02873 {
02874 parmval = convert_for_initialization
02875 (NULL_TREE, type, val, flags,
02876 "argument passing", fndecl, i);
02877 parmval = convert_for_arg_passing (type, parmval);
02878 }
02879
02880 if (parmval == error_mark_node)
02881 return error_mark_node;
02882
02883 result = tree_cons (NULL_TREE, parmval, result);
02884 }
02885 else
02886 {
02887 if (TREE_CODE (TREE_TYPE (val)) == REFERENCE_TYPE)
02888 val = convert_from_reference (val);
02889
02890 if (fndecl && DECL_BUILT_IN (fndecl)
02891 && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CONSTANT_P)
02892
02893
02894
02895 val = require_complete_type (val);
02896 else
02897 val = convert_arg_to_ellipsis (val);
02898
02899 result = tree_cons (NULL_TREE, val, result);
02900 }
02901
02902 if (typetail)
02903 typetail = TREE_CHAIN (typetail);
02904 }
02905
02906 if (typetail != 0 && typetail != void_list_node)
02907 {
02908
02909 if (TREE_PURPOSE (typetail))
02910 {
02911 for (; typetail != void_list_node; ++i)
02912 {
02913 tree parmval
02914 = convert_default_arg (TREE_VALUE (typetail),
02915 TREE_PURPOSE (typetail),
02916 fndecl, i);
02917
02918 if (parmval == error_mark_node)
02919 return error_mark_node;
02920
02921 result = tree_cons (0, parmval, result);
02922 typetail = TREE_CHAIN (typetail);
02923
02924 if (typetail == NULL_TREE)
02925 break;
02926 }
02927 }
02928 else
02929 {
02930 if (fndecl)
02931 {
02932 cp_error_at ("too few arguments to %s `%+#D'",
02933 called_thing, fndecl);
02934 error ("at this point in file");
02935 }
02936 else
02937 error ("too few arguments to function");
02938 return error_mark_list;
02939 }
02940 }
02941
02942 return nreverse (result);
02943 }
02944
02945
02946
02947
02948 tree
02949 build_x_binary_op (code, arg1, arg2)
02950 enum tree_code code;
02951 tree arg1, arg2;
02952 {
02953 if (processing_template_decl)
02954 return build_min_nt (code, arg1, arg2);
02955
02956 return build_new_op (code, LOOKUP_NORMAL, arg1, arg2, NULL_TREE);
02957 }
02958
02959
02960
02961
02962
02963
02964
02965
02966
02967
02968
02969
02970
02971
02972
02973
02974
02975
02976
02977 tree
02978 build_binary_op (code, orig_op0, orig_op1, convert_p)
02979 enum tree_code code;
02980 tree orig_op0, orig_op1;
02981 int convert_p ATTRIBUTE_UNUSED;
02982 {
02983 tree op0, op1;
02984 register enum tree_code code0, code1;
02985 tree type0, type1;
02986
02987
02988
02989
02990 register enum tree_code resultcode = code;
02991
02992
02993
02994 register tree result_type = NULL;
02995
02996
02997
02998
02999 int converted = 0;
03000
03001
03002
03003 tree build_type = 0;
03004
03005
03006
03007 tree final_type = 0;
03008
03009
03010
03011
03012
03013
03014
03015 int shorten = 0;
03016
03017
03018
03019
03020 int short_compare = 0;
03021
03022
03023
03024 int short_shift = 0;
03025
03026
03027 int common = 0;
03028
03029
03030 op0 = orig_op0;
03031 op1 = orig_op1;
03032
03033 if (code == TRUTH_AND_EXPR || code == TRUTH_ANDIF_EXPR
03034 || code == TRUTH_OR_EXPR || code == TRUTH_ORIF_EXPR
03035 || code == TRUTH_XOR_EXPR)
03036 {
03037 if (!really_overloaded_fn (op0))
03038 op0 = decay_conversion (op0);
03039 if (!really_overloaded_fn (op1))
03040 op1 = decay_conversion (op1);
03041 }
03042 else
03043 {
03044 if (!really_overloaded_fn (op0))
03045 op0 = default_conversion (op0);
03046 if (!really_overloaded_fn (op1))
03047 op1 = default_conversion (op1);
03048 }
03049
03050
03051 STRIP_TYPE_NOPS (op0);
03052 STRIP_TYPE_NOPS (op1);
03053
03054
03055 if (type_unknown_p (op0))
03056 {
03057 tree t = instantiate_type (TREE_TYPE (op1), op0, tf_none);
03058 if (t != error_mark_node)
03059 {
03060 pedwarn ("assuming cast to type `%T' from overloaded function",
03061 TREE_TYPE (t));
03062 op0 = t;
03063 }
03064 }
03065 if (type_unknown_p (op1))
03066 {
03067 tree t = instantiate_type (TREE_TYPE (op0), op1, tf_none);
03068 if (t != error_mark_node)
03069 {
03070 pedwarn ("assuming cast to type `%T' from overloaded function",
03071 TREE_TYPE (t));
03072 op1 = t;
03073 }
03074 }
03075
03076 type0 = TREE_TYPE (op0);
03077 type1 = TREE_TYPE (op1);
03078
03079
03080
03081 code0 = TREE_CODE (type0);
03082 code1 = TREE_CODE (type1);
03083
03084
03085
03086
03087 if (code0 == ERROR_MARK || code1 == ERROR_MARK)
03088 return error_mark_node;
03089
03090 switch (code)
03091 {
03092 case PLUS_EXPR:
03093
03094 if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
03095 return cp_pointer_int_sum (PLUS_EXPR, op0, op1);
03096 else if (code1 == POINTER_TYPE && code0 == INTEGER_TYPE)
03097 return cp_pointer_int_sum (PLUS_EXPR, op1, op0);
03098 else
03099 common = 1;
03100 break;
03101
03102 case MINUS_EXPR:
03103
03104
03105 if (code0 == POINTER_TYPE && code1 == POINTER_TYPE
03106 && comp_target_types (type0, type1, 1))
03107 return pointer_diff (op0, op1, common_type (type0, type1));
03108
03109 else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
03110 return cp_pointer_int_sum (MINUS_EXPR, op0, op1);
03111 else
03112 common = 1;
03113 break;
03114
03115 case MULT_EXPR:
03116 common = 1;
03117 break;
03118
03119 case TRUNC_DIV_EXPR:
03120 case CEIL_DIV_EXPR:
03121 case FLOOR_DIV_EXPR:
03122 case ROUND_DIV_EXPR:
03123 case EXACT_DIV_EXPR:
03124 if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
03125 || code0 == COMPLEX_TYPE)
03126 && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
03127 || code1 == COMPLEX_TYPE))
03128 {
03129 if (TREE_CODE (op1) == INTEGER_CST && integer_zerop (op1))
03130 warning ("division by zero in `%E / 0'", op0);
03131 else if (TREE_CODE (op1) == REAL_CST && real_zerop (op1))
03132 warning ("division by zero in `%E / 0.'", op0);
03133
03134 if (!(code0 == INTEGER_TYPE && code1 == INTEGER_TYPE))
03135 resultcode = RDIV_EXPR;
03136 else
03137
03138
03139
03140
03141
03142 shorten = ((TREE_CODE (op0) == NOP_EXPR
03143 && TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op0, 0))))
03144 || (TREE_CODE (op1) == INTEGER_CST
03145 && ! integer_all_onesp (op1)));
03146
03147 common = 1;
03148 }
03149 break;
03150
03151 case BIT_AND_EXPR:
03152 case BIT_ANDTC_EXPR:
03153 case BIT_IOR_EXPR:
03154 case BIT_XOR_EXPR:
03155 if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
03156 shorten = -1;
03157 break;
03158
03159 case TRUNC_MOD_EXPR:
03160 case FLOOR_MOD_EXPR:
03161 if (code1 == INTEGER_TYPE && integer_zerop (op1))
03162 warning ("division by zero in `%E %% 0'", op0);
03163 else if (code1 == REAL_TYPE && real_zerop (op1))
03164 warning ("division by zero in `%E %% 0.'", op0);
03165
03166 if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
03167 {
03168
03169
03170
03171
03172 shorten = ((TREE_CODE (op0) == NOP_EXPR
03173 && TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op0, 0))))
03174 || (TREE_CODE (op1) == INTEGER_CST
03175 && ! integer_all_onesp (op1)));
03176 common = 1;
03177 }
03178 break;
03179
03180 case TRUTH_ANDIF_EXPR:
03181 case TRUTH_ORIF_EXPR:
03182 case TRUTH_AND_EXPR:
03183 case TRUTH_OR_EXPR:
03184 result_type = boolean_type_node;
03185 break;
03186
03187
03188
03189
03190
03191 case RSHIFT_EXPR:
03192 if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
03193 {
03194 result_type = type0;
03195 if (TREE_CODE (op1) == INTEGER_CST)
03196 {
03197 if (tree_int_cst_lt (op1, integer_zero_node))
03198 warning ("right shift count is negative");
03199 else
03200 {
03201 if (! integer_zerop (op1))
03202 short_shift = 1;
03203 if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0)
03204 warning ("right shift count >= width of type");
03205 }
03206 }
03207
03208
03209 if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
03210 op1 = cp_convert (integer_type_node, op1);
03211
03212 converted = 1;
03213 }
03214 break;
03215
03216 case LSHIFT_EXPR:
03217 if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
03218 {
03219 result_type = type0;
03220 if (TREE_CODE (op1) == INTEGER_CST)
03221 {
03222 if (tree_int_cst_lt (op1, integer_zero_node))
03223 warning ("left shift count is negative");
03224 else if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0)
03225 warning ("left shift count >= width of type");
03226 }
03227
03228
03229 if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
03230 op1 = cp_convert (integer_type_node, op1);
03231
03232 converted = 1;
03233 }
03234 break;
03235
03236 case RROTATE_EXPR:
03237 case LROTATE_EXPR:
03238 if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
03239 {
03240 result_type = type0;
03241 if (TREE_CODE (op1) == INTEGER_CST)
03242 {
03243 if (tree_int_cst_lt (op1, integer_zero_node))
03244 warning ("%s rotate count is negative",
03245 (code == LROTATE_EXPR) ? "left" : "right");
03246 else if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0)
03247 warning ("%s rotate count >= width of type",
03248 (code == LROTATE_EXPR) ? "left" : "right");
03249 }
03250
03251
03252 if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
03253 op1 = cp_convert (integer_type_node, op1);
03254 }
03255 break;
03256
03257 case EQ_EXPR:
03258 case NE_EXPR:
03259 if (warn_float_equal && (code0 == REAL_TYPE || code1 == REAL_TYPE))
03260 warning ("comparing floating point with == or != is unsafe");
03261
03262 build_type = boolean_type_node;
03263 if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
03264 || code0 == COMPLEX_TYPE)
03265 && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
03266 || code1 == COMPLEX_TYPE))
03267 short_compare = 1;
03268 else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
03269 result_type = composite_pointer_type (type0, type1, op0, op1,
03270 "comparison");
03271 else if (code0 == POINTER_TYPE && null_ptr_cst_p (op1))
03272 result_type = type0;
03273 else if (code1 == POINTER_TYPE && null_ptr_cst_p (op0))
03274 result_type = type1;
03275 else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
03276 {
03277 result_type = type0;
03278 error ("ISO C++ forbids comparison between pointer and integer");
03279 }
03280 else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
03281 {
03282 result_type = type1;
03283 error ("ISO C++ forbids comparison between pointer and integer");
03284 }
03285 else if (TYPE_PTRMEMFUNC_P (type0) && null_ptr_cst_p (op1))
03286 {
03287 op0 = build_ptrmemfunc_access_expr (op0, pfn_identifier);
03288 op1 = cp_convert (TREE_TYPE (op0), integer_zero_node);
03289 result_type = TREE_TYPE (op0);
03290 }
03291 else if (TYPE_PTRMEMFUNC_P (type1) && null_ptr_cst_p (op0))
03292 return cp_build_binary_op (code, op1, op0);
03293 else if (TYPE_PTRMEMFUNC_P (type0) && TYPE_PTRMEMFUNC_P (type1)
03294 && same_type_p (type0, type1))
03295 {
03296
03297 tree e;
03298
03299 tree e1;
03300 tree e2;
03301 tree pfn0;
03302 tree pfn1;
03303 tree delta0;
03304 tree delta1;
03305
03306 if (TREE_SIDE_EFFECTS (op0))
03307 op0 = save_expr (op0);
03308 if (TREE_SIDE_EFFECTS (op1))
03309 op1 = save_expr (op1);
03310
03311
03312
03313
03314
03315
03316
03317
03318
03319 pfn0 = pfn_from_ptrmemfunc (op0);
03320 pfn1 = pfn_from_ptrmemfunc (op1);
03321 delta0 = build_ptrmemfunc_access_expr (op0,
03322 delta_identifier);
03323 delta1 = build_ptrmemfunc_access_expr (op1,
03324 delta_identifier);
03325 e1 = cp_build_binary_op (EQ_EXPR, delta0, delta1);
03326 e2 = cp_build_binary_op (EQ_EXPR,
03327 pfn0,
03328 cp_convert (TREE_TYPE (pfn0),
03329 integer_zero_node));
03330 e1 = cp_build_binary_op (TRUTH_ORIF_EXPR, e1, e2);
03331 e2 = build (EQ_EXPR, boolean_type_node, pfn0, pfn1);
03332 e = cp_build_binary_op (TRUTH_ANDIF_EXPR, e2, e1);
03333 if (code == EQ_EXPR)
03334 return e;
03335 return cp_build_binary_op (EQ_EXPR, e, integer_zero_node);
03336 }
03337 else if ((TYPE_PTRMEMFUNC_P (type0)
03338 && same_type_p (TYPE_PTRMEMFUNC_FN_TYPE (type0), type1))
03339 || (TYPE_PTRMEMFUNC_P (type1)
03340 && same_type_p (TYPE_PTRMEMFUNC_FN_TYPE (type1), type0)))
03341 abort ();
03342 break;
03343
03344 case MAX_EXPR:
03345 case MIN_EXPR:
03346 if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
03347 && (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
03348 shorten = 1;
03349 else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
03350 result_type = composite_pointer_type (type0, type1, op0, op1,
03351 "comparison");
03352 break;
03353
03354 case LE_EXPR:
03355 case GE_EXPR:
03356 case LT_EXPR:
03357 case GT_EXPR:
03358 build_type = boolean_type_node;
03359 if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
03360 && (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
03361 short_compare = 1;
03362 else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
03363 result_type = composite_pointer_type (type0, type1, op0, op1,
03364 "comparison");
03365 else if (code0 == POINTER_TYPE && TREE_CODE (op1) == INTEGER_CST
03366 && integer_zerop (op1))
03367 result_type = type0;
03368 else if (code1 == POINTER_TYPE && TREE_CODE (op0) == INTEGER_CST
03369 && integer_zerop (op0))
03370 result_type = type1;
03371 else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
03372 {
03373 result_type = type0;
03374 pedwarn ("ISO C++ forbids comparison between pointer and integer");
03375 }
03376 else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
03377 {
03378 result_type = type1;
03379 pedwarn ("ISO C++ forbids comparison between pointer and integer");
03380 }
03381 break;
03382
03383 case UNORDERED_EXPR:
03384 case ORDERED_EXPR:
03385 case UNLT_EXPR:
03386 case UNLE_EXPR:
03387 case UNGT_EXPR:
03388 case UNGE_EXPR:
03389 case UNEQ_EXPR:
03390 build_type = integer_type_node;
03391 if (code0 != REAL_TYPE || code1 != REAL_TYPE)
03392 {
03393 error ("unordered comparison on non-floating point argument");
03394 return error_mark_node;
03395 }
03396 common = 1;
03397 break;
03398
03399 default:
03400 break;
03401 }
03402
03403 if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE)
03404 &&
03405 (code1 == INTEGER_TYPE || code1 == REAL_TYPE || code1 == COMPLEX_TYPE))
03406 {
03407 int none_complex = (code0 != COMPLEX_TYPE && code1 != COMPLEX_TYPE);
03408
03409 if (shorten || common || short_compare)
03410 result_type = common_type (type0, type1);
03411
03412
03413
03414
03415
03416
03417
03418
03419
03420
03421
03422
03423 if (shorten && none_complex)
03424 {
03425 int unsigned0, unsigned1;
03426 tree arg0 = get_narrower (op0, &unsigned0);
03427 tree arg1 = get_narrower (op1, &unsigned1);
03428
03429 int uns = TREE_UNSIGNED (result_type);
03430 tree type;
03431
03432 final_type = result_type;
03433
03434
03435
03436
03437 if (op0 == arg0 && TREE_TYPE (op0) != final_type)
03438 unsigned0 = TREE_UNSIGNED (TREE_TYPE (op0));
03439 if (op1 == arg1 && TREE_TYPE (op1) != final_type)
03440 unsigned1 = TREE_UNSIGNED (TREE_TYPE (op1));
03441
03442
03443
03444
03445
03446 if (shorten == -1)
03447 uns = unsigned0;
03448
03449
03450
03451
03452
03453
03454
03455
03456 if ((TYPE_PRECISION (TREE_TYPE (arg0))
03457 < TYPE_PRECISION (result_type))
03458 && (TYPE_PRECISION (TREE_TYPE (arg1))
03459 == TYPE_PRECISION (TREE_TYPE (arg0)))
03460 && unsigned0 == unsigned1
03461 && (unsigned0 || !uns))
03462 result_type = c_common_signed_or_unsigned_type
03463 (unsigned0, common_type (TREE_TYPE (arg0), TREE_TYPE (arg1)));
03464 else if (TREE_CODE (arg0) == INTEGER_CST
03465 && (unsigned1 || !uns)
03466 && (TYPE_PRECISION (TREE_TYPE (arg1))
03467 < TYPE_PRECISION (result_type))
03468 && (type = c_common_signed_or_unsigned_type
03469 (unsigned1, TREE_TYPE (arg1)),
03470 int_fits_type_p (arg0, type)))
03471 result_type = type;
03472 else if (TREE_CODE (arg1) == INTEGER_CST
03473 && (unsigned0 || !uns)
03474 && (TYPE_PRECISION (TREE_TYPE (arg0))
03475 < TYPE_PRECISION (result_type))
03476 && (type = c_common_signed_or_unsigned_type
03477 (unsigned0, TREE_TYPE (arg0)),
03478 int_fits_type_p (arg1, type)))
03479 result_type = type;
03480 }
03481
03482
03483
03484 if (short_shift)
03485 {
03486 int unsigned_arg;
03487 tree arg0 = get_narrower (op0, &unsigned_arg);
03488
03489 final_type = result_type;
03490
03491 if (arg0 == op0 && final_type == TREE_TYPE (op0))
03492 unsigned_arg = TREE_UNSIGNED (TREE_TYPE (op0));
03493
03494 if (TYPE_PRECISION (TREE_TYPE (arg0)) < TYPE_PRECISION (result_type)
03495
03496
03497 && compare_tree_int (op1, TYPE_PRECISION (TREE_TYPE (arg0))) < 0
03498
03499
03500
03501
03502
03503
03504
03505 && (!TREE_UNSIGNED (final_type)
03506 || unsigned_arg
03507 || (((unsigned) 2 * TYPE_PRECISION (TREE_TYPE (arg0)))
03508 <= TYPE_PRECISION (result_type))))
03509 {
03510
03511 result_type
03512 = c_common_signed_or_unsigned_type (unsigned_arg,
03513 TREE_TYPE (arg0));
03514
03515 if (TREE_TYPE (op0) != result_type)
03516 op0 = cp_convert (result_type, op0);
03517 converted = 1;
03518 }
03519 }
03520
03521
03522
03523
03524 if (short_compare)
03525 {
03526
03527
03528
03529
03530 tree xop0 = op0, xop1 = op1, xresult_type = result_type;
03531 enum tree_code xresultcode = resultcode;
03532 tree val
03533 = shorten_compare (&xop0, &xop1, &xresult_type, &xresultcode);
03534 if (val != 0)
03535 return cp_convert (boolean_type_node, val);
03536 op0 = xop0, op1 = xop1;
03537 converted = 1;
03538 resultcode = xresultcode;
03539 }
03540
03541 if ((short_compare || code == MIN_EXPR || code == MAX_EXPR)
03542 && warn_sign_compare)
03543 {
03544 int op0_signed = ! TREE_UNSIGNED (TREE_TYPE (orig_op0));
03545 int op1_signed = ! TREE_UNSIGNED (TREE_TYPE (orig_op1));
03546
03547 int unsignedp0, unsignedp1;
03548 tree primop0 = get_narrower (op0, &unsignedp0);
03549 tree primop1 = get_narrower (op1, &unsignedp1);
03550
03551
03552 if (TREE_CODE (TREE_TYPE (orig_op0)) == ENUMERAL_TYPE
03553 && TREE_CODE (TREE_TYPE (orig_op1)) == ENUMERAL_TYPE
03554 && TYPE_MAIN_VARIANT (TREE_TYPE (orig_op0))
03555 != TYPE_MAIN_VARIANT (TREE_TYPE (orig_op1)))
03556 {
03557 warning ("comparison between types `%#T' and `%#T'",
03558 TREE_TYPE (orig_op0), TREE_TYPE (orig_op1));
03559 }
03560
03561
03562
03563
03564
03565
03566
03567
03568
03569 if (! TREE_UNSIGNED (result_type))
03570 ;
03571
03572 else if (op0_signed == op1_signed)
03573 ;
03574
03575
03576
03577
03578 else if ((op0_signed && tree_expr_nonnegative_p (orig_op0))
03579 || (op1_signed && tree_expr_nonnegative_p (orig_op1)))
03580 ;
03581
03582
03583
03584 else if ((resultcode == EQ_EXPR || resultcode == NE_EXPR)
03585 && ((op0_signed && TREE_CODE (orig_op1) == INTEGER_CST
03586 && int_fits_type_p (orig_op1, c_common_signed_type
03587 (result_type)))
03588 || (op1_signed && TREE_CODE (orig_op0) == INTEGER_CST
03589 && int_fits_type_p (orig_op0, c_common_signed_type
03590 (result_type)))))
03591 ;
03592 else
03593 warning ("comparison between signed and unsigned integer expressions");
03594
03595
03596
03597
03598
03599
03600
03601
03602
03603 if ((TREE_CODE (primop0) == BIT_NOT_EXPR)
03604 ^ (TREE_CODE (primop1) == BIT_NOT_EXPR))
03605 {
03606 if (TREE_CODE (primop0) == BIT_NOT_EXPR)
03607 primop0 = get_narrower (TREE_OPERAND (op0, 0), &unsignedp0);
03608 if (TREE_CODE (primop1) == BIT_NOT_EXPR)
03609 primop1 = get_narrower (TREE_OPERAND (op1, 0), &unsignedp1);
03610
03611 if (host_integerp (primop0, 0) || host_integerp (primop1, 0))
03612 {
03613 tree primop;
03614 HOST_WIDE_INT constant, mask;
03615 int unsignedp;
03616 unsigned int bits;
03617
03618 if (host_integerp (primop0, 0))
03619 {
03620 primop = primop1;
03621 unsignedp = unsignedp1;
03622 constant = tree_low_cst (primop0, 0);
03623 }
03624 else
03625 {
03626 primop = primop0;
03627 unsignedp = unsignedp0;
03628 constant = tree_low_cst (primop1, 0);
03629 }
03630
03631 bits = TYPE_PRECISION (TREE_TYPE (primop));
03632 if (bits < TYPE_PRECISION (result_type)
03633 && bits < HOST_BITS_PER_LONG && unsignedp)
03634 {
03635 mask = (~ (HOST_WIDE_INT) 0) << bits;
03636 if ((mask & constant) != mask)
03637 warning ("comparison of promoted ~unsigned with constant");
03638 }
03639 }
03640 else if (unsignedp0 && unsignedp1
03641 && (TYPE_PRECISION (TREE_TYPE (primop0))
03642 < TYPE_PRECISION (result_type))
03643 && (TYPE_PRECISION (TREE_TYPE (primop1))
03644 < TYPE_PRECISION (result_type)))
03645 warning ("comparison of promoted ~unsigned with unsigned");
03646 }
03647 }
03648 }
03649
03650
03651
03652
03653
03654
03655
03656 if (!result_type)
03657 {
03658 error ("invalid operands of types `%T' and `%T' to binary `%O'",
03659 TREE_TYPE (orig_op0), TREE_TYPE (orig_op1), code);
03660 return error_mark_node;
03661 }
03662
03663
03664 if (
03665
03666 !(code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR)
03667 && (
03668 (orig_op0 == null_node
03669 && TREE_CODE (TREE_TYPE (op1)) != POINTER_TYPE)
03670
03671 || (orig_op1 == null_node
03672 && TREE_CODE (TREE_TYPE (op0)) != POINTER_TYPE)
03673
03674 || (orig_op0 == null_node && orig_op1 == null_node
03675 && code != EQ_EXPR && code != NE_EXPR)))
03676
03677
03678
03679
03680 warning ("NULL used in arithmetic");
03681
03682 if (! converted)
03683 {
03684 if (TREE_TYPE (op0) != result_type)
03685 op0 = cp_convert (result_type, op0);
03686 if (TREE_TYPE (op1) != result_type)
03687 op1 = cp_convert (result_type, op1);
03688
03689 if (op0 == error_mark_node || op1 == error_mark_node)
03690 return error_mark_node;
03691 }
03692
03693 if (build_type == NULL_TREE)
03694 build_type = result_type;
03695
03696 {
03697 register tree result = build (resultcode, build_type, op0, op1);
03698 register tree folded;
03699
03700 folded = fold (result);
03701 if (folded == result)
03702 TREE_CONSTANT (folded) = TREE_CONSTANT (op0) & TREE_CONSTANT (op1);
03703 if (final_type != 0)
03704 return cp_convert (final_type, folded);
03705 return folded;
03706 }
03707 }
03708
03709
03710
03711
03712 static tree
03713 cp_pointer_int_sum (resultcode, ptrop, intop)
03714 enum tree_code resultcode;
03715 register tree ptrop, intop;
03716 {
03717 tree res_type = TREE_TYPE (ptrop);
03718
03719
03720
03721
03722
03723
03724 complete_type (TREE_TYPE (res_type));
03725
03726 return pointer_int_sum (resultcode, ptrop, fold (intop));
03727 }
03728
03729
03730
03731
03732 static tree
03733 pointer_diff (op0, op1, ptrtype)
03734 register tree op0, op1;
03735 register tree ptrtype;
03736 {
03737 register tree result, folded;
03738 tree restype = ptrdiff_type_node;
03739 tree target_type = TREE_TYPE (ptrtype);
03740
03741 if (!complete_type_or_else (target_type, NULL_TREE))
03742 return error_mark_node;
03743
03744 if (pedantic || warn_pointer_arith)
03745 {
03746 if (TREE_CODE (target_type) == VOID_TYPE)
03747 pedwarn ("ISO C++ forbids using pointer of type `void *' in subtraction");
03748 if (TREE_CODE (target_type) == FUNCTION_TYPE)
03749 pedwarn ("ISO C++ forbids using pointer to a function in subtraction");
03750 if (TREE_CODE (target_type) == METHOD_TYPE)
03751 pedwarn ("ISO C++ forbids using pointer to a method in subtraction");
03752 if (TREE_CODE (target_type) == OFFSET_TYPE)
03753 pedwarn ("ISO C++ forbids using pointer to a member in subtraction");
03754 }
03755
03756
03757
03758
03759 op0 = cp_build_binary_op (MINUS_EXPR,
03760 cp_convert (restype, op0),
03761 cp_convert (restype, op1));
03762
03763
03764 if (!COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (op1))))
03765 error ("invalid use of a pointer to an incomplete type in pointer arithmetic");
03766
03767 op1 = ((TREE_CODE (target_type) == VOID_TYPE
03768 || TREE_CODE (target_type) == FUNCTION_TYPE
03769 || TREE_CODE (target_type) == METHOD_TYPE
03770 || TREE_CODE (target_type) == OFFSET_TYPE)
03771 ? integer_one_node
03772 : size_in_bytes (target_type));
03773
03774
03775
03776 result = build (EXACT_DIV_EXPR, restype, op0, cp_convert (restype, op1));
03777
03778 folded = fold (result);
03779 if (folded == result)
03780 TREE_CONSTANT (folded) = TREE_CONSTANT (op0) & TREE_CONSTANT (op1);
03781 return folded;
03782 }
03783
03784
03785
03786
03787
03788 tree
03789 build_x_unary_op (code, xarg)
03790 enum tree_code code;
03791 tree xarg;
03792 {
03793 tree exp;
03794 int ptrmem = 0;
03795
03796 if (processing_template_decl)
03797 return build_min_nt (code, xarg, NULL_TREE);
03798
03799
03800
03801 if (code == ADDR_EXPR
03802 && TREE_CODE (xarg) != TEMPLATE_ID_EXPR
03803 && ((IS_AGGR_TYPE_CODE (TREE_CODE (TREE_TYPE (xarg)))
03804 && !COMPLETE_TYPE_P (TREE_TYPE (xarg)))
03805 || (TREE_CODE (xarg) == OFFSET_REF)))
03806 ;
03807 else
03808 {
03809 tree rval;
03810
03811 rval = build_new_op (code, LOOKUP_NORMAL, xarg,
03812 NULL_TREE, NULL_TREE);
03813 if (rval || code != ADDR_EXPR)
03814 return rval;
03815 }
03816 if (code == ADDR_EXPR)
03817 {
03818
03819
03820 if (!flag_ms_extensions && TREE_CODE (TREE_TYPE (xarg)) == METHOD_TYPE
03821 && (TREE_CODE (xarg) != OFFSET_REF || !PTRMEM_OK_P (xarg)))
03822 {
03823 if (TREE_CODE (xarg) != OFFSET_REF)
03824 {
03825 error ("invalid use of '%E' to form a pointer-to-member-function. Use a qualified-id.",
03826 xarg);
03827 return error_mark_node;
03828 }
03829 else
03830 {
03831 error ("parenthesis around '%E' cannot be used to form a pointer-to-member-function",
03832 xarg);
03833 PTRMEM_OK_P (xarg) = 1;
03834 }
03835 }
03836
03837 if (TREE_CODE (xarg) == OFFSET_REF)
03838 {
03839 ptrmem = PTRMEM_OK_P (xarg);
03840
03841 if (!ptrmem && !flag_ms_extensions
03842 && TREE_CODE (TREE_TYPE (TREE_OPERAND (xarg, 1))) == METHOD_TYPE)
03843 {
03844
03845
03846 xarg = build (OFFSET_REF, TREE_TYPE (xarg),
03847 TREE_OPERAND (xarg, 0),
03848 ovl_cons (TREE_OPERAND (xarg, 1), NULL_TREE));
03849 PTRMEM_OK_P (xarg) = ptrmem;
03850 }
03851
03852 }
03853 else if (TREE_CODE (xarg) == TARGET_EXPR)
03854 warning ("taking address of temporary");
03855 }
03856 exp = build_unary_op (code, xarg, 0);
03857 if (TREE_CODE (exp) == ADDR_EXPR)
03858 PTRMEM_OK_P (exp) = ptrmem;
03859
03860 return exp;
03861 }
03862
03863
03864
03865
03866
03867 tree
03868 cp_truthvalue_conversion (expr)
03869 tree expr;
03870 {
03871 tree type = TREE_TYPE (expr);
03872 if (TYPE_PTRMEM_P (type))
03873 return build_binary_op (NE_EXPR, expr, integer_zero_node, 1);
03874 else
03875 return c_common_truthvalue_conversion (expr);
03876 }
03877
03878
03879
03880 tree
03881 condition_conversion (expr)
03882 tree expr;
03883 {
03884 tree t;
03885 if (processing_template_decl)
03886 return expr;
03887 if (TREE_CODE (expr) == OFFSET_REF)
03888 expr = resolve_offset_ref (expr);
03889 t = perform_implicit_conversion (boolean_type_node, expr);
03890 t = fold (build1 (CLEANUP_POINT_EXPR, boolean_type_node, t));
03891 return t;
03892 }
03893
03894
03895
03896
03897
03898 tree
03899 build_address (tree t)
03900 {
03901 tree addr;
03902
03903 if (error_operand_p (t) || !cxx_mark_addressable (t))
03904 return error_mark_node;
03905
03906 addr = build1 (ADDR_EXPR,
03907 build_pointer_type (TREE_TYPE (t)),
03908 t);
03909 if (staticp (t))
03910 TREE_CONSTANT (addr) = 1;
03911
03912 return addr;
03913 }
03914
03915
03916
03917 tree
03918 build_nop (tree type, tree expr)
03919 {
03920 tree nop;
03921
03922 if (type == error_mark_node || error_operand_p (expr))
03923 return expr;
03924
03925 nop = build1 (NOP_EXPR, type, expr);
03926 if (TREE_CONSTANT (expr))
03927 TREE_CONSTANT (nop) = 1;
03928
03929 return nop;
03930 }
03931
03932
03933
03934
03935
03936
03937
03938
03939
03940
03941 tree
03942 build_unary_op (code, xarg, noconvert)
03943 enum tree_code code;
03944 tree xarg;
03945 int noconvert;
03946 {
03947
03948 register tree arg = xarg;
03949 register tree argtype = 0;
03950 const char *errstring = NULL;
03951 tree val;
03952
03953 if (arg == error_mark_node)
03954 return error_mark_node;
03955
03956 switch (code)
03957 {
03958 case CONVERT_EXPR:
03959
03960
03961
03962 if (!(arg = build_expr_type_conversion
03963 (WANT_ARITH | WANT_ENUM | WANT_POINTER, arg, 1)))
03964 errstring = "wrong type argument to unary plus";
03965 else
03966 {
03967 if (!noconvert)
03968 arg = default_conversion (arg);
03969 arg = build1 (NON_LVALUE_EXPR, TREE_TYPE (arg), arg);
03970 TREE_CONSTANT (arg) = TREE_CONSTANT (TREE_OPERAND (arg, 0));
03971 }
03972 break;
03973
03974 case NEGATE_EXPR:
03975 if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, arg, 1)))
03976 errstring = "wrong type argument to unary minus";
03977 else if (!noconvert)
03978 arg = default_conversion (arg);
03979 break;
03980
03981 case BIT_NOT_EXPR:
03982 if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
03983 {
03984 code = CONJ_EXPR;
03985 if (!noconvert)
03986 arg = default_conversion (arg);
03987 }
03988 else if (!(arg = build_expr_type_conversion (WANT_INT | WANT_ENUM,
03989 arg, 1)))
03990 errstring = "wrong type argument to bit-complement";
03991 else if (!noconvert)
03992 arg = default_conversion (arg);
03993 break;
03994
03995 case ABS_EXPR:
03996 if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, arg, 1)))
03997 errstring = "wrong type argument to abs";
03998 else if (!noconvert)
03999 arg = default_conversion (arg);
04000 break;
04001
04002 case CONJ_EXPR:
04003
04004 if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, arg, 1)))
04005 errstring = "wrong type argument to conjugation";
04006 else if (!noconvert)
04007 arg = default_conversion (arg);
04008 break;
04009
04010 case TRUTH_NOT_EXPR:
04011 arg = cp_convert (boolean_type_node, arg);
04012 val = invert_truthvalue (arg);
04013 if (arg != error_mark_node)
04014 return val;
04015 errstring = "in argument to unary !";
04016 break;
04017
04018 case NOP_EXPR:
04019 break;
04020
04021 case REALPART_EXPR:
04022 if (TREE_CODE (arg) == COMPLEX_CST)
04023 return TREE_REALPART (arg);
04024 else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
04025 return fold (build1 (REALPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg));
04026 else
04027 return arg;
04028
04029 case IMAGPART_EXPR:
04030 if (TREE_CODE (arg) == COMPLEX_CST)
04031 return TREE_IMAGPART (arg);
04032 else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
04033 return fold (build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg));
04034 else
04035 return cp_convert (TREE_TYPE (arg), integer_zero_node);
04036
04037 case PREINCREMENT_EXPR:
04038 case POSTINCREMENT_EXPR:
04039 case PREDECREMENT_EXPR:
04040 case POSTDECREMENT_EXPR:
04041
04042
04043
04044 val = unary_complex_lvalue (code, arg);
04045 if (val != 0)
04046 return val;
04047
04048
04049
04050 if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
04051 {
04052 tree real, imag;
04053
04054 arg = stabilize_reference (arg);
04055 real = build_unary_op (REALPART_EXPR, arg, 1);
04056 imag = build_unary_op (IMAGPART_EXPR, arg, 1);
04057 return build (COMPLEX_EXPR, TREE_TYPE (arg),
04058 build_unary_op (code, real, 1), imag);
04059 }
04060
04061
04062
04063 if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_POINTER,
04064 arg, 1)))
04065 {
04066 if (code == PREINCREMENT_EXPR)
04067 errstring ="no pre-increment operator for type";
04068 else if (code == POSTINCREMENT_EXPR)
04069 errstring ="no post-increment operator for type";
04070 else if (code == PREDECREMENT_EXPR)
04071 errstring ="no pre-decrement operator for type";
04072 else
04073 errstring ="no post-decrement operator for type";
04074 break;
04075 }
04076
04077
04078
04079 if (CP_TYPE_CONST_P (TREE_TYPE (arg))
04080 || TREE_READONLY (arg))
04081 readonly_error (arg, ((code == PREINCREMENT_EXPR
04082 || code == POSTINCREMENT_EXPR)
04083 ? "increment" : "decrement"),
04084 0);
04085
04086 {
04087 register tree inc;
04088 tree result_type = TREE_TYPE (arg);
04089
04090 arg = get_unwidened (arg, 0);
04091 argtype = TREE_TYPE (arg);
04092
04093
04094 if (TREE_CODE (argtype) == ENUMERAL_TYPE)
04095 pedwarn ("ISO C++ forbids %sing an enum",
04096 (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
04097 ? "increment" : "decrement");
04098
04099
04100
04101 if (TREE_CODE (argtype) == POINTER_TYPE)
04102 {
04103 enum tree_code tmp = TREE_CODE (TREE_TYPE (argtype));
04104 tree type = complete_type (TREE_TYPE (argtype));
04105
04106 if (!COMPLETE_OR_VOID_TYPE_P (type))
04107 error ("cannot %s a pointer to incomplete type `%T'",
04108 ((code == PREINCREMENT_EXPR
04109 || code == POSTINCREMENT_EXPR)
04110 ? "increment" : "decrement"), TREE_TYPE (argtype));
04111 else if ((pedantic || warn_pointer_arith)
04112 && (tmp == FUNCTION_TYPE || tmp == METHOD_TYPE
04113 || tmp == VOID_TYPE || tmp == OFFSET_TYPE))
04114 pedwarn ("ISO C++ forbids %sing a pointer of type `%T'",
04115 ((code == PREINCREMENT_EXPR
04116 || code == POSTINCREMENT_EXPR)
04117 ? "increment" : "decrement"), argtype);
04118 inc = cxx_sizeof_nowarn (TREE_TYPE (argtype));
04119 }
04120 else
04121 inc = integer_one_node;
04122
04123 inc = cp_convert (argtype, inc);
04124
04125
04126
04127 switch (TREE_CODE (arg))
04128 {
04129 case NOP_EXPR:
04130 case CONVERT_EXPR:
04131 case FLOAT_EXPR:
04132 case FIX_TRUNC_EXPR:
04133 case FIX_FLOOR_EXPR:
04134 case FIX_ROUND_EXPR:
04135 case FIX_CEIL_EXPR:
04136 {
04137 tree incremented, modify, value, compound;
04138 if (! lvalue_p (arg) && pedantic)
04139 pedwarn ("cast to non-reference type used as lvalue");
04140 arg = stabilize_reference (arg);
04141 if (code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR)
04142 value = arg;
04143 else
04144 value = save_expr (arg);
04145 incremented = build (((code == PREINCREMENT_EXPR
04146 || code == POSTINCREMENT_EXPR)
04147 ? PLUS_EXPR : MINUS_EXPR),
04148 argtype, value, inc);
04149
04150 modify = build_modify_expr (arg, NOP_EXPR, incremented);
04151 compound = build (COMPOUND_EXPR, TREE_TYPE (arg), modify, value);
04152
04153
04154 TREE_NO_UNUSED_WARNING (compound) = 1;
04155 return compound;
04156 }
04157
04158 default:
04159 break;
04160 }
04161
04162
04163 if (!lvalue_or_else (arg, ((code == PREINCREMENT_EXPR
04164 || code == POSTINCREMENT_EXPR)
04165 ? "increment" : "decrement")))
04166 return error_mark_node;
04167
04168
04169 if (TREE_TYPE (arg) == boolean_type_node)
04170 {
04171 if (code == POSTDECREMENT_EXPR || code == PREDECREMENT_EXPR)
04172 {
04173 error ("invalid use of `--' on bool variable `%D'", arg);
04174 return error_mark_node;
04175 }
04176 #if 0
04177
04178
04179 val = build (code, TREE_TYPE (arg), arg, inc);
04180 #else
04181 val = boolean_increment (code, arg);
04182 #endif
04183 }
04184 else
04185 val = build (code, TREE_TYPE (arg), arg, inc);
04186
04187 TREE_SIDE_EFFECTS (val) = 1;
04188 return cp_convert (result_type, val);
04189 }
04190
04191 case ADDR_EXPR:
04192
04193
04194
04195 argtype = lvalue_type (arg);
04196 if (TREE_CODE (argtype) == REFERENCE_TYPE)
04197 {
04198 arg = build1
04199 (CONVERT_EXPR,
04200 build_pointer_type (TREE_TYPE (argtype)), arg);
04201 TREE_CONSTANT (arg) = TREE_CONSTANT (TREE_OPERAND (arg, 0));
04202 return arg;
04203 }
04204 else if (pedantic && DECL_MAIN_P (arg))
04205
04206 pedwarn ("ISO C++ forbids taking address of function `::main'");
04207
04208
04209 if (TREE_CODE (arg) == INDIRECT_REF)
04210 {
04211
04212
04213 if (arg == current_class_ref)
04214 return current_class_ptr;
04215
04216 arg = TREE_OPERAND (arg, 0);
04217 if (TREE_CODE (TREE_TYPE (arg)) == REFERENCE_TYPE)
04218 {
04219 arg = build1
04220 (CONVERT_EXPR,
04221 build_pointer_type (TREE_TYPE (TREE_TYPE (arg))), arg);
04222 TREE_CONSTANT (arg) = TREE_CONSTANT (TREE_OPERAND (arg, 0));
04223 }
04224 else if (lvalue_p (arg))
04225
04226 return non_lvalue (arg);
04227 return arg;
04228 }
04229
04230
04231 if (TREE_CODE (arg) == ARRAY_REF)
04232 {
04233 if (!cxx_mark_addressable (TREE_OPERAND (arg, 0)))
04234 return error_mark_node;
04235 return cp_build_binary_op (PLUS_EXPR, TREE_OPERAND (arg, 0),
04236 TREE_OPERAND (arg, 1));
04237 }
04238
04239
04240
04241
04242
04243 if (TREE_CODE (arg) == IDENTIFIER_NODE
04244 && IDENTIFIER_OPNAME_P (arg))
04245 {
04246 abort ();
04247
04248
04249 return build1 (ADDR_EXPR, unknown_type_node, arg);
04250 }
04251
04252 if (TREE_CODE (arg) == COMPONENT_REF && type_unknown_p (arg)
04253 && !really_overloaded_fn (TREE_OPERAND (arg, 1)))
04254 {
04255
04256
04257
04258
04259
04260
04261
04262
04263
04264
04265 tree base = TREE_TYPE (TREE_OPERAND (arg, 0));
04266 tree name = DECL_NAME (get_first_fn (TREE_OPERAND (arg, 1)));
04267
04268 if (! flag_ms_extensions)
04269 {
04270 if (current_class_type
04271 && TREE_OPERAND (arg, 0) == current_class_ref)
04272
04273 pedwarn ("ISO C++ forbids taking the address of an unqualified non-static member function to form a pointer to member function. Say `&%T::%D'", base, name);
04274 else
04275 pedwarn ("ISO C++ forbids taking the address of a bound member function to form a pointer to member function. Say `&%T::%D'", base, name);
04276 }
04277 arg = build_offset_ref (base, name);
04278 }
04279
04280 if (type_unknown_p (arg))
04281 return build1 (ADDR_EXPR, unknown_type_node, arg);
04282
04283
04284
04285 val = unary_complex_lvalue (code, arg);
04286 if (val != 0)
04287 return val;
04288
04289 switch (TREE_CODE (arg))
04290 {
04291 case NOP_EXPR:
04292 case CONVERT_EXPR:
04293 case FLOAT_EXPR:
04294 case FIX_TRUNC_EXPR:
04295 case FIX_FLOOR_EXPR:
04296 case FIX_ROUND_EXPR:
04297 case FIX_CEIL_EXPR:
04298 if (! lvalue_p (arg) && pedantic)
04299 pedwarn ("ISO C++ forbids taking the address of a cast to a non-lvalue expression");
04300 break;
04301
04302 default:
04303 break;
04304 }
04305
04306
04307
04308 if (TREE_CODE (arg) == CONSTRUCTOR && TREE_HAS_CONSTRUCTOR (arg)
04309 && TREE_CONSTANT (arg))
04310 ;
04311
04312
04313 else if (TREE_CODE (argtype) != FUNCTION_TYPE
04314 && TREE_CODE (argtype) != METHOD_TYPE
04315 && !non_cast_lvalue_or_else (arg, "unary `&'"))
04316 return error_mark_node;
04317
04318 if (argtype != error_mark_node)
04319 argtype = build_pointer_type (argtype);
04320
04321 {
04322 tree addr;
04323
04324 if (TREE_CODE (arg) != COMPONENT_REF)
04325 addr = build_address (arg);
04326 else if (DECL_C_BIT_FIELD (TREE_OPERAND (arg, 1)))
04327 {
04328 error ("attempt to take address of bit-field structure member `%D'",
04329 TREE_OPERAND (arg, 1));
04330 return error_mark_node;
04331 }
04332 else
04333 {
04334
04335
04336
04337 tree field = TREE_OPERAND (arg, 1);
04338 tree rval = build_unary_op (ADDR_EXPR, TREE_OPERAND (arg, 0), 0);
04339 tree binfo = lookup_base (TREE_TYPE (TREE_TYPE (rval)),
04340 decl_type_context (field),
04341 ba_check, NULL);
04342
04343 rval = build_base_path (PLUS_EXPR, rval, binfo, 1);
04344 rval = build1 (NOP_EXPR, argtype, rval);
04345 TREE_CONSTANT (rval) = TREE_CONSTANT (TREE_OPERAND (rval, 0));
04346 addr = fold (build (PLUS_EXPR, argtype, rval,
04347 cp_convert (argtype, byte_position (field))));
04348 }
04349
04350 if (TREE_CODE (argtype) == POINTER_TYPE
04351 && TREE_CODE (TREE_TYPE (argtype)) == METHOD_TYPE)
04352 {
04353 build_ptrmemfunc_type (argtype);
04354 addr = build_ptrmemfunc (argtype, addr, 0);
04355 }
04356
04357 return addr;
04358 }
04359
04360 default:
04361 break;
04362 }
04363
04364 if (!errstring)
04365 {
04366 if (argtype == 0)
04367 argtype = TREE_TYPE (arg);
04368 return fold (build1 (code, argtype, arg));
04369 }
04370
04371 error ("%s", errstring);
04372 return error_mark_node;
04373 }
04374
04375
04376
04377
04378
04379
04380
04381 tree
04382 unary_complex_lvalue (code, arg)
04383 enum tree_code code;
04384 tree arg;
04385 {
04386
04387 if (TREE_CODE (arg) == COMPOUND_EXPR)
04388 {
04389 tree real_result = build_unary_op (code, TREE_OPERAND (arg, 1), 0);
04390 return build (COMPOUND_EXPR, TREE_TYPE (real_result),
04391 TREE_OPERAND (arg, 0), real_result);
04392 }
04393
04394
04395 if (TREE_CODE (arg) == COND_EXPR
04396 || TREE_CODE (arg) == MIN_EXPR || TREE_CODE (arg) == MAX_EXPR)
04397 return rationalize_conditional_expr (code, arg);
04398
04399
04400 if (TREE_CODE (arg) == MODIFY_EXPR
04401 || TREE_CODE (arg) == PREINCREMENT_EXPR
04402 || TREE_CODE (arg) == PREDECREMENT_EXPR)
04403 {
04404 tree lvalue = TREE_OPERAND (arg, 0);
04405 if (TREE_SIDE_EFFECTS (lvalue))
04406 {
04407 lvalue = stabilize_reference (lvalue);
04408 arg = build (TREE_CODE (arg), TREE_TYPE (arg),
04409 lvalue, TREE_OPERAND (arg, 1));
04410 }
04411 return unary_complex_lvalue
04412 (code, build (COMPOUND_EXPR, TREE_TYPE (lvalue), arg, lvalue));
04413 }
04414
04415 if (code != ADDR_EXPR)
04416 return 0;
04417
04418
04419 if (TREE_CODE (arg) == MODIFY_EXPR
04420 || TREE_CODE (arg) == INIT_EXPR)
04421 {
04422 tree real_result = build_unary_op (code, TREE_OPERAND (arg, 0), 0);
04423 arg = build (COMPOUND_EXPR, TREE_TYPE (real_result), arg, real_result);
04424 TREE_NO_UNUSED_WARNING (arg) = 1;
04425 return arg;
04426 }
04427
04428 if (TREE_CODE (TREE_TYPE (arg)) == FUNCTION_TYPE
04429 || TREE_CODE (TREE_TYPE (arg)) == METHOD_TYPE
04430 || TREE_CODE (TREE_TYPE (arg)) == OFFSET_TYPE)
04431 {
04432
04433
04434
04435 tree t;
04436
04437 my_friendly_assert (TREE_CODE (arg) != SCOPE_REF, 313);
04438
04439 if (TREE_CODE (arg) != OFFSET_REF)
04440 return 0;
04441
04442 t = TREE_OPERAND (arg, 1);
04443
04444
04445 if (TREE_CODE (t) == FUNCTION_DECL)
04446 {
04447 if (DECL_DESTRUCTOR_P (t))
04448 error ("taking address of destructor");
04449 return build_unary_op (ADDR_EXPR, t, 0);
04450 }
04451 if (TREE_CODE (t) == VAR_DECL)
04452 return build_unary_op (ADDR_EXPR, t, 0);
04453 else
04454 {
04455 tree type;
04456
04457 if (TREE_OPERAND (arg, 0)
04458 && ! is_dummy_object (TREE_OPERAND (arg, 0))
04459 && TREE_CODE (t) != FIELD_DECL)
04460 {
04461 error ("taking address of bound pointer-to-member expression");
04462 return error_mark_node;
04463 }
04464 if (!PTRMEM_OK_P (arg))
04465 {
04466
04467
04468
04469
04470 arg = resolve_offset_ref (arg);
04471
04472 return build_unary_op (code, arg, 0);
04473 }
04474
04475 if (TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE)
04476 {
04477 error ("cannot create pointer to reference member `%D'", t);
04478 return error_mark_node;
04479 }
04480
04481 type = build_ptrmem_type (DECL_FIELD_CONTEXT (t), TREE_TYPE (t));
04482 t = make_ptrmem_cst (type, TREE_OPERAND (arg, 1));
04483 return t;
04484 }
04485 }
04486
04487
04488
04489
04490 {
04491 tree targ = arg;
04492
04493 if (TREE_CODE (targ) == SAVE_EXPR)
04494 targ = TREE_OPERAND (targ, 0);
04495
04496 if (TREE_CODE (targ) == CALL_EXPR && IS_AGGR_TYPE (TREE_TYPE (targ)))
04497 {
04498 if (TREE_CODE (arg) == SAVE_EXPR)
04499 targ = arg;
04500 else
04501 targ = build_cplus_new (TREE_TYPE (arg), arg);
04502 return build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg)), targ);
04503 }
04504
04505 if (TREE_CODE (arg) == SAVE_EXPR && TREE_CODE (targ) == INDIRECT_REF)
04506 return build (SAVE_EXPR, build_pointer_type (TREE_TYPE (arg)),
04507 TREE_OPERAND (targ, 0), current_function_decl, NULL);
04508 }
04509
04510
04511 return 0;
04512 }
04513
04514
04515
04516
04517
04518
04519
04520 bool
04521 cxx_mark_addressable (exp)
04522 tree exp;
04523 {
04524 register tree x = exp;
04525
04526 while (1)
04527 switch (TREE_CODE (x))
04528 {
04529 case ADDR_EXPR:
04530 case COMPONENT_REF:
04531 case ARRAY_REF:
04532 case REALPART_EXPR:
04533 case IMAGPART_EXPR:
04534 x = TREE_OPERAND (x, 0);
04535 break;
04536
04537 case PARM_DECL:
04538 if (x == current_class_ptr)
04539 {
04540 error ("cannot take the address of `this', which is an rvalue expression");
04541 TREE_ADDRESSABLE (x) = 1;
04542 return true;
04543 }
04544
04545
04546 case VAR_DECL:
04547
04548
04549 my_friendly_assert (DECL_LANG_SPECIFIC (x) == 0
04550 || DECL_IN_AGGR_P (x) == 0
04551 || TREE_STATIC (x)
04552 || DECL_EXTERNAL (x), 314);
04553
04554
04555 case CONST_DECL:
04556 case RESULT_DECL:
04557 if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)
04558 && !DECL_ARTIFICIAL (x) && extra_warnings)
04559 warning ("address requested for `%D', which is declared `register'",
04560 x);
04561 TREE_ADDRESSABLE (x) = 1;
04562 put_var_into_stack (x, true);
04563 return true;
04564
04565 case FUNCTION_DECL:
04566 TREE_ADDRESSABLE (x) = 1;
04567 TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (x)) = 1;
04568 return true;
04569
04570 case CONSTRUCTOR:
04571 TREE_ADDRESSABLE (x) = 1;
04572 return true;
04573
04574 case TARGET_EXPR:
04575 TREE_ADDRESSABLE (x) = 1;
04576 cxx_mark_addressable (TREE_OPERAND (x, 0));
04577 return true;
04578
04579 default:
04580 return true;
04581 }
04582 }
04583
04584
04585
04586 tree
04587 build_x_conditional_expr (ifexp, op1, op2)
04588 tree ifexp, op1, op2;
04589 {
04590 if (processing_template_decl)
04591 return build_min_nt (COND_EXPR, ifexp, op1, op2);
04592
04593 return build_conditional_expr (ifexp, op1, op2);
04594 }
04595
04596
04597
04598
04599 tree
04600 build_x_compound_expr (list)
04601 tree list;
04602 {
04603 tree rest = TREE_CHAIN (list);
04604 tree result;
04605
04606 if (processing_template_decl)
04607 return build_min_nt (COMPOUND_EXPR, list, NULL_TREE);
04608
04609 if (rest == NULL_TREE)
04610 return build_compound_expr (list);
04611
04612 result = build_opfncall (COMPOUND_EXPR, LOOKUP_NORMAL,
04613 TREE_VALUE (list), TREE_VALUE (rest), NULL_TREE);
04614 if (result)
04615 return build_x_compound_expr (tree_cons (NULL_TREE, result,
04616 TREE_CHAIN (rest)));
04617
04618 if (! TREE_SIDE_EFFECTS (TREE_VALUE (list)))
04619 {
04620
04621
04622
04623
04624 if ((extra_warnings || warn_unused_value)
04625 && !(TREE_CODE (TREE_VALUE(list)) == CONVERT_EXPR
04626 && VOID_TYPE_P (TREE_TYPE (TREE_VALUE(list)))))
04627 warning("left-hand operand of comma expression has no effect");
04628 }
04629 #if 0
04630 else if (warn_unused_value)
04631 warn_if_unused_value (TREE_VALUE(list));
04632 #endif
04633
04634 return build_compound_expr
04635 (tree_cons (NULL_TREE, TREE_VALUE (list),
04636 build_tree_list (NULL_TREE,
04637 build_x_compound_expr (rest))));
04638 }
04639
04640
04641
04642
04643 tree
04644 build_compound_expr (list)
04645 tree list;
04646 {
04647 register tree rest;
04648 tree first;
04649
04650 TREE_VALUE (list) = decl_constant_value (TREE_VALUE (list));
04651
04652 if (TREE_CHAIN (list) == 0)
04653 {
04654
04655
04656 if (TREE_CODE (list) == NOP_EXPR
04657 && TREE_TYPE (list) == TREE_TYPE (TREE_OPERAND (list, 0)))
04658 list = TREE_OPERAND (list, 0);
04659
04660 return TREE_VALUE (list);
04661 }
04662
04663 first = TREE_VALUE (list);
04664 first = convert_to_void (first, "left-hand operand of comma");
04665 if (first == error_mark_node)
04666 return error_mark_node;
04667
04668 rest = build_compound_expr (TREE_CHAIN (list));
04669 if (rest == error_mark_node)
04670 return error_mark_node;
04671
04672
04673 if (! TREE_SIDE_EFFECTS (first) && ! pedantic)
04674 return rest;
04675
04676 return build (COMPOUND_EXPR, TREE_TYPE (rest), first, rest);
04677 }
04678
04679
04680
04681
04682 static void
04683 check_for_casting_away_constness (tree src_type, tree dest_type)
04684 {
04685 if (casts_away_constness (src_type, dest_type))
04686 error ("static_cast from type `%T' to type `%T' casts away constness",
04687 src_type, dest_type);
04688 }
04689
04690
04691
04692 tree
04693 build_static_cast (type, expr)
04694 tree type, expr;
04695 {
04696 tree intype;
04697 tree result;
04698
04699 if (type == error_mark_node || expr == error_mark_node)
04700 return error_mark_node;
04701
04702 if (TREE_CODE (expr) == OFFSET_REF)
04703 expr = resolve_offset_ref (expr);
04704
04705 if (processing_template_decl)
04706 {
04707 tree t = build_min (STATIC_CAST_EXPR, type, expr);
04708 return t;
04709 }
04710
04711
04712
04713 if (TREE_CODE (type) != REFERENCE_TYPE
04714 && TREE_CODE (expr) == NOP_EXPR
04715 && TREE_TYPE (expr) == TREE_TYPE (TREE_OPERAND (expr, 0)))
04716 expr = TREE_OPERAND (expr, 0);
04717
04718 intype = TREE_TYPE (expr);
04719
04720
04721
04722
04723
04724
04725
04726
04727
04728
04729
04730
04731
04732
04733
04734
04735
04736
04737
04738
04739 if (TREE_CODE (type) == REFERENCE_TYPE
04740 && CLASS_TYPE_P (TREE_TYPE (type))
04741 && CLASS_TYPE_P (intype)
04742 && real_non_cast_lvalue_p (expr)
04743 && DERIVED_FROM_P (intype, TREE_TYPE (type))
04744 && can_convert (build_pointer_type (TYPE_MAIN_VARIANT (intype)),
04745 build_pointer_type (TYPE_MAIN_VARIANT
04746 (TREE_TYPE (type))))
04747 && at_least_as_qualified_p (TREE_TYPE (type), intype))
04748 {
04749
04750
04751
04752 tree base = lookup_base (TREE_TYPE (type), intype, ba_check, NULL);
04753
04754
04755
04756 expr = build_base_path (MINUS_EXPR, build_address (expr),
04757 base, false);
04758
04759
04760 return convert_from_reference (build_nop (type, expr));
04761 }
04762
04763
04764
04765
04766
04767
04768
04769 result = perform_direct_initialization_if_possible (type, expr);
04770 if (result)
04771 return convert_from_reference (result);
04772
04773
04774
04775
04776 if (TREE_CODE (type) == VOID_TYPE)
04777 return convert_to_void (expr, NULL);
04778
04779
04780
04781
04782
04783
04784
04785
04786
04787
04788
04789
04790
04791
04792 if ((ARITHMETIC_TYPE_P (type) && ARITHMETIC_TYPE_P (intype))
04793
04794
04795
04796
04797 || (INTEGRAL_OR_ENUMERATION_TYPE_P (type)
04798 && INTEGRAL_OR_ENUMERATION_TYPE_P (intype)))
04799
04800
04801 return build_c_cast (type, expr);
04802 if (TYPE_PTR_P (type) && TYPE_PTR_P (intype)
04803 && CLASS_TYPE_P (TREE_TYPE (type))
04804 && CLASS_TYPE_P (TREE_TYPE (intype))
04805 && can_convert (build_pointer_type (TYPE_MAIN_VARIANT
04806 (TREE_TYPE (intype))),
04807 build_pointer_type (TYPE_MAIN_VARIANT
04808 (TREE_TYPE (type)))))
04809 {
04810 tree base;
04811
04812 check_for_casting_away_constness (intype, type);
04813 base = lookup_base (TREE_TYPE (type), TREE_TYPE (intype),
04814 ba_check, NULL);
04815 return build_base_path (MINUS_EXPR, expr, base, false);
04816 }
04817 if ((TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype))
04818 || (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype)))
04819 {
04820 tree c1;
04821 tree c2;
04822 tree t1;
04823 tree t2;
04824
04825 c1 = TYPE_PTRMEM_CLASS_TYPE (intype);
04826 c2 = TYPE_PTRMEM_CLASS_TYPE (type);
04827
04828 if (TYPE_PTRMEM_P (type))
04829 {
04830 t1 = (build_ptrmem_type
04831 (c1,
04832 TYPE_MAIN_VARIANT (TYPE_PTRMEM_POINTED_TO_TYPE (intype))));
04833 t2 = (build_ptrmem_type
04834 (c2,
04835 TYPE_MAIN_VARIANT (TYPE_PTRMEM_POINTED_TO_TYPE (type))));
04836 }
04837 else
04838 {
04839 t1 = intype;
04840 t2 = type;
04841 }
04842 if (can_convert (t1, t2))
04843 {
04844 check_for_casting_away_constness (intype, type);
04845 if (TYPE_PTRMEM_P (type))
04846 {
04847 if (TREE_CODE (expr) == PTRMEM_CST)
04848 expr = cplus_expand_constant (expr);
04849 expr = cp_build_binary_op (PLUS_EXPR,
04850 cp_convert (ptrdiff_type_node, expr),
04851 get_delta_difference (c1, c2,
04852 1));
04853 return build_nop (type, expr);
04854 }
04855 else
04856 return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr,
04857 1);
04858 }
04859 }
04860
04861
04862
04863
04864
04865
04866
04867 if (TREE_CODE (intype) == POINTER_TYPE
04868 && VOID_TYPE_P (TREE_TYPE (intype))
04869 && TYPE_PTROB_P (type))
04870 {
04871 check_for_casting_away_constness (intype, type);
04872 return build_nop (type, expr);
04873 }
04874
04875 error ("invalid static_cast from type `%T' to type `%T'", intype, type);
04876 return error_mark_node;
04877 }
04878
04879 tree
04880 build_reinterpret_cast (type, expr)
04881 tree type, expr;
04882 {
04883 tree intype;
04884
04885 if (type == error_mark_node || expr == error_mark_node)
04886 return error_mark_node;
04887
04888 if (TREE_CODE (expr) == OFFSET_REF)
04889 expr = resolve_offset_ref (expr);
04890
04891 if (processing_template_decl)
04892 {
04893 tree t = build_min (REINTERPRET_CAST_EXPR, type, expr);
04894 return t;
04895 }
04896
04897 if (TREE_CODE (type) != REFERENCE_TYPE)
04898 {
04899 expr = decay_conversion (expr);
04900
04901
04902
04903 if (TREE_CODE (expr) == NOP_EXPR
04904 && TREE_TYPE (expr) == TREE_TYPE (TREE_OPERAND (expr, 0)))
04905 expr = TREE_OPERAND (expr, 0);
04906 }
04907
04908 intype = TREE_TYPE (expr);
04909
04910 if (TREE_CODE (type) == REFERENCE_TYPE)
04911 {
04912 if (! real_lvalue_p (expr))
04913 {
04914 error ("invalid reinterpret_cast of an rvalue expression of type `%T' to type `%T'", intype, type);
04915 return error_mark_node;
04916 }
04917 expr = build_unary_op (ADDR_EXPR, expr, 0);
04918 if (expr != error_mark_node)
04919 expr = build_reinterpret_cast
04920 (build_pointer_type (TREE_TYPE (type)), expr);
04921 if (expr != error_mark_node)
04922 expr = build_indirect_ref (expr, 0);
04923 return expr;
04924 }
04925 else if (same_type_ignoring_top_level_qualifiers_p (intype, type))
04926 return build_static_cast (type, expr);
04927
04928 if (TYPE_PTR_P (type) && (TREE_CODE (intype) == INTEGER_TYPE
04929 || TREE_CODE (intype) == ENUMERAL_TYPE))
04930 ;
04931 else if (TREE_CODE (type) == INTEGER_TYPE && TYPE_PTR_P (intype))
04932 {
04933 if (TYPE_PRECISION (type) < TYPE_PRECISION (intype))
04934 pedwarn ("reinterpret_cast from `%T' to `%T' loses precision",
04935 intype, type);
04936 }
04937 else if ((TYPE_PTRFN_P (type) && TYPE_PTRFN_P (intype))
04938 || (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype)))
04939 {
04940 expr = decl_constant_value (expr);
04941 return fold (build1 (NOP_EXPR, type, expr));
04942 }
04943 else if ((TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype))
04944 || (TYPE_PTROBV_P (type) && TYPE_PTROBV_P (intype)))
04945 {
04946 if (! comp_ptr_ttypes_reinterpret (TREE_TYPE (type), TREE_TYPE (intype)))
04947 pedwarn ("reinterpret_cast from `%T' to `%T' casts away const (or volatile)",
04948 intype, type);
04949
04950 expr = decl_constant_value (expr);
04951 return fold (build1 (NOP_EXPR, type, expr));
04952 }
04953 else if ((TYPE_PTRFN_P (type) && TYPE_PTROBV_P (intype))
04954 || (TYPE_PTRFN_P (intype) && TYPE_PTROBV_P (type)))
04955 {
04956 pedwarn ("ISO C++ forbids casting between pointer-to-function and pointer-to-object");
04957 expr = decl_constant_value (expr);
04958 return fold (build1 (NOP_EXPR, type, expr));
04959 }
04960 else
04961 {
04962 error ("invalid reinterpret_cast from type `%T' to type `%T'",
04963 intype, type);
04964 return error_mark_node;
04965 }
04966
04967 return cp_convert (type, expr);
04968 }
04969
04970 tree
04971 build_const_cast (type, expr)
04972 tree type, expr;
04973 {
04974 tree intype;
04975
04976 if (type == error_mark_node || expr == error_mark_node)
04977 return error_mark_node;
04978
04979 if (TREE_CODE (expr) == OFFSET_REF)
04980 expr = resolve_offset_ref (expr);
04981
04982 if (processing_template_decl)
04983 {
04984 tree t = build_min (CONST_CAST_EXPR, type, expr);
04985 return t;
04986 }
04987
04988 if (!POINTER_TYPE_P (type))
04989 error ("invalid use of const_cast with type `%T', which is not a pointer, reference, nor a pointer-to-data-member type", type);
04990 else if (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
04991 {
04992 error ("invalid use of const_cast with type `%T', which is a pointer or reference to a function type", type);
04993 return error_mark_node;
04994 }
04995
04996 if (TREE_CODE (type) != REFERENCE_TYPE)
04997 {
04998 expr = decay_conversion (expr);
04999
05000
05001
05002 if (TREE_CODE (expr) == NOP_EXPR
05003 && TREE_TYPE (expr) == TREE_TYPE (TREE_OPERAND (expr, 0)))
05004 expr = TREE_OPERAND (expr, 0);
05005 }
05006
05007 intype = TREE_TYPE (expr);
05008
05009 if (same_type_ignoring_top_level_qualifiers_p (intype, type))
05010 return build_static_cast (type, expr);
05011 else if (TREE_CODE (type) == REFERENCE_TYPE)
05012 {
05013 if (! real_lvalue_p (expr))
05014 {
05015 error ("invalid const_cast of an rvalue of type `%T' to type `%T'", intype, type);
05016 return error_mark_node;
05017 }
05018
05019 if (comp_ptr_ttypes_const (TREE_TYPE (type), intype))
05020 {
05021 expr = build_unary_op (ADDR_EXPR, expr, 0);
05022 expr = build1 (NOP_EXPR, type, expr);
05023 return convert_from_reference (expr);
05024 }
05025 }
05026 else if (TREE_CODE (type) == POINTER_TYPE
05027 && TREE_CODE (intype) == POINTER_TYPE
05028 && comp_ptr_ttypes_const (TREE_TYPE (type), TREE_TYPE (intype)))
05029 return cp_convert (type, expr);
05030
05031 error ("invalid const_cast from type `%T' to type `%T'", intype, type);
05032 return error_mark_node;
05033 }
05034
05035
05036
05037
05038
05039
05040 tree
05041 build_c_cast (type, expr)
05042 tree type, expr;
05043 {
05044 register tree value = expr;
05045 tree otype;
05046
05047 if (type == error_mark_node || expr == error_mark_node)
05048 return error_mark_node;
05049
05050 if (processing_template_decl)
05051 {
05052 tree t = build_min (CAST_EXPR, type,
05053 tree_cons (NULL_TREE, value, NULL_TREE));
05054 return t;
05055 }
05056
05057
05058
05059 if (TREE_CODE (type) != REFERENCE_TYPE
05060 && TREE_CODE (value) == NOP_EXPR
05061 && TREE_TYPE (value) == TREE_TYPE (TREE_OPERAND (value, 0)))
05062 value = TREE_OPERAND (value, 0);
05063
05064 if (TREE_CODE (value) == OFFSET_REF)
05065 value = resolve_offset_ref (value);
05066
05067 if (TREE_CODE (type) == ARRAY_TYPE)
05068 {
05069
05070
05071 if (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE)
05072 {
05073 pedwarn ("ISO C++ forbids casting to an array type `%T'", type);
05074 type = build_pointer_type (TREE_TYPE (type));
05075 }
05076 else
05077 {
05078 error ("ISO C++ forbids casting to an array type `%T'", type);
05079 return error_mark_node;
05080 }
05081 }
05082
05083 if (TREE_CODE (type) == FUNCTION_TYPE
05084 || TREE_CODE (type) == METHOD_TYPE)
05085 {
05086 error ("invalid cast to function type `%T'", type);
05087 return error_mark_node;
05088 }
05089
05090 if (TREE_CODE (type) == VOID_TYPE)
05091 {
05092
05093
05094
05095 value = convert_to_void (value, NULL);
05096 return value;
05097 }
05098
05099 if (!complete_type_or_else (type, NULL_TREE))
05100 return error_mark_node;
05101
05102
05103
05104
05105
05106
05107
05108
05109
05110
05111
05112
05113
05114
05115 if (!IS_AGGR_TYPE (type))
05116 {
05117 if (TREE_CODE (TREE_TYPE (value)) == FUNCTION_TYPE
05118 || (TREE_CODE (TREE_TYPE (value)) == METHOD_TYPE
05119
05120 && ! (TREE_CODE (type) == POINTER_TYPE
05121 && bound_pmf_p (value)))
05122 || TREE_CODE (TREE_TYPE (value)) == ARRAY_TYPE
05123 || TREE_CODE (TREE_TYPE (value)) == REFERENCE_TYPE)
05124 value = default_conversion (value);
05125 }
05126 else if (TREE_CODE (TREE_TYPE (value)) == REFERENCE_TYPE)
05127
05128
05129
05130
05131 value = convert_from_reference (value);
05132
05133 otype = TREE_TYPE (value);
05134
05135
05136
05137 if (warn_cast_qual
05138 && TREE_CODE (type) == POINTER_TYPE
05139 && TREE_CODE (otype) == POINTER_TYPE
05140 && !at_least_as_qualified_p (TREE_TYPE (type),
05141 TREE_TYPE (otype)))
05142 warning ("cast from `%T' to `%T' discards qualifiers from pointer target type",
05143 otype, type);
05144
05145 if (TREE_CODE (type) == INTEGER_TYPE
05146 && TREE_CODE (otype) == POINTER_TYPE
05147 && TYPE_PRECISION (type) != TYPE_PRECISION (otype))
05148 warning ("cast from pointer to integer of different size");
05149
05150 if (TREE_CODE (type) == POINTER_TYPE
05151 && TREE_CODE (otype) == INTEGER_TYPE
05152 && TYPE_PRECISION (type) != TYPE_PRECISION (otype)
05153
05154 && !TREE_CONSTANT (value))
05155 warning ("cast to pointer from integer of different size");
05156
05157 if (TREE_CODE (type) == REFERENCE_TYPE)
05158 value = (convert_from_reference
05159 (convert_to_reference (type, value, CONV_C_CAST,
05160 LOOKUP_COMPLAIN, NULL_TREE)));
05161 else
05162 {
05163 tree ovalue;
05164
05165 value = decl_constant_value (value);
05166
05167 ovalue = value;
05168 value = convert_force (type, value, CONV_C_CAST);
05169
05170
05171 if (TREE_CODE (value) == INTEGER_CST)
05172 {
05173 TREE_OVERFLOW (value) = TREE_OVERFLOW (ovalue);
05174 TREE_CONSTANT_OVERFLOW (value) = TREE_CONSTANT_OVERFLOW (ovalue);
05175 }
05176 }
05177
05178
05179
05180 if (STRICT_ALIGNMENT && warn_cast_align
05181 && TREE_CODE (type) == POINTER_TYPE
05182 && TREE_CODE (otype) == POINTER_TYPE
05183 && TREE_CODE (TREE_TYPE (otype)) != VOID_TYPE
05184 && TREE_CODE (TREE_TYPE (otype)) != FUNCTION_TYPE
05185 && COMPLETE_TYPE_P (TREE_TYPE (otype))
05186 && COMPLETE_TYPE_P (TREE_TYPE (type))
05187 && TYPE_ALIGN (TREE_TYPE (type)) > TYPE_ALIGN (TREE_TYPE (otype)))
05188 warning ("cast from `%T' to `%T' increases required alignment of target type",
05189 otype, type);
05190
05191
05192
05193 if (TREE_CODE (type) != REFERENCE_TYPE && value == expr
05194 && real_lvalue_p (value))
05195 value = non_lvalue (value);
05196
05197 return value;
05198 }
05199
05200
05201
05202
05203
05204
05205
05206
05207 tree
05208 build_modify_expr (lhs, modifycode, rhs)
05209 tree lhs;
05210 enum tree_code modifycode;
05211 tree rhs;
05212 {
05213 register tree result;
05214 tree newrhs = rhs;
05215 tree lhstype = TREE_TYPE (lhs);
05216 tree olhstype = lhstype;
05217 tree olhs = lhs;
05218
05219
05220 if (lhs == error_mark_node || rhs == error_mark_node)
05221 return error_mark_node;
05222
05223
05224 switch (TREE_CODE (lhs))
05225 {
05226
05227 case PREDECREMENT_EXPR:
05228 case PREINCREMENT_EXPR:
05229 if (TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0)))
05230 lhs = build (TREE_CODE (lhs), TREE_TYPE (lhs),
05231 stabilize_reference (TREE_OPERAND (lhs, 0)),
05232 TREE_OPERAND (lhs, 1));
05233 return build (COMPOUND_EXPR, lhstype,
05234 lhs,
05235 build_modify_expr (TREE_OPERAND (lhs, 0),
05236 modifycode, rhs));
05237
05238
05239 case COMPOUND_EXPR:
05240 newrhs = build_modify_expr (TREE_OPERAND (lhs, 1),
05241 modifycode, rhs);
05242 if (newrhs == error_mark_node)
05243 return error_mark_node;
05244 return build (COMPOUND_EXPR, lhstype,
05245 TREE_OPERAND (lhs, 0), newrhs);
05246
05247 case MODIFY_EXPR:
05248 if (TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0)))
05249 lhs = build (TREE_CODE (lhs), TREE_TYPE (lhs),
05250 stabilize_reference (TREE_OPERAND (lhs, 0)),
05251 TREE_OPERAND (lhs, 1));
05252 newrhs = build_modify_expr (TREE_OPERAND (lhs, 0), modifycode, rhs);
05253 if (newrhs == error_mark_node)
05254 return error_mark_node;
05255 return build (COMPOUND_EXPR, lhstype, lhs, newrhs);
05256
05257
05258 case COND_EXPR:
05259 {
05260
05261
05262
05263 tree cond;
05264 tree preeval = NULL_TREE;
05265
05266 rhs = stabilize_expr (rhs, &preeval);
05267
05268
05269
05270 if (!lvalue_or_else (lhs, "assignment"))
05271 return error_mark_node;
05272
05273 cond = build_conditional_expr
05274 (TREE_OPERAND (lhs, 0),
05275 build_modify_expr (cp_convert (TREE_TYPE (lhs),
05276 TREE_OPERAND (lhs, 1)),
05277 modifycode, rhs),
05278 build_modify_expr (cp_convert (TREE_TYPE (lhs),
05279 TREE_OPERAND (lhs, 2)),
05280 modifycode, rhs));
05281
05282 if (cond == error_mark_node)
05283 return cond;
05284
05285
05286 return build (COMPOUND_EXPR, TREE_TYPE (lhs), preeval, cond);
05287 }
05288
05289 case OFFSET_REF:
05290 lhs = resolve_offset_ref (lhs);
05291 if (lhs == error_mark_node)
05292 return error_mark_node;
05293 olhstype = lhstype = TREE_TYPE (lhs);
05294
05295 default:
05296 break;
05297 }
05298
05299 if (modifycode == INIT_EXPR)
05300 {
05301 if (TREE_CODE (rhs) == CONSTRUCTOR)
05302 {
05303 my_friendly_assert (same_type_p (TREE_TYPE (rhs), lhstype),
05304 20011220);
05305 result = build (INIT_EXPR, lhstype, lhs, rhs);
05306 TREE_SIDE_EFFECTS (result) = 1;
05307 return result;
05308 }
05309 else if (! IS_AGGR_TYPE (lhstype))
05310 ;
05311 else
05312 {
05313 result = build_special_member_call (lhs, complete_ctor_identifier,
05314 build_tree_list (NULL_TREE, rhs),
05315 TYPE_BINFO (lhstype),
05316 LOOKUP_NORMAL);
05317 if (result == NULL_TREE)
05318 return error_mark_node;
05319 return result;
05320 }
05321 }
05322 else
05323 {
05324 if (TREE_CODE (lhstype) == REFERENCE_TYPE)
05325 {
05326 lhs = convert_from_reference (lhs);
05327 olhstype = lhstype = TREE_TYPE (lhs);
05328 }
05329 lhs = require_complete_type (lhs);
05330 if (lhs == error_mark_node)
05331 return error_mark_node;
05332
05333 if (modifycode == NOP_EXPR)
05334 {
05335
05336 if (! IS_AGGR_TYPE (lhstype))
05337 ;
05338 else
05339 {
05340 result = build_opfncall (MODIFY_EXPR, LOOKUP_NORMAL,
05341 lhs, rhs, make_node (NOP_EXPR));
05342 if (result == NULL_TREE)
05343 return error_mark_node;
05344 return result;
05345 }
05346 lhstype = olhstype;
05347 }
05348 else
05349 {
05350
05351
05352
05353
05354 my_friendly_assert (!PROMOTES_TO_AGGR_TYPE (lhstype, REFERENCE_TYPE),
05355 978652);
05356 lhs = stabilize_reference (lhs);
05357 newrhs = cp_build_binary_op (modifycode, lhs, rhs);
05358 if (newrhs == error_mark_node)
05359 {
05360 error (" in evaluation of `%Q(%#T, %#T)'", modifycode,
05361 TREE_TYPE (lhs), TREE_TYPE (rhs));
05362 return error_mark_node;
05363 }
05364
05365
05366 modifycode = NOP_EXPR;
05367 }
05368 my_friendly_assert (TREE_CODE (lhstype) != REFERENCE_TYPE, 20011220);
05369 my_friendly_assert (TREE_CODE (TREE_TYPE (newrhs)) != REFERENCE_TYPE,
05370 20011220);
05371 }
05372
05373
05374
05375
05376
05377
05378
05379
05380 switch (TREE_CODE (lhs))
05381 {
05382 case NOP_EXPR:
05383 case CONVERT_EXPR:
05384 case FLOAT_EXPR:
05385 case FIX_TRUNC_EXPR:
05386 case FIX_FLOOR_EXPR:
05387 case FIX_ROUND_EXPR:
05388 case FIX_CEIL_EXPR:
05389 {
05390 tree inner_lhs = TREE_OPERAND (lhs, 0);
05391 tree result;
05392
05393 if (TREE_CODE (TREE_TYPE (newrhs)) == ARRAY_TYPE
05394 || TREE_CODE (TREE_TYPE (newrhs)) == FUNCTION_TYPE
05395 || TREE_CODE (TREE_TYPE (newrhs)) == METHOD_TYPE
05396 || TREE_CODE (TREE_TYPE (newrhs)) == OFFSET_TYPE)
05397 newrhs = default_conversion (newrhs);
05398
05399
05400
05401 if (! lvalue_p (lhs))
05402 pedwarn ("ISO C++ forbids cast to non-reference type used as lvalue");
05403
05404 result = build_modify_expr (inner_lhs, NOP_EXPR,
05405 cp_convert (TREE_TYPE (inner_lhs),
05406 cp_convert (lhstype, newrhs)));
05407 if (result == error_mark_node)
05408 return result;
05409 return cp_convert (TREE_TYPE (lhs), result);
05410 }
05411
05412 default:
05413 break;
05414 }
05415
05416
05417
05418
05419 if (!lvalue_or_else (lhs, "assignment"))
05420 return error_mark_node;
05421
05422
05423
05424 if (modifycode != INIT_EXPR
05425 && (TREE_READONLY (lhs) || CP_TYPE_CONST_P (lhstype)
05426
05427
05428 || TREE_CODE (TREE_TYPE (lhs)) == FUNCTION_TYPE
05429 || TREE_CODE (TREE_TYPE (lhs)) == METHOD_TYPE
05430
05431
05432 || (IS_AGGR_TYPE_CODE (TREE_CODE (lhstype))
05433 && C_TYPE_FIELDS_READONLY (lhstype))))
05434 readonly_error (lhs, "assignment", 0);
05435
05436
05437
05438
05439
05440 if (TREE_CODE (lhs) == COMPONENT_REF
05441 && (TREE_CODE (lhstype) == INTEGER_TYPE
05442 || TREE_CODE (lhstype) == REAL_TYPE
05443 || TREE_CODE (lhstype) == ENUMERAL_TYPE))
05444 {
05445 lhstype = TREE_TYPE (get_unwidened (lhs, 0));
05446
05447
05448
05449
05450 if (lhstype != TREE_TYPE (lhs))
05451 {
05452 lhs = copy_node (lhs);
05453 TREE_TYPE (lhs) = lhstype;
05454 }
05455 }
05456
05457 #ifdef KEY
05458
05459
05460 if (TREE_CODE (lhstype) != REFERENCE_TYPE)
05461 {
05462 if (TREE_SIDE_EFFECTS (lhs))
05463 lhs = stabilize_reference (lhs);
05464 if (TREE_SIDE_EFFECTS (newrhs))
05465 newrhs = stabilize_reference (newrhs);
05466 }
05467 #endif
05468
05469
05470
05471 if (TREE_CODE (lhstype) == ARRAY_TYPE)
05472 {
05473 int from_array;
05474
05475 if (!same_or_base_type_p (TYPE_MAIN_VARIANT (lhstype),
05476 TYPE_MAIN_VARIANT (TREE_TYPE (rhs))))
05477 {
05478 error ("incompatible types in assignment of `%T' to `%T'",
05479 TREE_TYPE (rhs), lhstype);
05480 return error_mark_node;
05481 }
05482
05483
05484 if (! DECL_ARTIFICIAL (current_function_decl))
05485 pedwarn ("ISO C++ forbids assignment of arrays");
05486
05487 from_array = TREE_CODE (TREE_TYPE (newrhs)) == ARRAY_TYPE
05488 ? 1 + (modifycode != INIT_EXPR): 0;
05489 return build_vec_init (lhs, NULL_TREE, newrhs, from_array);
05490 }
05491
05492 if (modifycode == INIT_EXPR)
05493 newrhs = convert_for_initialization (lhs, lhstype, newrhs, LOOKUP_NORMAL,
05494 "initialization", NULL_TREE, 0);
05495 else
05496 {
05497
05498 if (TREE_CODE (olhstype) == ENUMERAL_TYPE
05499 && TREE_CODE (lhstype) == INTEGER_TYPE)
05500 {
05501 newrhs = convert_for_assignment (olhstype, newrhs, "assignment",
05502 NULL_TREE, 0);
05503 newrhs = convert_force (lhstype, newrhs, 0);
05504 }
05505 else
05506 newrhs = convert_for_assignment (lhstype, newrhs, "assignment",
05507 NULL_TREE, 0);
05508 if (TREE_CODE (newrhs) == CALL_EXPR
05509 && TYPE_NEEDS_CONSTRUCTING (lhstype))
05510 newrhs = build_cplus_new (lhstype, newrhs);
05511
05512
05513
05514
05515
05516 if (TREE_CODE (newrhs) == TARGET_EXPR)
05517 newrhs = build (COMPOUND_EXPR, TREE_TYPE (newrhs), newrhs,
05518 TREE_OPERAND (newrhs, 0));
05519 }
05520
05521 if (newrhs == error_mark_node)
05522 return error_mark_node;
05523
05524 if (TREE_CODE (newrhs) == COND_EXPR)
05525 {
05526 tree lhs1;
05527 tree cond = TREE_OPERAND (newrhs, 0);
05528
05529 if (TREE_SIDE_EFFECTS (lhs))
05530 cond = build_compound_expr (tree_cons
05531 (NULL_TREE, lhs,
05532 build_tree_list (NULL_TREE, cond)));
05533
05534
05535
05536
05537
05538 lhs1 = break_out_calls (lhs);
05539
05540 if (lhs == lhs1)
05541
05542 result = build (modifycode == NOP_EXPR ? MODIFY_EXPR : INIT_EXPR,
05543 lhstype, lhs, newrhs);
05544 else
05545 {
05546 tree result_type = TREE_TYPE (newrhs);
05547
05548
05549 result
05550 = build (COND_EXPR, result_type, cond,
05551 build_modify_expr (lhs, modifycode,
05552 cp_convert (result_type,
05553 TREE_OPERAND (newrhs, 1))),
05554 build_modify_expr (lhs1, modifycode,
05555 cp_convert (result_type,
05556 TREE_OPERAND (newrhs, 2))));
05557 }
05558 }
05559 else
05560 result = build (modifycode == NOP_EXPR ? MODIFY_EXPR : INIT_EXPR,
05561 lhstype, lhs, newrhs);
05562
05563 TREE_SIDE_EFFECTS (result) = 1;
05564
05565
05566
05567
05568
05569
05570 if (olhstype == TREE_TYPE (result))
05571 return result;
05572
05573
05574 if (TREE_CODE (TREE_TYPE (result)) == INTEGER_TYPE
05575 && TREE_CODE (olhstype) == ENUMERAL_TYPE)
05576 {
05577 result = build (COMPOUND_EXPR, olhstype, result, olhs);
05578 TREE_NO_UNUSED_WARNING (result) = 1;
05579 return result;
05580 }
05581 return convert_for_assignment (olhstype, result, "assignment",
05582 NULL_TREE, 0);
05583 }
05584
05585 tree
05586 build_x_modify_expr (lhs, modifycode, rhs)
05587 tree lhs;
05588 enum tree_code modifycode;
05589 tree rhs;
05590 {
05591 if (processing_template_decl)
05592 return build_min_nt (MODOP_EXPR, lhs,
05593 build_min_nt (modifycode, NULL_TREE, NULL_TREE), rhs);
05594
05595 if (modifycode != NOP_EXPR)
05596 {
05597 tree rval = build_opfncall (MODIFY_EXPR, LOOKUP_NORMAL, lhs, rhs,
05598 make_node (modifycode));
05599 if (rval)
05600 return rval;
05601 }
05602 #if defined(TARG_SL2)
05603
05604
05605
05606 if(TREE_CODE(lhs) == ARRAY_REF)
05607 {
05608 tree opnd0 = TREE_OPERAND(lhs, 0);
05609 while(TREE_CODE(opnd0) == ARRAY_REF)
05610 opnd0 = TREE_OPERAND(opnd0, 0);
05611 if(opnd0 && (TREE_CODE(opnd0) == VAR_DECL) && DECL_VBUF(opnd0))
05612 {
05613 error("direct assignment to vbuf array is forbidden");
05614 }
05615 }
05616 #endif
05617 return build_modify_expr (lhs, modifycode, rhs);
05618 }
05619
05620
05621
05622
05623
05624
05625
05626
05627
05628
05629
05630 static tree
05631 get_delta_difference (from, to, force)
05632 tree from, to;
05633 int force;
05634 {
05635 tree delta = integer_zero_node;
05636 tree binfo;
05637 tree virt_binfo;
05638 base_kind kind;
05639
05640 binfo = lookup_base (to, from, ba_check, &kind);
05641 if (kind == bk_inaccessible || kind == bk_ambig)
05642 {
05643 error (" in pointer to member function conversion");
05644 return delta;
05645 }
05646 if (!binfo)
05647 {
05648 if (!force)
05649 {
05650 error_not_base_type (from, to);
05651 error (" in pointer to member conversion");
05652 return delta;
05653 }
05654 binfo = lookup_base (from, to, ba_check, &kind);
05655 if (binfo == 0)
05656 return delta;
05657 virt_binfo = binfo_from_vbase (binfo);
05658
05659 if (virt_binfo)
05660 {
05661
05662 warning ("pointer to member cast via virtual base `%T' of `%T'",
05663 BINFO_TYPE (virt_binfo),
05664 BINFO_TYPE (BINFO_INHERITANCE_CHAIN (virt_binfo)));
05665 return delta;
05666 }
05667 delta = BINFO_OFFSET (binfo);
05668 delta = cp_convert (ptrdiff_type_node, delta);
05669 delta = cp_build_binary_op (MINUS_EXPR,
05670 integer_zero_node,
05671 delta);
05672
05673 return delta;
05674 }
05675
05676 virt_binfo = binfo_from_vbase (binfo);
05677 if (virt_binfo)
05678 {
05679
05680 if (force)
05681 warning ("pointer to member cast via virtual base `%T' of `%T'",
05682 BINFO_TYPE (virt_binfo),
05683 BINFO_TYPE (BINFO_INHERITANCE_CHAIN (virt_binfo)));
05684 else
05685 error ("pointer to member conversion via virtual base `%T' of `%T'",
05686 BINFO_TYPE (virt_binfo),
05687 BINFO_TYPE (BINFO_INHERITANCE_CHAIN (virt_binfo)));
05688 return delta;
05689 }
05690 delta = BINFO_OFFSET (binfo);
05691
05692 return cp_convert (ptrdiff_type_node, delta);
05693 }
05694
05695
05696
05697
05698 tree
05699 build_ptrmemfunc1 (type, delta, pfn)
05700 tree type, delta, pfn;
05701 {
05702 tree u = NULL_TREE;
05703 tree delta_field;
05704 tree pfn_field;
05705
05706
05707 pfn_field = TYPE_FIELDS (type);
05708 delta_field = TREE_CHAIN (pfn_field);
05709
05710
05711 delta = convert_and_check (delta_type_node, delta);
05712
05713
05714 u = tree_cons (pfn_field, pfn,
05715 build_tree_list (delta_field, delta));
05716 u = build (CONSTRUCTOR, type, NULL_TREE, u);
05717 TREE_CONSTANT (u) = TREE_CONSTANT (pfn) && TREE_CONSTANT (delta);
05718 TREE_STATIC (u) = (TREE_CONSTANT (u)
05719 && (initializer_constant_valid_p (pfn, TREE_TYPE (pfn))
05720 != NULL_TREE)
05721 && (initializer_constant_valid_p (delta, TREE_TYPE (delta))
05722 != NULL_TREE));
05723 return u;
05724 }
05725
05726
05727
05728
05729
05730
05731
05732
05733
05734
05735
05736
05737 tree
05738 build_ptrmemfunc (type, pfn, force)
05739 tree type, pfn;
05740 int force;
05741 {
05742 tree fn;
05743 tree pfn_type;
05744 tree to_type;
05745
05746 if (error_operand_p (pfn))
05747 return error_mark_node;
05748
05749 pfn_type = TREE_TYPE (pfn);
05750 to_type = build_ptrmemfunc_type (type);
05751
05752
05753 if (TYPE_PTRMEMFUNC_P (pfn_type))
05754 {
05755 tree delta = NULL_TREE;
05756 tree npfn = NULL_TREE;
05757 tree n;
05758
05759 if (!force
05760 && !can_convert_arg (to_type, TREE_TYPE (pfn), pfn))
05761 error ("invalid conversion to type `%T' from type `%T'",
05762 to_type, pfn_type);
05763
05764 n = get_delta_difference (TYPE_PTRMEMFUNC_OBJECT_TYPE (pfn_type),
05765 TYPE_PTRMEMFUNC_OBJECT_TYPE (to_type),
05766 force);
05767
05768
05769
05770
05771
05772 if (TREE_CODE (pfn) != PTRMEM_CST)
05773 {
05774 if (same_type_p (to_type, pfn_type))
05775 return pfn;
05776 else if (integer_zerop (n))
05777 return build_reinterpret_cast (to_type, pfn);
05778 }
05779
05780 if (TREE_SIDE_EFFECTS (pfn))
05781 pfn = save_expr (pfn);
05782
05783
05784 if (TREE_CODE (pfn) == PTRMEM_CST)
05785 expand_ptrmemfunc_cst (pfn, &delta, &npfn);
05786 else
05787 {
05788 npfn = build_ptrmemfunc_access_expr (pfn, pfn_identifier);
05789 delta = build_ptrmemfunc_access_expr (pfn, delta_identifier);
05790 }
05791
05792
05793 delta = cp_convert (ptrdiff_type_node, delta);
05794 if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_delta)
05795 n = cp_build_binary_op (LSHIFT_EXPR, n, integer_one_node);
05796 delta = cp_build_binary_op (PLUS_EXPR, delta, n);
05797 return build_ptrmemfunc1 (to_type, delta, npfn);
05798 }
05799
05800
05801 if (integer_zerop (pfn))
05802 {
05803 pfn = build_c_cast (type, integer_zero_node);
05804 return build_ptrmemfunc1 (to_type,
05805 integer_zero_node,
05806 pfn);
05807 }
05808
05809 if (type_unknown_p (pfn))
05810 return instantiate_type (type, pfn, tf_error | tf_warning);
05811
05812 fn = TREE_OPERAND (pfn, 0);
05813 my_friendly_assert (TREE_CODE (fn) == FUNCTION_DECL, 0);
05814 return make_ptrmem_cst (to_type, fn);
05815 }
05816
05817
05818
05819
05820
05821
05822
05823
05824 void
05825 expand_ptrmemfunc_cst (cst, delta, pfn)
05826 tree cst;
05827 tree *delta;
05828 tree *pfn;
05829 {
05830 tree type = TREE_TYPE (cst);
05831 tree fn = PTRMEM_CST_MEMBER (cst);
05832 tree ptr_class, fn_class;
05833
05834 my_friendly_assert (TREE_CODE (fn) == FUNCTION_DECL, 0);
05835
05836
05837 fn_class = DECL_CONTEXT (fn);
05838
05839
05840 ptr_class = TYPE_PTRMEMFUNC_OBJECT_TYPE (type);
05841
05842
05843 *delta = get_delta_difference (fn_class, ptr_class, 0);
05844
05845 if (!DECL_VIRTUAL_P (fn))
05846 *pfn = convert (TYPE_PTRMEMFUNC_FN_TYPE (type), build_addr_func (fn));
05847 else
05848 {
05849
05850
05851
05852 tree orig_class = DECL_CONTEXT (fn);
05853 tree binfo = binfo_or_else (orig_class, fn_class);
05854 *delta = fold (build (PLUS_EXPR, TREE_TYPE (*delta),
05855 *delta, BINFO_OFFSET (binfo)));
05856
05857
05858
05859
05860 *pfn = DECL_VINDEX (fn);
05861 *pfn = fold (build (MULT_EXPR, integer_type_node, *pfn,
05862 TYPE_SIZE_UNIT (vtable_entry_type)));
05863
05864 switch (TARGET_PTRMEMFUNC_VBIT_LOCATION)
05865 {
05866 case ptrmemfunc_vbit_in_pfn:
05867 *pfn = fold (build (PLUS_EXPR, integer_type_node, *pfn,
05868 integer_one_node));
05869 break;
05870
05871 case ptrmemfunc_vbit_in_delta:
05872 *delta = fold (build (LSHIFT_EXPR, TREE_TYPE (*delta),
05873 *delta, integer_one_node));
05874 *delta = fold (build (PLUS_EXPR, TREE_TYPE (*delta),
05875 *delta, integer_one_node));
05876 break;
05877
05878 default:
05879 abort ();
05880 }
05881
05882 *pfn = fold (build1 (NOP_EXPR, TYPE_PTRMEMFUNC_FN_TYPE (type),
05883 *pfn));
05884 }
05885 }
05886
05887
05888
05889
05890 tree
05891 pfn_from_ptrmemfunc (t)
05892 tree t;
05893 {
05894 if (TREE_CODE (t) == PTRMEM_CST)
05895 {
05896 tree delta;
05897 tree pfn;
05898
05899 expand_ptrmemfunc_cst (t, &delta, &pfn);
05900 if (pfn)
05901 return pfn;
05902 }
05903
05904 return build_ptrmemfunc_access_expr (t, pfn_identifier);
05905 }
05906
05907
05908
05909
05910
05911 tree
05912 dubious_conversion_warnings (type, expr, errtype, fndecl, parmnum)
05913 tree type;
05914 tree expr;
05915 const char *errtype;
05916 tree fndecl;
05917 int parmnum;
05918 {
05919 if (TREE_CODE (type) == REFERENCE_TYPE)
05920 type = TREE_TYPE (type);
05921
05922
05923 if (ARITHMETIC_TYPE_P (type) && expr == null_node)
05924 {
05925 if (fndecl)
05926 warning ("passing NULL used for non-pointer %s %P of `%D'",
05927 errtype, parmnum, fndecl);
05928 else
05929 warning ("%s to non-pointer type `%T' from NULL", errtype, type);
05930 }
05931
05932
05933 if (TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE
05934 && TREE_CODE (type) == INTEGER_TYPE)
05935 {
05936 if (fndecl)
05937 warning ("passing `%T' for %s %P of `%D'",
05938 TREE_TYPE (expr), errtype, parmnum, fndecl);
05939 else
05940 warning ("%s to `%T' from `%T'", errtype, type, TREE_TYPE (expr));
05941 }
05942
05943
05944 else if (TREE_UNSIGNED (type) && TREE_CODE (type) != BOOLEAN_TYPE)
05945 {
05946 if (TREE_CODE (expr) == INTEGER_CST
05947 && TREE_NEGATED_INT (expr))
05948 {
05949 if (fndecl)
05950 warning ("passing negative value `%E' for %s %P of `%D'",
05951 expr, errtype, parmnum, fndecl);
05952 else
05953 warning ("%s of negative value `%E' to `%T'",
05954 errtype, expr, type);
05955 }
05956
05957 overflow_warning (expr);
05958
05959 if (TREE_CONSTANT (expr))
05960 expr = fold (expr);
05961 }
05962 return expr;
05963 }
05964
05965
05966
05967
05968
05969
05970
05971 static tree
05972 convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
05973 tree type, rhs;
05974 const char *errtype;
05975 tree fndecl;
05976 int parmnum;
05977 {
05978 register enum tree_code codel = TREE_CODE (type);
05979 register tree rhstype;
05980 register enum tree_code coder;
05981
05982 if (codel == OFFSET_TYPE)
05983 abort ();
05984
05985 if (TREE_CODE (rhs) == OFFSET_REF)
05986 rhs = resolve_offset_ref (rhs);
05987
05988
05989 if (TREE_CODE (rhs) == NON_LVALUE_EXPR)
05990 rhs = TREE_OPERAND (rhs, 0);
05991
05992 rhstype = TREE_TYPE (rhs);
05993 coder = TREE_CODE (rhstype);
05994
05995 if (rhs == error_mark_node || rhstype == error_mark_node)
05996 return error_mark_node;
05997 if (TREE_CODE (rhs) == TREE_LIST && TREE_VALUE (rhs) == error_mark_node)
05998 return error_mark_node;
05999
06000 rhs = dubious_conversion_warnings (type, rhs, errtype, fndecl, parmnum);
06001
06002
06003 if (coder == VOID_TYPE)
06004 {
06005 error ("void value not ignored as it ought to be");
06006 return error_mark_node;
06007 }
06008
06009
06010 if (TREE_CODE (rhs) == CONST_DECL)
06011 rhs = DECL_INITIAL (rhs);
06012
06013
06014
06015
06016
06017
06018
06019
06020
06021
06022
06023
06024
06025
06026
06027
06028
06029
06030
06031 if (!can_convert_arg_bad (type, rhstype, rhs))
06032 {
06033
06034
06035
06036 if (!warn_pmf2ptr
06037 && TYPE_PTR_P (type)
06038 && TYPE_PTRMEMFUNC_P (rhstype))
06039 rhs = cp_convert (strip_top_quals (type), rhs);
06040 else
06041 {
06042
06043
06044
06045 if (rhstype == unknown_type_node)
06046 instantiate_type (type, rhs, tf_error | tf_warning);
06047 else if (fndecl)
06048 error ("cannot convert `%T' to `%T' for argument `%P' to `%D'",
06049 rhstype, type, parmnum, fndecl);
06050 else
06051 error ("cannot convert `%T' to `%T' in %s", rhstype, type,
06052 errtype);
06053 return error_mark_node;
06054 }
06055 }
06056 return perform_implicit_conversion (strip_top_quals (type), rhs);
06057 }
06058
06059
06060
06061
06062
06063
06064
06065
06066
06067
06068
06069
06070
06071
06072
06073
06074
06075 tree
06076 convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum)
06077 tree exp, type, rhs;
06078 int flags;
06079 const char *errtype;
06080 tree fndecl;
06081 int parmnum;
06082 {
06083 register enum tree_code codel = TREE_CODE (type);
06084 register tree rhstype;
06085 register enum tree_code coder;
06086
06087
06088
06089 if (TREE_CODE (rhs) == NOP_EXPR
06090 && TREE_TYPE (rhs) == TREE_TYPE (TREE_OPERAND (rhs, 0))
06091 && codel != REFERENCE_TYPE)
06092 rhs = TREE_OPERAND (rhs, 0);
06093
06094 if (rhs == error_mark_node
06095 || (TREE_CODE (rhs) == TREE_LIST && TREE_VALUE (rhs) == error_mark_node))
06096 return error_mark_node;
06097
06098 if (TREE_CODE (rhs) == OFFSET_REF)
06099 {
06100 rhs = resolve_offset_ref (rhs);
06101 if (rhs == error_mark_node)
06102 return error_mark_node;
06103 }
06104
06105 if (TREE_CODE (TREE_TYPE (rhs)) == REFERENCE_TYPE)
06106 rhs = convert_from_reference (rhs);
06107
06108 if ((TREE_CODE (TREE_TYPE (rhs)) == ARRAY_TYPE
06109 && TREE_CODE (type) != ARRAY_TYPE
06110 && (TREE_CODE (type) != REFERENCE_TYPE
06111 || TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE))
06112 || (TREE_CODE (TREE_TYPE (rhs)) == FUNCTION_TYPE
06113 && (TREE_CODE (type) != REFERENCE_TYPE
06114 || TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE))
06115 || TREE_CODE (TREE_TYPE (rhs)) == METHOD_TYPE)
06116 rhs = default_conversion (rhs);
06117
06118 rhstype = TREE_TYPE (rhs);
06119 coder = TREE_CODE (rhstype);
06120
06121 if (coder == ERROR_MARK)
06122 return error_mark_node;
06123
06124
06125
06126
06127 if (codel == REFERENCE_TYPE)
06128 {
06129
06130 int savew = 0, savee = 0;
06131
06132 if (fndecl)
06133 savew = warningcount, savee = errorcount;
06134 rhs = initialize_reference (type, rhs, NULL_TREE,
06135 NULL);
06136 if (fndecl)
06137 {
06138 if (warningcount > savew)
06139 cp_warning_at ("in passing argument %P of `%+D'", parmnum, fndecl);
06140 else if (errorcount > savee)
06141 cp_error_at ("in passing argument %P of `%+D'", parmnum, fndecl);
06142 }
06143 return rhs;
06144 }
06145
06146 if (exp != 0)
06147 exp = require_complete_type (exp);
06148 if (exp == error_mark_node)
06149 return error_mark_node;
06150
06151 if (TREE_CODE (rhstype) == REFERENCE_TYPE)
06152 rhstype = TREE_TYPE (rhstype);
06153
06154 type = complete_type (type);
06155
06156 if (IS_AGGR_TYPE (type))
06157 return ocp_convert (type, rhs, CONV_IMPLICIT|CONV_FORCE_TEMP, flags);
06158
06159 return convert_for_assignment (type, rhs, errtype, fndecl, parmnum);
06160 }
06161
06162
06163
06164
06165
06166
06167
06168
06169
06170
06171 void
06172 c_expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
06173 tree string, outputs, inputs, clobbers;
06174 int vol;
06175 const char *filename;
06176 int line;
06177 {
06178 int noutputs = list_length (outputs);
06179 register int i;
06180
06181 register tree *o = (tree *) alloca (noutputs * sizeof (tree));
06182 register tree tail;
06183
06184
06185 for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
06186 o[i] = TREE_VALUE (tail);
06187
06188
06189
06190
06191 expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line);
06192
06193
06194 for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
06195 {
06196 if (o[i] != TREE_VALUE (tail))
06197 {
06198 expand_expr (build_modify_expr (o[i], NOP_EXPR, TREE_VALUE (tail)),
06199 const0_rtx, VOIDmode, EXPAND_NORMAL);
06200 free_temp_slots ();
06201
06202
06203
06204 TREE_VALUE (tail) = o[i];
06205 }
06206
06207
06208 else
06209 {
06210 tree type = TREE_TYPE (o[i]);
06211 if (type != error_mark_node
06212 && (CP_TYPE_CONST_P (type)
06213 || (IS_AGGR_TYPE_CODE (TREE_CODE (type))
06214 && C_TYPE_FIELDS_READONLY (type))))
06215 readonly_error (o[i], "modification by `asm'", 1);
06216 }
06217 }
06218
06219
06220 emit_queue ();
06221 }
06222
06223
06224
06225
06226 static void
06227 maybe_warn_about_returning_address_of_local (retval)
06228 tree retval;
06229 {
06230 tree valtype = TREE_TYPE (DECL_RESULT (current_function_decl));
06231 tree whats_returned = retval;
06232
06233 for (;;)
06234 {
06235 if (TREE_CODE (whats_returned) == COMPOUND_EXPR)
06236 whats_returned = TREE_OPERAND (whats_returned, 1);
06237 else if (TREE_CODE (whats_returned) == CONVERT_EXPR
06238 || TREE_CODE (whats_returned) == NON_LVALUE_EXPR
06239 || TREE_CODE (whats_returned) == NOP_EXPR)
06240 whats_returned = TREE_OPERAND (whats_returned, 0);
06241 else
06242 break;
06243 }
06244
06245 if (TREE_CODE (whats_returned) != ADDR_EXPR)
06246 return;
06247 whats_returned = TREE_OPERAND (whats_returned, 0);
06248
06249 if (TREE_CODE (valtype) == REFERENCE_TYPE)
06250 {
06251 if (TREE_CODE (whats_returned) == AGGR_INIT_EXPR
06252 || TREE_CODE (whats_returned) == TARGET_EXPR)
06253 {
06254
06255 whats_returned = TREE_OPERAND (whats_returned, 0);
06256 warning ("returning reference to temporary");
06257 return;
06258 }
06259 if (TREE_CODE (whats_returned) == VAR_DECL
06260 && DECL_NAME (whats_returned)
06261 && TEMP_NAME_P (DECL_NAME (whats_returned)))
06262 {
06263 warning ("reference to non-lvalue returned");
06264 return;
06265 }
06266 }
06267
06268 if (TREE_CODE (whats_returned) == VAR_DECL
06269 && DECL_NAME (whats_returned)
06270 && DECL_FUNCTION_SCOPE_P (whats_returned)
06271 && !(TREE_STATIC (whats_returned)
06272 || TREE_PUBLIC (whats_returned)))
06273 {
06274 if (TREE_CODE (valtype) == REFERENCE_TYPE)
06275 cp_warning_at ("reference to local variable `%D' returned",
06276 whats_returned);
06277 else
06278 cp_warning_at ("address of local variable `%D' returned",
06279 whats_returned);
06280 return;
06281 }
06282 }
06283
06284
06285
06286
06287
06288
06289 tree
06290 check_return_expr (retval)
06291 tree retval;
06292 {
06293 tree result;
06294
06295
06296 tree valtype;
06297 int fn_returns_value_p;
06298
06299
06300
06301
06302 if (TREE_THIS_VOLATILE (current_function_decl))
06303 warning ("function declared `noreturn' has a `return' statement");
06304
06305
06306 if (DECL_DESTRUCTOR_P (current_function_decl))
06307 {
06308 if (retval)
06309 error ("returning a value from a destructor");
06310 return NULL_TREE;
06311 }
06312 else if (DECL_CONSTRUCTOR_P (current_function_decl))
06313 {
06314 if (in_function_try_handler)
06315
06316
06317 error ("cannot return from a handler of a function-try-block of a constructor");
06318 else if (retval)
06319
06320 error ("returning a value from a constructor");
06321 return NULL_TREE;
06322 }
06323
06324
06325
06326 result = DECL_RESULT (current_function_decl);
06327 valtype = TREE_TYPE (result);
06328 my_friendly_assert (valtype != NULL_TREE, 19990924);
06329 fn_returns_value_p = !VOID_TYPE_P (valtype);
06330 if (!retval && DECL_NAME (result) && fn_returns_value_p)
06331 retval = result;
06332
06333
06334
06335 if (!retval && fn_returns_value_p)
06336 {
06337 pedwarn ("return-statement with no value, in function declared with a non-void return type");
06338
06339
06340
06341 current_function_returns_null = 0;
06342 }
06343
06344
06345 else if (retval && !fn_returns_value_p)
06346 {
06347 if (VOID_TYPE_P (TREE_TYPE (retval)))
06348
06349
06350
06351 finish_expr_stmt (retval);
06352 else
06353 pedwarn ("return-statement with a value, in function declared with a void return type");
06354
06355 current_function_returns_null = 1;
06356
06357
06358 return NULL_TREE;
06359 }
06360 else if (!retval)
06361
06362
06363 current_function_returns_null = 1;
06364 else
06365
06366 current_function_returns_value = 1;
06367
06368
06369 if ((DECL_OVERLOADED_OPERATOR_P (current_function_decl) == NEW_EXPR
06370 || DECL_OVERLOADED_OPERATOR_P (current_function_decl) == VEC_NEW_EXPR)
06371 && !TYPE_NOTHROW_P (TREE_TYPE (current_function_decl))
06372 && ! flag_check_new
06373 && null_ptr_cst_p (retval))
06374 warning ("`operator new' must not return NULL unless it is declared `throw()' (or -fcheck-new is in effect)");
06375
06376
06377 if (warn_ecpp
06378 && DECL_NAME (current_function_decl) == ansi_assopname(NOP_EXPR)
06379 && retval != current_class_ref)
06380 warning ("`operator=' should return a reference to `*this'");
06381
06382
06383
06384
06385
06386
06387
06388
06389
06390
06391
06392
06393
06394
06395
06396
06397
06398
06399
06400
06401
06402 if (fn_returns_value_p && flag_elide_constructors)
06403 {
06404 if (retval != NULL_TREE
06405 && (current_function_return_value == NULL_TREE
06406 || current_function_return_value == retval)
06407 && TREE_CODE (retval) == VAR_DECL
06408 && DECL_CONTEXT (retval) == current_function_decl
06409 && ! TREE_STATIC (retval)
06410 && (DECL_ALIGN (retval)
06411 >= DECL_ALIGN (DECL_RESULT (current_function_decl)))
06412 && same_type_p ((TYPE_MAIN_VARIANT
06413 (TREE_TYPE (retval))),
06414 (TYPE_MAIN_VARIANT
06415 (TREE_TYPE (TREE_TYPE (current_function_decl))))))
06416 {
06417 current_function_return_value = retval;
06418 #ifdef KEY
06419
06420 DECL_NAMED_RETURN_OBJECT(current_function_decl) = retval;
06421 #endif
06422 }
06423 else
06424 {
06425 current_function_return_value = error_mark_node;
06426 #ifdef KEY
06427
06428
06429 DECL_NAMED_RETURN_OBJECT(current_function_decl) = NULL_TREE;
06430 #endif
06431 }
06432 }
06433
06434
06435
06436 if (!retval || retval == error_mark_node)
06437 return retval;
06438
06439
06440 if (retval == result || DECL_CONSTRUCTOR_P (current_function_decl))
06441
06442 ;
06443 else
06444 {
06445
06446 tree functype = TREE_TYPE (TREE_TYPE (current_function_decl));
06447
06448
06449
06450
06451 retval = convert_for_initialization
06452 (NULL_TREE, functype, retval, LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING,
06453 "return", NULL_TREE, 0);
06454 retval = convert (valtype, retval);
06455
06456
06457 if (retval == error_mark_node)
06458 return retval;
06459
06460 else if (! current_function_returns_struct
06461 && TREE_CODE (retval) == TARGET_EXPR
06462 && TREE_CODE (TREE_OPERAND (retval, 1)) == AGGR_INIT_EXPR)
06463 retval = build (COMPOUND_EXPR, TREE_TYPE (retval), retval,
06464 TREE_OPERAND (retval, 0));
06465 else
06466 maybe_warn_about_returning_address_of_local (retval);
06467 }
06468
06469
06470 if (retval && retval != result)
06471 retval = build (INIT_EXPR, TREE_TYPE (result), result, retval);
06472
06473 return retval;
06474 }
06475
06476
06477
06478
06479
06480
06481
06482
06483
06484
06485 static int
06486 comp_ptr_ttypes_real (to, from, constp)
06487 tree to, from;
06488 int constp;
06489 {
06490 int to_more_cv_qualified = 0;
06491
06492 for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from))
06493 {
06494 if (TREE_CODE (to) != TREE_CODE (from))
06495 return 0;
06496
06497 if (TREE_CODE (from) == OFFSET_TYPE
06498 && same_type_p (TYPE_OFFSET_BASETYPE (from),
06499 TYPE_OFFSET_BASETYPE (to)))
06500 continue;
06501
06502
06503
06504 if (TREE_CODE (to) != FUNCTION_TYPE && TREE_CODE (to) != METHOD_TYPE)
06505 {
06506 if (!at_least_as_qualified_p (to, from))
06507 return 0;
06508
06509 if (!at_least_as_qualified_p (from, to))
06510 {
06511 if (constp == 0)
06512 return 0;
06513 else
06514 ++to_more_cv_qualified;
06515 }
06516
06517 if (constp > 0)
06518 constp &= TYPE_READONLY (to);
06519 }
06520
06521 if (TREE_CODE (to) != POINTER_TYPE)
06522 return
06523 same_type_ignoring_top_level_qualifiers_p (to, from)
06524 && (constp >= 0 || to_more_cv_qualified);
06525 }
06526 }
06527
06528
06529
06530
06531
06532 int
06533 comp_ptr_ttypes (to, from)
06534 tree to, from;
06535 {
06536 return comp_ptr_ttypes_real (to, from, 1);
06537 }
06538
06539
06540
06541
06542 int
06543 ptr_reasonably_similar (to, from)
06544 tree to, from;
06545 {
06546 for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from))
06547 {
06548
06549 if (TREE_CODE (to) == VOID_TYPE
06550 || TREE_CODE (from) == VOID_TYPE)
06551 return 1;
06552
06553 if (TREE_CODE (to) != TREE_CODE (from))
06554 return 0;
06555
06556 if (TREE_CODE (from) == OFFSET_TYPE
06557 && comptypes (TYPE_OFFSET_BASETYPE (to),
06558 TYPE_OFFSET_BASETYPE (from),
06559 COMPARE_BASE | COMPARE_RELAXED))
06560 continue;
06561
06562 if (TREE_CODE (to) == INTEGER_TYPE
06563 && TYPE_PRECISION (to) == TYPE_PRECISION (from))
06564 return 1;
06565
06566 if (TREE_CODE (to) == FUNCTION_TYPE)
06567 return 1;
06568
06569 if (TREE_CODE (to) != POINTER_TYPE)
06570 return comptypes
06571 (TYPE_MAIN_VARIANT (to), TYPE_MAIN_VARIANT (from),
06572 COMPARE_BASE | COMPARE_RELAXED);
06573 }
06574 }
06575
06576
06577
06578 static int
06579 comp_ptr_ttypes_const (to, from)
06580 tree to, from;
06581 {
06582 for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from))
06583 {
06584 if (TREE_CODE (to) != TREE_CODE (from))
06585 return 0;
06586
06587 if (TREE_CODE (from) == OFFSET_TYPE
06588 && same_type_p (TYPE_OFFSET_BASETYPE (from),
06589 TYPE_OFFSET_BASETYPE (to)))
06590 continue;
06591
06592 if (TREE_CODE (to) != POINTER_TYPE)
06593 return same_type_ignoring_top_level_qualifiers_p (to, from);
06594 }
06595 }
06596
06597
06598
06599 static int
06600 comp_ptr_ttypes_reinterpret (to, from)
06601 tree to, from;
06602 {
06603 int constp = 1;
06604
06605 for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from))
06606 {
06607 if (TREE_CODE (from) == OFFSET_TYPE)
06608 from = TREE_TYPE (from);
06609 if (TREE_CODE (to) == OFFSET_TYPE)
06610 to = TREE_TYPE (to);
06611
06612
06613
06614 if (TREE_CODE (from) != FUNCTION_TYPE && TREE_CODE (from) != METHOD_TYPE
06615 && TREE_CODE (to) != FUNCTION_TYPE && TREE_CODE (to) != METHOD_TYPE)
06616 {
06617 if (!at_least_as_qualified_p (to, from))
06618 return 0;
06619
06620 if (! constp
06621 && !at_least_as_qualified_p (from, to))
06622 return 0;
06623 constp &= TYPE_READONLY (to);
06624 }
06625
06626 if (TREE_CODE (from) != POINTER_TYPE
06627 || TREE_CODE (to) != POINTER_TYPE)
06628 return 1;
06629 }
06630 }
06631
06632
06633
06634
06635 int
06636 cp_type_quals (type)
06637 tree type;
06638 {
06639 type = strip_array_types (type);
06640 if (type == error_mark_node)
06641 return TYPE_UNQUALIFIED;
06642 return TYPE_QUALS (type);
06643 }
06644
06645
06646
06647 int
06648 cp_has_mutable_p (type)
06649 tree type;
06650 {
06651 type = strip_array_types (type);
06652
06653 return CLASS_TYPE_P (type) && CLASSTYPE_HAS_MUTABLE (type);
06654 }
06655
06656
06657
06658
06659
06660 static void
06661 casts_away_constness_r (t1, t2)
06662 tree *t1;
06663 tree *t2;
06664 {
06665 int quals1;
06666 int quals2;
06667
06668
06669
06670
06671
06672
06673
06674 if (TYPE_PTRMEM_P (*t1))
06675 *t1 = build_pointer_type (TREE_TYPE (TREE_TYPE (*t1)));
06676 if (TYPE_PTRMEM_P (*t2))
06677 *t2 = build_pointer_type (TREE_TYPE (TREE_TYPE (*t2)));
06678
06679
06680
06681
06682
06683
06684
06685
06686
06687
06688
06689
06690
06691
06692
06693
06694
06695
06696
06697 if (TREE_CODE (*t1) != POINTER_TYPE
06698 || TREE_CODE (*t2) != POINTER_TYPE)
06699 {
06700 *t1 = cp_build_qualified_type (void_type_node,
06701 cp_type_quals (*t1));
06702 *t2 = cp_build_qualified_type (void_type_node,
06703 cp_type_quals (*t2));
06704 return;
06705 }
06706
06707 quals1 = cp_type_quals (*t1);
06708 quals2 = cp_type_quals (*t2);
06709 *t1 = TREE_TYPE (*t1);
06710 *t2 = TREE_TYPE (*t2);
06711 casts_away_constness_r (t1, t2);
06712 *t1 = build_pointer_type (*t1);
06713 *t2 = build_pointer_type (*t2);
06714 *t1 = cp_build_qualified_type (*t1, quals1);
06715 *t2 = cp_build_qualified_type (*t2, quals2);
06716 }
06717
06718
06719
06720
06721 static int
06722 casts_away_constness (t1, t2)
06723 tree t1;
06724 tree t2;
06725 {
06726 if (TREE_CODE (t2) == REFERENCE_TYPE)
06727 {
06728
06729
06730
06731
06732
06733
06734 t1 = (TREE_CODE (t1) == REFERENCE_TYPE
06735 ? TREE_TYPE (t1) : t1);
06736 return casts_away_constness (build_pointer_type (t1),
06737 build_pointer_type (TREE_TYPE (t2)));
06738 }
06739
06740 if (TYPE_PTRMEM_P (t1) && TYPE_PTRMEM_P (t2))
06741
06742
06743
06744
06745
06746
06747
06748 return casts_away_constness
06749 (build_pointer_type (TREE_TYPE (TREE_TYPE (t1))),
06750 build_pointer_type (TREE_TYPE (TREE_TYPE (t2))));
06751
06752
06753
06754 if (TREE_CODE (t1) != POINTER_TYPE
06755 || TREE_CODE (t2) != POINTER_TYPE)
06756 return 0;
06757
06758
06759 t1 = TYPE_MAIN_VARIANT (t1);
06760 t2 = TYPE_MAIN_VARIANT (t2);
06761 casts_away_constness_r (&t1, &t2);
06762 if (!can_convert (t2, t1))
06763 return 1;
06764
06765 return 0;
06766 }
06767
06768
06769
06770
06771
06772
06773 static tree
06774 strip_all_pointer_quals (type)
06775 tree type;
06776 {
06777 if (TREE_CODE (type) == POINTER_TYPE)
06778 return build_pointer_type (strip_all_pointer_quals (TREE_TYPE (type)));
06779 else if (TREE_CODE (type) == OFFSET_TYPE)
06780 return build_offset_type (TYPE_OFFSET_BASETYPE (type),
06781 strip_all_pointer_quals (TREE_TYPE (type)));
06782 else
06783 return TYPE_MAIN_VARIANT (type);
06784 }