LCOV - code coverage report
Current view: top level - gcc/cp - typeck.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 92.1 % 5589 5150
Test Date: 2026-06-20 15:32:29 Functions: 97.8 % 178 174
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Build expressions with type checking for C++ compiler.
       2              :    Copyright (C) 1987-2026 Free Software Foundation, Inc.
       3              :    Hacked by Michael Tiemann (tiemann@cygnus.com)
       4              : 
       5              : This file is part of GCC.
       6              : 
       7              : GCC is free software; you can redistribute it and/or modify
       8              : it under the terms of the GNU General Public License as published by
       9              : the Free Software Foundation; either version 3, or (at your option)
      10              : any later version.
      11              : 
      12              : GCC is distributed in the hope that it will be useful,
      13              : but WITHOUT ANY WARRANTY; without even the implied warranty of
      14              : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15              : GNU General Public License for more details.
      16              : 
      17              : You should have received a copy of the GNU General Public License
      18              : along with GCC; see the file COPYING3.  If not see
      19              : <http://www.gnu.org/licenses/>.  */
      20              : 
      21              : 
      22              : /* This file is part of the C++ front end.
      23              :    It contains routines to build C++ expressions given their operands,
      24              :    including computing the types of the result, C and C++ specific error
      25              :    checks, and some optimization.  */
      26              : 
      27              : #include "config.h"
      28              : #include "system.h"
      29              : #include "coretypes.h"
      30              : #include "target.h"
      31              : #include "cp-tree.h"
      32              : #include "stor-layout.h"
      33              : #include "varasm.h"
      34              : #include "intl.h"
      35              : #include "convert.h"
      36              : #include "c-family/c-objc.h"
      37              : #include "c-family/c-ubsan.h"
      38              : #include "c-family/c-type-mismatch.h"
      39              : #include "stringpool.h"
      40              : #include "attribs.h"
      41              : #include "asan.h"
      42              : #include "gimplify.h"
      43              : 
      44              : static tree cp_build_addr_expr_strict (tree, tsubst_flags_t);
      45              : static tree cp_build_function_call (tree, tree, tsubst_flags_t);
      46              : static tree pfn_from_ptrmemfunc (tree);
      47              : static tree delta_from_ptrmemfunc (tree);
      48              : static tree convert_for_assignment (tree, tree, impl_conv_rhs, tree, int,
      49              :                                     tsubst_flags_t, int);
      50              : static tree cp_pointer_int_sum (location_t, enum tree_code, tree, tree,
      51              :                                 tsubst_flags_t);
      52              : static tree rationalize_conditional_expr (enum tree_code, tree,
      53              :                                           tsubst_flags_t);
      54              : static bool comp_ptr_ttypes_real (tree, tree, int);
      55              : static bool comp_except_types (tree, tree, bool);
      56              : static bool comp_array_types (const_tree, const_tree, compare_bounds_t, bool);
      57              : static tree pointer_diff (location_t, tree, tree, tree, tsubst_flags_t, tree *);
      58              : static tree get_delta_difference (tree, tree, bool, bool, tsubst_flags_t);
      59              : static void casts_away_constness_r (tree *, tree *, tsubst_flags_t);
      60              : static bool casts_away_constness (tree, tree, tsubst_flags_t);
      61              : static bool maybe_warn_about_returning_address_of_local (tree, location_t = UNKNOWN_LOCATION);
      62              : static void error_args_num (location_t, tree, bool);
      63              : static int convert_arguments (tree, vec<tree, va_gc> **, tree, int,
      64              :                               tsubst_flags_t);
      65              : static bool is_std_move_p (tree);
      66              : static bool is_std_forward_p (tree);
      67              : 
      68              : /* Do `exp = require_complete_type (exp);' to make sure exp
      69              :    does not have an incomplete type.  (That includes void types.)
      70              :    Returns error_mark_node if the VALUE does not have
      71              :    complete type when this function returns.  */
      72              : 
      73              : tree
      74    139928301 : require_complete_type (tree value,
      75              :                        tsubst_flags_t complain /* = tf_warning_or_error */)
      76              : {
      77    139928301 :   tree type;
      78              : 
      79    139928301 :   if (processing_template_decl || value == error_mark_node)
      80              :     return value;
      81              : 
      82    129746327 :   if (TREE_CODE (value) == OVERLOAD)
      83            0 :     type = unknown_type_node;
      84              :   else
      85    129746327 :     type = TREE_TYPE (value);
      86              : 
      87    129746327 :   if (type == error_mark_node)
      88              :     return error_mark_node;
      89              : 
      90              :   /* First, detect a valid value with a complete type.  */
      91    129746315 :   if (COMPLETE_TYPE_P (type))
      92              :     return value;
      93              : 
      94       144858 :   if (complete_type_or_maybe_complain (type, value, complain))
      95              :     return value;
      96              :   else
      97          145 :     return error_mark_node;
      98              : }
      99              : 
     100              : /* Try to complete TYPE, if it is incomplete.  For example, if TYPE is
     101              :    a template instantiation, do the instantiation.  Returns TYPE,
     102              :    whether or not it could be completed, unless something goes
     103              :    horribly wrong, in which case the error_mark_node is returned.  */
     104              : 
     105              : tree
     106  15003263487 : complete_type (tree type)
     107              : {
     108  15003263487 :   if (type == NULL_TREE)
     109              :     /* Rather than crash, we return something sure to cause an error
     110              :        at some point.  */
     111            0 :     return error_mark_node;
     112              : 
     113  15003263487 :   if (type == error_mark_node || COMPLETE_TYPE_P (type))
     114              :     ;
     115   4911105137 :   else if (TREE_CODE (type) == ARRAY_TYPE)
     116              :     {
     117       773014 :       tree t = complete_type (TREE_TYPE (type));
     118       773014 :       unsigned int needs_constructing, has_nontrivial_dtor;
     119       773014 :       if (COMPLETE_TYPE_P (t) && !dependent_type_p (type))
     120       754888 :         layout_type (type);
     121       773014 :       needs_constructing
     122       773014 :         = TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (t));
     123       773014 :       has_nontrivial_dtor
     124       773014 :         = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TYPE_MAIN_VARIANT (t));
     125      2548695 :       for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
     126              :         {
     127      1775681 :           TYPE_NEEDS_CONSTRUCTING (t) = needs_constructing;
     128      1775681 :           TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = has_nontrivial_dtor;
     129              :         }
     130              :     }
     131   4910332123 :   else if (CLASS_TYPE_P (type))
     132              :     {
     133   4819496587 :       if (modules_p ())
     134              :         /* TYPE could be a class member we've not loaded the definition of.  */
     135     19243538 :         lazy_load_pendings (TYPE_NAME (TYPE_MAIN_VARIANT (type)));
     136              : 
     137   4819496587 :       if (CLASSTYPE_TEMPLATE_INSTANTIATION (type))
     138    918640635 :         instantiate_class_template (TYPE_MAIN_VARIANT (type));
     139              :     }
     140              : 
     141              :   return type;
     142              : }
     143              : 
     144              : /* Like complete_type, but issue an error if the TYPE cannot be completed.
     145              :    VALUE is used for informative diagnostics.
     146              :    Returns NULL_TREE if the type cannot be made complete.  */
     147              : 
     148              : tree
     149   1611729473 : complete_type_or_maybe_complain (tree type, tree value, tsubst_flags_t complain)
     150              : {
     151   1611729473 :   type = complete_type (type);
     152   1611729470 :   if (type == error_mark_node)
     153              :     /* We already issued an error.  */
     154              :     return NULL_TREE;
     155   1611729263 :   else if (!COMPLETE_TYPE_P (type))
     156              :     {
     157         3847 :       if (complain & tf_error)
     158          476 :         cxx_incomplete_type_diagnostic (value, type, diagnostics::kind::error);
     159         3847 :       note_failed_type_completion (type, complain);
     160         3847 :       return NULL_TREE;
     161              :     }
     162              :   else
     163              :     return type;
     164              : }
     165              : 
     166              : tree
     167    163859426 : complete_type_or_else (tree type, tree value)
     168              : {
     169    163859426 :   return complete_type_or_maybe_complain (type, value, tf_warning_or_error);
     170              : }
     171              : 
     172              : 
     173              : /* Return the common type of two parameter lists.
     174              :    We assume that comptypes has already been done and returned 1;
     175              :    if that isn't so, this may crash.
     176              : 
     177              :    As an optimization, free the space we allocate if the parameter
     178              :    lists are already common.  */
     179              : 
     180              : static tree
     181      4126910 : commonparms (tree p1, tree p2)
     182              : {
     183      4126910 :   tree oldargs = p1, newargs, n;
     184      4126910 :   int i, len;
     185      4126910 :   int any_change = 0;
     186              : 
     187      4126910 :   len = list_length (p1);
     188      4126910 :   newargs = tree_last (p1);
     189              : 
     190      4126910 :   if (newargs == void_list_node)
     191              :     i = 1;
     192              :   else
     193              :     {
     194        39549 :       i = 0;
     195        39549 :       newargs = 0;
     196              :     }
     197              : 
     198     13652038 :   for (; i < len; i++)
     199      9525128 :     newargs = tree_cons (NULL_TREE, NULL_TREE, newargs);
     200              : 
     201              :   n = newargs;
     202              : 
     203     17739399 :   for (i = 0; p1;
     204     13612489 :        p1 = TREE_CHAIN (p1), p2 = TREE_CHAIN (p2), n = TREE_CHAIN (n), i++)
     205              :     {
     206     13612696 :       if (TREE_PURPOSE (p1) && !TREE_PURPOSE (p2))
     207              :         {
     208          174 :           TREE_PURPOSE (n) = TREE_PURPOSE (p1);
     209          174 :           any_change = 1;
     210              :         }
     211     13612315 :       else if (! TREE_PURPOSE (p1))
     212              :         {
     213     13612282 :           if (TREE_PURPOSE (p2))
     214              :             {
     215       414651 :               TREE_PURPOSE (n) = TREE_PURPOSE (p2);
     216       414651 :               any_change = 1;
     217              :             }
     218              :         }
     219              :       else
     220              :         {
     221           33 :           if (simple_cst_equal (TREE_PURPOSE (p1), TREE_PURPOSE (p2)) != 1)
     222           33 :             any_change = 1;
     223           33 :           TREE_PURPOSE (n) = TREE_PURPOSE (p2);
     224              :         }
     225     13612489 :       if (TREE_VALUE (p1) != TREE_VALUE (p2))
     226              :         {
     227      3817292 :           any_change = 1;
     228      3817292 :           TREE_VALUE (n) = merge_types (TREE_VALUE (p1), TREE_VALUE (p2));
     229              :         }
     230              :       else
     231      9795197 :         TREE_VALUE (n) = TREE_VALUE (p1);
     232              :     }
     233      4126910 :   if (! any_change)
     234      1384671 :     return oldargs;
     235              : 
     236              :   return newargs;
     237              : }
     238              : 
     239              : /* Given a type, perhaps copied for a typedef,
     240              :    find the "original" version of it.  */
     241              : static tree
     242     32301802 : original_type (tree t)
     243              : {
     244     32301802 :   int quals = cp_type_quals (t);
     245     32301802 :   while (t != error_mark_node
     246     33413297 :          && TYPE_NAME (t) != NULL_TREE)
     247              :     {
     248     11272303 :       tree x = TYPE_NAME (t);
     249     11272303 :       if (TREE_CODE (x) != TYPE_DECL)
     250              :         break;
     251     11272303 :       x = DECL_ORIGINAL_TYPE (x);
     252     11272303 :       if (x == NULL_TREE)
     253              :         break;
     254              :       t = x;
     255              :     }
     256     32301802 :   return cp_build_qualified_type (t, quals);
     257              : }
     258              : 
     259              : /* Merge the attributes of type OTHER_TYPE into the attributes of type TYPE
     260              :    and return a variant of TYPE with the merged attributes.  */
     261              : 
     262              : static tree
     263        59984 : merge_type_attributes_from (tree type, tree other_type)
     264              : {
     265        59984 :   tree attrs = targetm.merge_type_attributes (type, other_type);
     266        59984 :   attrs = restrict_type_identity_attributes_to (attrs, TYPE_ATTRIBUTES (type));
     267        59984 :   return cp_build_type_attribute_variant (type, attrs);
     268              : }
     269              : 
     270              : /* Compare floating point conversion ranks and subranks of T1 and T2
     271              :    types.  If T1 and T2 have unordered conversion ranks, return 3.
     272              :    If T1 has greater conversion rank than T2, return 2.
     273              :    If T2 has greater conversion rank than T1, return -2.
     274              :    If T1 has equal conversion rank as T2, return -1, 0 or 1 depending
     275              :    on if T1 has smaller, equal or greater conversion subrank than
     276              :    T2.  */
     277              : 
     278              : int
     279      5470659 : cp_compare_floating_point_conversion_ranks (tree t1, tree t2)
     280              : {
     281      5470659 :   tree mv1 = TYPE_MAIN_VARIANT (t1);
     282      5470659 :   tree mv2 = TYPE_MAIN_VARIANT (t2);
     283      5470659 :   int extended1 = 0;
     284      5470659 :   int extended2 = 0;
     285              : 
     286      5470659 :   if (mv1 == mv2)
     287              :     return 0;
     288              : 
     289     43753952 :   for (int i = 0; i < NUM_FLOATN_NX_TYPES; ++i)
     290              :     {
     291     38284708 :       if (mv1 == FLOATN_NX_TYPE_NODE (i))
     292      2470601 :         extended1 = i + 1;
     293     38284708 :       if (mv2 == FLOATN_NX_TYPE_NODE (i))
     294      2053902 :         extended2 = i + 1;
     295              :     }
     296      5469244 :   if (mv1 == bfloat16_type_node)
     297       569667 :     extended1 = true;
     298      5469244 :   if (mv2 == bfloat16_type_node)
     299       454372 :     extended2 = true;
     300      5469244 :   if (extended2 && !extended1)
     301              :     {
     302      2396838 :       int ret = cp_compare_floating_point_conversion_ranks (t2, t1);
     303      2396838 :       return ret == 3 ? 3 : -ret;
     304              :     }
     305              : 
     306      3072406 :   const struct real_format *fmt1 = REAL_MODE_FORMAT (TYPE_MODE (t1));
     307      3072406 :   const struct real_format *fmt2 = REAL_MODE_FORMAT (TYPE_MODE (t2));
     308              :   /* Currently, extended floating point types are only binary, and
     309              :      they never have a proper subset or superset of values with
     310              :      decimal floating point types except for the _Float16 vs. _Decimal128
     311              :      pair, so return 3 for unordered conversion ranks.  */
     312      3072406 :   gcc_assert (fmt1->b == 2);
     313      3072406 :   if (fmt2->b == 10)
     314              :     {
     315              :       /* _Float16 needs at most 21 decimal digits (e.g.
     316              :          0x1.a3cp-14f16 is exactly 0.000100076198577880859375DL),
     317              :          so it is not a proper subset of _Decimal64 but is subset
     318              :          of _Decimal128.  While std::bfloat16_t needs at most 96
     319              :          decimal digits, so even _Decimal128 doesn't cover it.
     320              :          _Float32 has at least one value which needs 112 decimal
     321              :          digits, _Float64 at least 767 decimal digits.  */
     322           33 :       if (fmt1->emin == -13
     323           15 :           && fmt1->emax == 16
     324           15 :           && fmt1->p == 11
     325           15 :           && fmt2->emin == -6142
     326           15 :           && fmt2->emax == 6145
     327           15 :           && fmt2->p == 34)
     328              :         return -2;
     329              :       return 3;
     330              :     }
     331      3072373 :   gcc_assert (fmt2->b == 2);
     332              :   /* For {ibm,mips}_extended_format formats, the type has variable
     333              :      precision up to ~2150 bits when the first double is around maximum
     334              :      representable double and second double is subnormal minimum.
     335              :      So, e.g. for __ibm128 vs. std::float128_t, they have unordered
     336              :      ranks.  */
     337     24578984 :   int p1 = (MODE_COMPOSITE_P (TYPE_MODE (t1))
     338      6144746 :             ? fmt1->emax - fmt1->emin + fmt1->p - 1 : fmt1->p);
     339     24578984 :   int p2 = (MODE_COMPOSITE_P (TYPE_MODE (t2))
     340      6144746 :             ? fmt2->emax - fmt2->emin + fmt2->p - 1 : fmt2->p);
     341              :   /* The rank of a floating point type T is greater than the rank of
     342              :      any floating-point type whose set of values is a proper subset
     343              :      of the set of values of T.  */
     344      3072373 :   if ((p1 > p2 && fmt1->emax >= fmt2->emax)
     345      2399789 :        || (p1 == p2 && fmt1->emax > fmt2->emax))
     346              :     return 2;
     347      2399789 :   if ((p1 < p2 && fmt1->emax <= fmt2->emax)
     348       825591 :        || (p1 == p2 && fmt1->emax < fmt2->emax))
     349              :     return -2;
     350       825591 :   if ((p1 > p2 && fmt1->emax < fmt2->emax)
     351       820791 :        || (p1 < p2 && fmt1->emax > fmt2->emax))
     352              :     return 3;
     353       815991 :   if (!extended1 && !extended2)
     354              :     {
     355              :       /* The rank of long double is greater than the rank of double, which
     356              :          is greater than the rank of float.  */
     357            0 :       if (t1 == long_double_type_node)
     358              :         return 2;
     359            0 :       else if (t2 == long_double_type_node)
     360              :         return -2;
     361            0 :       if (t1 == double_type_node)
     362              :         return 2;
     363            0 :       else if (t2 == double_type_node)
     364              :         return -2;
     365            0 :       if (t1 == float_type_node)
     366              :         return 2;
     367            0 :       else if (t2 == float_type_node)
     368              :         return -2;
     369              :       return 0;
     370              :     }
     371              :   /* Two extended floating-point types with the same set of values have equal
     372              :      ranks.  */
     373       815991 :   if (extended1 && extended2)
     374              :     {
     375            6 :       if ((extended1 <= NUM_FLOATN_TYPES) == (extended2 <= NUM_FLOATN_TYPES))
     376              :         {
     377              :           /* Prefer higher extendedN value.  */
     378            0 :           if (extended1 > extended2)
     379              :             return 1;
     380            0 :           else if (extended1 < extended2)
     381              :             return -1;
     382              :           else
     383              :             return 0;
     384              :         }
     385            6 :       else if (extended1 <= NUM_FLOATN_TYPES)
     386              :         /* Prefer _FloatN type over _FloatMx type.  */
     387              :         return 1;
     388            3 :       else if (extended2 <= NUM_FLOATN_TYPES)
     389              :         return -1;
     390              :       else
     391              :         return 0;
     392              :     }
     393              : 
     394              :   /* gcc_assert (extended1 && !extended2);  */
     395              :   tree *p;
     396              :   int cnt = 0;
     397      3263940 :   for (p = &float_type_node; p <= &long_double_type_node; ++p)
     398              :     {
     399      2447955 :       const struct real_format *fmt3 = REAL_MODE_FORMAT (TYPE_MODE (*p));
     400      2447955 :       gcc_assert (fmt3->b == 2);
     401     19583640 :       int p3 = (MODE_COMPOSITE_P (TYPE_MODE (*p))
     402      4895910 :                 ? fmt3->emax - fmt3->emin + fmt3->p - 1 : fmt3->p);
     403      2447955 :       if (p1 == p3 && fmt1->emax == fmt3->emax)
     404       716134 :         ++cnt;
     405              :     }
     406              :   /* An extended floating-point type with the same set of values
     407              :      as exactly one cv-unqualified standard floating-point type
     408              :      has a rank equal to the rank of that standard floating-point
     409              :      type.
     410              : 
     411              :      An extended floating-point type with the same set of values
     412              :      as more than one cv-unqualified standard floating-point type
     413              :      has a rank equal to the rank of double.
     414              : 
     415              :      Thus, if the latter is true and t2 is long double, t2
     416              :      has higher rank.  */
     417       815985 :   if (cnt > 1 && mv2 == long_double_type_node)
     418              :     return -2;
     419              :   /* And similarly if t2 is float, t2 has lower rank.  */
     420            0 :   if (cnt > 1 && mv2 == float_type_node)
     421              :     return 2;
     422              :   /* Otherwise, they have equal rank, but extended types
     423              :      (other than std::bfloat16_t) have higher subrank.
     424              :      std::bfloat16_t shouldn't have equal rank to any standard
     425              :      floating point type.  */
     426              :   return 1;
     427              : }
     428              : 
     429              : /* Return the common type for two arithmetic types T1 and T2 under the
     430              :    usual arithmetic conversions.  The default conversions have already
     431              :    been applied, and enumerated types converted to their compatible
     432              :    integer types.  */
     433              : 
     434              : static tree
     435    109245818 : cp_common_type (tree t1, tree t2)
     436              : {
     437    109245818 :   enum tree_code code1 = TREE_CODE (t1);
     438    109245818 :   enum tree_code code2 = TREE_CODE (t2);
     439    109245818 :   tree attributes;
     440    109245818 :   int i;
     441              : 
     442              : 
     443              :   /* In what follows, we slightly generalize the rules given in [expr] so
     444              :      as to deal with `long long' and `complex'.  First, merge the
     445              :      attributes.  */
     446    109245818 :   attributes = (*targetm.merge_type_attributes) (t1, t2);
     447              : 
     448    109245818 :   if (SCOPED_ENUM_P (t1) || SCOPED_ENUM_P (t2))
     449              :     {
     450      1990526 :       if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
     451      1990526 :         return build_type_attribute_variant (t1, attributes);
     452              :       else
     453              :         return NULL_TREE;
     454              :     }
     455              : 
     456              :   /* FIXME: Attributes.  */
     457    107255292 :   gcc_assert (ARITHMETIC_TYPE_P (t1)
     458              :               || VECTOR_TYPE_P (t1)
     459              :               || UNSCOPED_ENUM_P (t1));
     460    107255292 :   gcc_assert (ARITHMETIC_TYPE_P (t2)
     461              :               || VECTOR_TYPE_P (t2)
     462              :               || UNSCOPED_ENUM_P (t2));
     463              : 
     464              :   /* If one type is complex, form the common type of the non-complex
     465              :      components, then make that complex.  Use T1 or T2 if it is the
     466              :      required type.  */
     467    107255292 :   if (code1 == COMPLEX_TYPE || code2 == COMPLEX_TYPE)
     468              :     {
     469       216370 :       tree subtype1 = code1 == COMPLEX_TYPE ? TREE_TYPE (t1) : t1;
     470       216370 :       tree subtype2 = code2 == COMPLEX_TYPE ? TREE_TYPE (t2) : t2;
     471       216370 :       tree subtype
     472       216370 :         = type_after_usual_arithmetic_conversions (subtype1, subtype2);
     473              : 
     474       216370 :       if (subtype == error_mark_node)
     475              :         return subtype;
     476       216370 :       if (code1 == COMPLEX_TYPE && TREE_TYPE (t1) == subtype)
     477       182962 :         return build_type_attribute_variant (t1, attributes);
     478        33408 :       else if (code2 == COMPLEX_TYPE && TREE_TYPE (t2) == subtype)
     479        33348 :         return build_type_attribute_variant (t2, attributes);
     480              :       else
     481           60 :         return build_type_attribute_variant (build_complex_type (subtype),
     482           60 :                                              attributes);
     483              :     }
     484              : 
     485    107038922 :   if (code1 == VECTOR_TYPE)
     486              :     {
     487              :       /* When we get here we should have two vectors of the same size.
     488              :          Just prefer the unsigned one if present.  */
     489        59984 :       if (TYPE_UNSIGNED (t1))
     490        12931 :         return merge_type_attributes_from (t1, t2);
     491              :       else
     492        47053 :         return merge_type_attributes_from (t2, t1);
     493              :     }
     494              : 
     495              :   /* If only one is real, use it as the result.  */
     496    106978938 :   if (code1 == REAL_TYPE && code2 != REAL_TYPE)
     497      1140267 :     return build_type_attribute_variant (t1, attributes);
     498    105838671 :   if (code2 == REAL_TYPE && code1 != REAL_TYPE)
     499      1001273 :     return build_type_attribute_variant (t2, attributes);
     500              : 
     501    104837398 :   if (code1 == REAL_TYPE
     502    104837398 :       && (extended_float_type_p (t1) || extended_float_type_p (t2)))
     503              :     {
     504       105552 :       tree mv1 = TYPE_MAIN_VARIANT (t1);
     505       105552 :       tree mv2 = TYPE_MAIN_VARIANT (t2);
     506       105552 :       if (mv1 == mv2)
     507       103173 :         return build_type_attribute_variant (t1, attributes);
     508              : 
     509         2379 :       int cmpret = cp_compare_floating_point_conversion_ranks (mv1, mv2);
     510         2379 :       if (cmpret == 3)
     511            6 :         return error_mark_node;
     512         2373 :       else if (cmpret >= 0)
     513         2050 :         return build_type_attribute_variant (t1, attributes);
     514              :       else
     515          323 :         return build_type_attribute_variant (t2, attributes);
     516              :     }
     517              : 
     518              :   /* Both real or both integers; use the one with greater precision.  */
     519    104731846 :   if (TYPE_PRECISION (t1) > TYPE_PRECISION (t2))
     520     16460019 :     return build_type_attribute_variant (t1, attributes);
     521     88271827 :   else if (TYPE_PRECISION (t2) > TYPE_PRECISION (t1))
     522      1890448 :     return build_type_attribute_variant (t2, attributes);
     523              : 
     524              :   /* The types are the same; no need to do anything fancy.  */
     525     86381379 :   if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
     526     79209271 :     return build_type_attribute_variant (t1, attributes);
     527              : 
     528      7172108 :   if (code1 != REAL_TYPE)
     529              :     {
     530              :       /* If one is unsigned long long, then convert the other to unsigned
     531              :          long long.  */
     532      7172105 :       if (same_type_p (TYPE_MAIN_VARIANT (t1), long_long_unsigned_type_node)
     533      7172105 :           || same_type_p (TYPE_MAIN_VARIANT (t2), long_long_unsigned_type_node))
     534       151724 :         return build_type_attribute_variant (long_long_unsigned_type_node,
     535       151724 :                                              attributes);
     536              :       /* If one is a long long, and the other is an unsigned long, and
     537              :          long long can represent all the values of an unsigned long, then
     538              :          convert to a long long.  Otherwise, convert to an unsigned long
     539              :          long.  Otherwise, if either operand is long long, convert the
     540              :          other to long long.
     541              : 
     542              :          Since we're here, we know the TYPE_PRECISION is the same;
     543              :          therefore converting to long long cannot represent all the values
     544              :          of an unsigned long, so we choose unsigned long long in that
     545              :          case.  */
     546      7020381 :       if (same_type_p (TYPE_MAIN_VARIANT (t1), long_long_integer_type_node)
     547      7020381 :           || same_type_p (TYPE_MAIN_VARIANT (t2), long_long_integer_type_node))
     548              :         {
     549         1326 :           tree t = ((TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
     550          669 :                     ? long_long_unsigned_type_node
     551          669 :                     : long_long_integer_type_node);
     552          669 :           return build_type_attribute_variant (t, attributes);
     553              :         }
     554              : 
     555              :       /* Go through the same procedure, but for longs.  */
     556      7019712 :       if (same_type_p (TYPE_MAIN_VARIANT (t1), long_unsigned_type_node)
     557      7019712 :           || same_type_p (TYPE_MAIN_VARIANT (t2), long_unsigned_type_node))
     558       892055 :         return build_type_attribute_variant (long_unsigned_type_node,
     559       892055 :                                              attributes);
     560      6127657 :       if (same_type_p (TYPE_MAIN_VARIANT (t1), long_integer_type_node)
     561      6127657 :           || same_type_p (TYPE_MAIN_VARIANT (t2), long_integer_type_node))
     562              :         {
     563        75719 :           tree t = ((TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
     564        75719 :                     ? long_unsigned_type_node : long_integer_type_node);
     565        38334 :           return build_type_attribute_variant (t, attributes);
     566              :         }
     567              : 
     568              :       /* For __intN types, either the type is __int128 (and is lower
     569              :          priority than the types checked above, but higher than other
     570              :          128-bit types) or it's known to not be the same size as other
     571              :          types (enforced in toplev.cc).  Prefer the unsigned type. */
     572     12178614 :       for (i = 0; i < NUM_INT_N_ENTS; i ++)
     573              :         {
     574      6089323 :           if (int_n_enabled_p [i]
     575      6089323 :               && (same_type_p (TYPE_MAIN_VARIANT (t1), int_n_trees[i].signed_type)
     576      6000813 :                   || same_type_p (TYPE_MAIN_VARIANT (t2), int_n_trees[i].signed_type)
     577      6000809 :                   || same_type_p (TYPE_MAIN_VARIANT (t1), int_n_trees[i].unsigned_type)
     578      6000809 :                   || same_type_p (TYPE_MAIN_VARIANT (t2), int_n_trees[i].unsigned_type)))
     579              :             {
     580           60 :               tree t = ((TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
     581           32 :                         ? int_n_trees[i].unsigned_type
     582           32 :                         : int_n_trees[i].signed_type);
     583           32 :               return build_type_attribute_variant (t, attributes);
     584              :             }
     585              :         }
     586              : 
     587              :       /* Otherwise prefer the unsigned one.  */
     588      6089291 :       if (TYPE_UNSIGNED (t1))
     589      4920006 :         return build_type_attribute_variant (t1, attributes);
     590              :       else
     591      1169285 :         return build_type_attribute_variant (t2, attributes);
     592              :     }
     593              :   else
     594              :     {
     595            3 :       if (same_type_p (TYPE_MAIN_VARIANT (t1), long_double_type_node)
     596            3 :           || same_type_p (TYPE_MAIN_VARIANT (t2), long_double_type_node))
     597            0 :         return build_type_attribute_variant (long_double_type_node,
     598            0 :                                              attributes);
     599            3 :       if (same_type_p (TYPE_MAIN_VARIANT (t1), double_type_node)
     600            3 :           || same_type_p (TYPE_MAIN_VARIANT (t2), double_type_node))
     601            3 :         return build_type_attribute_variant (double_type_node,
     602            3 :                                              attributes);
     603            0 :       if (same_type_p (TYPE_MAIN_VARIANT (t1), float_type_node)
     604            0 :           || same_type_p (TYPE_MAIN_VARIANT (t2), float_type_node))
     605            0 :         return build_type_attribute_variant (float_type_node,
     606            0 :                                              attributes);
     607              : 
     608              :       /* Two floating-point types whose TYPE_MAIN_VARIANTs are none of
     609              :          the standard C++ floating-point types.  Logic earlier in this
     610              :          function has already eliminated the possibility that
     611              :          TYPE_PRECISION (t2) != TYPE_PRECISION (t1), so there's no
     612              :          compelling reason to choose one or the other.  */
     613            0 :       return build_type_attribute_variant (t1, attributes);
     614              :     }
     615              : }
     616              : 
     617              : /* T1 and T2 are arithmetic or enumeration types.  Return the type
     618              :    that will result from the "usual arithmetic conversions" on T1 and
     619              :    T2 as described in [expr].  */
     620              : 
     621              : tree
     622      1156741 : type_after_usual_arithmetic_conversions (tree t1, tree t2)
     623              : {
     624      1156741 :   gcc_assert (ARITHMETIC_TYPE_P (t1)
     625              :               || VECTOR_TYPE_P (t1)
     626              :               || UNSCOPED_ENUM_P (t1));
     627      1156741 :   gcc_assert (ARITHMETIC_TYPE_P (t2)
     628              :               || VECTOR_TYPE_P (t2)
     629              :               || UNSCOPED_ENUM_P (t2));
     630              : 
     631              :   /* Perform the integral promotions.  We do not promote real types here.  */
     632      1156741 :   if (INTEGRAL_OR_ENUMERATION_TYPE_P (t1)
     633       939953 :       && INTEGRAL_OR_ENUMERATION_TYPE_P (t2))
     634              :     {
     635       939686 :       t1 = type_promotes_to (t1);
     636       939686 :       t2 = type_promotes_to (t2);
     637              :     }
     638              : 
     639      1156741 :   return cp_common_type (t1, t2);
     640              : }
     641              : 
     642              : static void
     643           42 : composite_pointer_error (const op_location_t &location,
     644              :                          enum diagnostics::kind kind, tree t1, tree t2,
     645              :                          composite_pointer_operation operation)
     646              : {
     647           42 :   switch (operation)
     648              :     {
     649           33 :     case CPO_COMPARISON:
     650           33 :       emit_diagnostic (kind, location, 0,
     651              :                        "comparison between "
     652              :                        "distinct pointer types %qT and %qT lacks a cast",
     653              :                        t1, t2);
     654           33 :       break;
     655            0 :     case CPO_CONVERSION:
     656            0 :       emit_diagnostic (kind, location, 0,
     657              :                        "conversion between "
     658              :                        "distinct pointer types %qT and %qT lacks a cast",
     659              :                        t1, t2);
     660            0 :       break;
     661            9 :     case CPO_CONDITIONAL_EXPR:
     662            9 :       emit_diagnostic (kind, location, 0,
     663              :                        "conditional expression between "
     664              :                        "distinct pointer types %qT and %qT lacks a cast",
     665              :                        t1, t2);
     666            9 :       break;
     667            0 :     default:
     668            0 :       gcc_unreachable ();
     669              :     }
     670           42 : }
     671              : 
     672              : /* Subroutine of composite_pointer_type to implement the recursive
     673              :    case.  See that function for documentation of the parameters.  And ADD_CONST
     674              :    is used to track adding "const" where needed.  */
     675              : 
     676              : static tree
     677      5888353 : composite_pointer_type_r (const op_location_t &location,
     678              :                           tree t1, tree t2, bool *add_const,
     679              :                           composite_pointer_operation operation,
     680              :                           tsubst_flags_t complain)
     681              : {
     682      5888353 :   tree pointee1;
     683      5888353 :   tree pointee2;
     684      5888353 :   tree result_type;
     685      5888353 :   tree attributes;
     686              : 
     687              :   /* Determine the types pointed to by T1 and T2.  */
     688      5888353 :   if (TYPE_PTR_P (t1))
     689              :     {
     690      5887782 :       pointee1 = TREE_TYPE (t1);
     691      5887782 :       pointee2 = TREE_TYPE (t2);
     692              :     }
     693              :   else
     694              :     {
     695          571 :       pointee1 = TYPE_PTRMEM_POINTED_TO_TYPE (t1);
     696          571 :       pointee2 = TYPE_PTRMEM_POINTED_TO_TYPE (t2);
     697              :     }
     698              : 
     699              :   /* [expr.type]
     700              : 
     701              :      If T1 and T2 are similar types, the result is the cv-combined type of
     702              :      T1 and T2.  */
     703      5888353 :   if (same_type_ignoring_top_level_qualifiers_p (pointee1, pointee2))
     704              :     result_type = pointee1;
     705           33 :   else if ((TYPE_PTR_P (pointee1) && TYPE_PTR_P (pointee2))
     706          134 :            || (TYPE_PTRMEM_P (pointee1) && TYPE_PTRMEM_P (pointee2)))
     707              :     {
     708           33 :       result_type = composite_pointer_type_r (location, pointee1, pointee2,
     709              :                                               add_const, operation, complain);
     710           33 :       if (result_type == error_mark_node)
     711              :         return error_mark_node;
     712              :     }
     713              :   else
     714              :     {
     715          101 :       if (complain & tf_error)
     716           30 :         composite_pointer_error (location, diagnostics::kind::permerror,
     717              :                                  t1, t2, operation);
     718              :       else
     719           71 :         return error_mark_node;
     720           30 :       result_type = void_type_node;
     721              :     }
     722      5888276 :   const int q1 = cp_type_quals (pointee1);
     723      5888276 :   const int q2 = cp_type_quals (pointee2);
     724      5888276 :   const int quals = q1 | q2;
     725      5888276 :   result_type = cp_build_qualified_type (result_type,
     726      5888276 :                                          (quals | (*add_const
     727      5888276 :                                                    ? TYPE_QUAL_CONST
     728              :                                                    : TYPE_UNQUALIFIED)));
     729              :   /* The cv-combined type can add "const" as per [conv.qual]/3.3 (except for
     730              :      the TLQ).  The reason is that both T1 and T2 can then be converted to the
     731              :      cv-combined type of T1 and T2.  */
     732      5888276 :   if (quals != q1 || quals != q2)
     733       719834 :     *add_const = true;
     734              :   /* If the original types were pointers to members, so is the
     735              :      result.  */
     736      5888276 :   if (TYPE_PTRMEM_P (t1))
     737              :     {
     738          557 :       if (!same_type_p (TYPE_PTRMEM_CLASS_TYPE (t1),
     739              :                         TYPE_PTRMEM_CLASS_TYPE (t2)))
     740              :         {
     741            0 :           if (complain & tf_error)
     742            0 :             composite_pointer_error (location, diagnostics::kind::permerror,
     743              :                                      t1, t2, operation);
     744              :           else
     745            0 :             return error_mark_node;
     746              :         }
     747          557 :       result_type = build_ptrmem_type (TYPE_PTRMEM_CLASS_TYPE (t1),
     748              :                                        result_type);
     749              :     }
     750              :   else
     751      5887719 :     result_type = build_pointer_type (result_type);
     752              : 
     753              :   /* Merge the attributes.  */
     754      5888276 :   attributes = (*targetm.merge_type_attributes) (t1, t2);
     755      5888276 :   return build_type_attribute_variant (result_type, attributes);
     756              : }
     757              : 
     758              : /* Return the composite pointer type (see [expr.type]) for T1 and T2.
     759              :    ARG1 and ARG2 are the values with those types.  The OPERATION is to
     760              :    describe the operation between the pointer types,
     761              :    in case an error occurs.
     762              : 
     763              :    This routine also implements the computation of a common type for
     764              :    pointers-to-members as per [expr.eq].  */
     765              : 
     766              : tree
     767      6344282 : composite_pointer_type (const op_location_t &location,
     768              :                         tree t1, tree t2, tree arg1, tree arg2,
     769              :                         composite_pointer_operation operation,
     770              :                         tsubst_flags_t complain)
     771              : {
     772      6344282 :   tree class1;
     773      6344282 :   tree class2;
     774              : 
     775              :   /* [expr.type]
     776              : 
     777              :      If one operand is a null pointer constant, the composite pointer
     778              :      type is the type of the other operand.  */
     779      6344282 :   if (null_ptr_cst_p (arg1))
     780              :     return t2;
     781      6344107 :   if (null_ptr_cst_p (arg2))
     782              :     return t1;
     783              : 
     784              :   /* We have:
     785              : 
     786              :        [expr.type]
     787              : 
     788              :        If one of the operands has type "pointer to cv1 void", then
     789              :        the other has type "pointer to cv2 T", and the composite pointer
     790              :        type is "pointer to cv12 void", where cv12 is the union of cv1
     791              :        and cv2.
     792              : 
     793              :     If either type is a pointer to void, make sure it is T1.  */
     794      6323327 :   if (TYPE_PTR_P (t2) && VOID_TYPE_P (TREE_TYPE (t2)))
     795              :     std::swap (t1, t2);
     796              : 
     797              :   /* Now, if T1 is a pointer to void, merge the qualifiers.  */
     798      6323327 :   if (TYPE_PTR_P (t1) && VOID_TYPE_P (TREE_TYPE (t1)))
     799              :     {
     800       434902 :       tree attributes;
     801       434902 :       tree result_type;
     802              : 
     803       434902 :       if (TYPE_PTRFN_P (t2))
     804              :         {
     805           11 :           if (complain & tf_error)
     806              :             {
     807            9 :               switch (operation)
     808              :                 {
     809            9 :                 case CPO_COMPARISON:
     810            9 :                   pedwarn (location, OPT_Wpedantic,
     811              :                            "ISO C++ forbids comparison between pointer "
     812              :                            "of type %<void *%> and pointer-to-function");
     813            9 :                   break;
     814            0 :                 case CPO_CONVERSION:
     815            0 :                   pedwarn (location, OPT_Wpedantic,
     816              :                            "ISO C++ forbids conversion between pointer "
     817              :                            "of type %<void *%> and pointer-to-function");
     818            0 :                   break;
     819            0 :                 case CPO_CONDITIONAL_EXPR:
     820            0 :                   pedwarn (location, OPT_Wpedantic,
     821              :                            "ISO C++ forbids conditional expression between "
     822              :                            "pointer of type %<void *%> and "
     823              :                            "pointer-to-function");
     824            0 :                   break;
     825            0 :                 default:
     826            0 :                   gcc_unreachable ();
     827              :                 }
     828              :             }
     829              :           else
     830            2 :             return error_mark_node;
     831              :         }
     832       434900 :       result_type
     833       434900 :         = cp_build_qualified_type (void_type_node,
     834       434900 :                                    (cp_type_quals (TREE_TYPE (t1))
     835       434900 :                                     | cp_type_quals (TREE_TYPE (t2))));
     836       434900 :       result_type = build_pointer_type (result_type);
     837              :       /* Merge the attributes.  */
     838       434900 :       attributes = (*targetm.merge_type_attributes) (t1, t2);
     839       434900 :       return build_type_attribute_variant (result_type, attributes);
     840              :     }
     841              : 
     842      5888425 :   if (c_dialect_objc () && TYPE_PTR_P (t1)
     843            0 :       && TYPE_PTR_P (t2))
     844              :     {
     845            0 :       if (objc_have_common_type (t1, t2, -3, NULL_TREE))
     846            0 :         return objc_common_type (t1, t2);
     847              :     }
     848              : 
     849              :   /* if T1 or T2 is "pointer to noexcept function" and the other type is
     850              :      "pointer to function", where the function types are otherwise the same,
     851              :      "pointer to function" */
     852      5888425 :   if (fnptr_conv_p (t1, t2))
     853              :     return t1;
     854      5888390 :   if (fnptr_conv_p (t2, t1))
     855              :     return t2;
     856              : 
     857              :   /* [expr.eq] permits the application of a pointer conversion to
     858              :      bring the pointers to a common type.  */
     859      5887767 :   if (TYPE_PTR_P (t1) && TYPE_PTR_P (t2)
     860      5887767 :       && CLASS_TYPE_P (TREE_TYPE (t1))
     861       915847 :       && CLASS_TYPE_P (TREE_TYPE (t2))
     862      6804203 :       && !same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (t1),
     863       915844 :                                                      TREE_TYPE (t2)))
     864              :     {
     865        29174 :       class1 = TREE_TYPE (t1);
     866        29174 :       class2 = TREE_TYPE (t2);
     867              : 
     868        29174 :       if (DERIVED_FROM_P (class1, class2))
     869         3140 :         t2 = (build_pointer_type
     870         1570 :               (cp_build_qualified_type (class1, cp_type_quals (class2))));
     871        27604 :       else if (DERIVED_FROM_P (class2, class1))
     872        55172 :         t1 = (build_pointer_type
     873        27586 :               (cp_build_qualified_type (class2, cp_type_quals (class1))));
     874              :       else
     875              :         {
     876           18 :           if (complain & tf_error)
     877           12 :             composite_pointer_error (location, diagnostics::kind::error,
     878              :                                      t1, t2, operation);
     879           18 :           return error_mark_node;
     880              :         }
     881              :     }
     882              :   /* [expr.eq] permits the application of a pointer-to-member
     883              :      conversion to change the class type of one of the types.  */
     884      5858746 :   else if (TYPE_PTRMEM_P (t1)
     885      5859338 :            && !same_type_p (TYPE_PTRMEM_CLASS_TYPE (t1),
     886              :                             TYPE_PTRMEM_CLASS_TYPE (t2)))
     887              :     {
     888           79 :       class1 = TYPE_PTRMEM_CLASS_TYPE (t1);
     889           79 :       class2 = TYPE_PTRMEM_CLASS_TYPE (t2);
     890              : 
     891           79 :       if (DERIVED_FROM_P (class1, class2))
     892           43 :         t1 = build_ptrmem_type (class2, TYPE_PTRMEM_POINTED_TO_TYPE (t1));
     893           36 :       else if (DERIVED_FROM_P (class2, class1))
     894           15 :         t2 = build_ptrmem_type (class1, TYPE_PTRMEM_POINTED_TO_TYPE (t2));
     895              :       else
     896              :         {
     897           21 :           if (complain & tf_error)
     898            3 :             switch (operation)
     899              :               {
     900            3 :               case CPO_COMPARISON:
     901            3 :                 error_at (location, "comparison between distinct "
     902              :                           "pointer-to-member types %qT and %qT lacks a cast",
     903              :                           t1, t2);
     904            3 :                 break;
     905            0 :               case CPO_CONVERSION:
     906            0 :                 error_at (location, "conversion between distinct "
     907              :                           "pointer-to-member types %qT and %qT lacks a cast",
     908              :                           t1, t2);
     909            0 :                 break;
     910            0 :               case CPO_CONDITIONAL_EXPR:
     911            0 :                 error_at (location, "conditional expression between distinct "
     912              :                           "pointer-to-member types %qT and %qT lacks a cast",
     913              :                           t1, t2);
     914            0 :                 break;
     915            0 :               default:
     916            0 :                 gcc_unreachable ();
     917              :               }
     918           21 :           return error_mark_node;
     919              :         }
     920              :     }
     921              : 
     922      5888320 :   bool add_const = false;
     923      5888320 :   return composite_pointer_type_r (location, t1, t2, &add_const, operation,
     924      5888320 :                                    complain);
     925              : }
     926              : 
     927              : /* Return the merged type of two types.
     928              :    We assume that comptypes has already been done and returned 1;
     929              :    if that isn't so, this may crash.
     930              : 
     931              :    This just combines attributes and default arguments; any other
     932              :    differences would cause the two types to compare unalike.  */
     933              : 
     934              : tree
     935     29526783 : merge_types (tree t1, tree t2)
     936              : {
     937     29526783 :   enum tree_code code1;
     938     29526783 :   enum tree_code code2;
     939     29526783 :   tree attributes;
     940              : 
     941              :   /* Save time if the two types are the same.  */
     942     29526783 :   if (t1 == t2)
     943              :     return t1;
     944     16150901 :   if (original_type (t1) == original_type (t2))
     945              :     return t1;
     946              : 
     947              :   /* If one type is nonsense, use the other.  */
     948     16030698 :   if (t1 == error_mark_node)
     949              :     return t2;
     950     16030698 :   if (t2 == error_mark_node)
     951              :     return t1;
     952              : 
     953              :   /* Handle merging an auto redeclaration with a previous deduced
     954              :      return type.  */
     955     16030698 :   if (is_auto (t1))
     956              :     return t2;
     957              : 
     958              :   /* Merge the attributes.  */
     959     16021633 :   attributes = (*targetm.merge_type_attributes) (t1, t2);
     960              : 
     961     16021633 :   if (TYPE_PTRMEMFUNC_P (t1))
     962           15 :     t1 = TYPE_PTRMEMFUNC_FN_TYPE (t1);
     963     16021633 :   if (TYPE_PTRMEMFUNC_P (t2))
     964           15 :     t2 = TYPE_PTRMEMFUNC_FN_TYPE (t2);
     965              : 
     966     16021633 :   code1 = TREE_CODE (t1);
     967     16021633 :   code2 = TREE_CODE (t2);
     968     16021633 :   if (code1 != code2)
     969              :     {
     970            0 :       gcc_assert (code1 == TYPENAME_TYPE || code2 == TYPENAME_TYPE);
     971            0 :       if (code1 == TYPENAME_TYPE)
     972              :         {
     973            0 :           t1 = resolve_typename_type (t1, /*only_current_p=*/true);
     974            0 :           code1 = TREE_CODE (t1);
     975              :         }
     976              :       else
     977              :         {
     978            0 :           t2 = resolve_typename_type (t2, /*only_current_p=*/true);
     979            0 :           code2 = TREE_CODE (t2);
     980              :         }
     981              :     }
     982              : 
     983     16021633 :   switch (code1)
     984              :     {
     985      2726000 :     case POINTER_TYPE:
     986      2726000 :     case REFERENCE_TYPE:
     987              :       /* For two pointers, do this recursively on the target type.  */
     988      2726000 :       {
     989      2726000 :         tree target = merge_types (TREE_TYPE (t1), TREE_TYPE (t2));
     990      2726000 :         int quals = cp_type_quals (t1);
     991              : 
     992      2726000 :         if (code1 == POINTER_TYPE)
     993              :           {
     994       742725 :             t1 = build_pointer_type (target);
     995       742725 :             if (TREE_CODE (target) == METHOD_TYPE)
     996           15 :               t1 = build_ptrmemfunc_type (t1);
     997              :           }
     998              :         else
     999      1983275 :           t1 = cp_build_reference_type (target, TYPE_REF_IS_RVALUE (t1));
    1000      2726000 :         t1 = build_type_attribute_variant (t1, attributes);
    1001      2726000 :         t1 = cp_build_qualified_type (t1, quals);
    1002              : 
    1003      2726000 :         return t1;
    1004              :       }
    1005              : 
    1006           12 :     case OFFSET_TYPE:
    1007           12 :       {
    1008           12 :         int quals;
    1009           12 :         tree pointee;
    1010           12 :         quals = cp_type_quals (t1);
    1011           12 :         pointee = merge_types (TYPE_PTRMEM_POINTED_TO_TYPE (t1),
    1012           12 :                                TYPE_PTRMEM_POINTED_TO_TYPE (t2));
    1013           12 :         t1 = build_ptrmem_type (TYPE_PTRMEM_CLASS_TYPE (t1),
    1014              :                                 pointee);
    1015           12 :         t1 = cp_build_qualified_type (t1, quals);
    1016           12 :         break;
    1017              :       }
    1018              : 
    1019        10151 :     case ARRAY_TYPE:
    1020        10151 :       {
    1021        10151 :         tree elt = merge_types (TREE_TYPE (t1), TREE_TYPE (t2));
    1022              :         /* Save space: see if the result is identical to one of the args.  */
    1023        20302 :         if (elt == TREE_TYPE (t1) && TYPE_DOMAIN (t1))
    1024        10126 :           return build_type_attribute_variant (t1, attributes);
    1025           44 :         if (elt == TREE_TYPE (t2) && TYPE_DOMAIN (t2))
    1026           19 :           return build_type_attribute_variant (t2, attributes);
    1027              :         /* Merge the element types, and have a size if either arg has one.  */
    1028            6 :         t1 = build_cplus_array_type
    1029            6 :           (elt, TYPE_DOMAIN (TYPE_DOMAIN (t1) ? t1 : t2));
    1030            6 :         break;
    1031              :       }
    1032              : 
    1033      4270439 :     case FUNCTION_TYPE:
    1034              :       /* Function types: prefer the one that specified arg types.
    1035              :          If both do, merge the arg types.  Also merge the return types.  */
    1036      4270439 :       {
    1037      4270439 :         tree valtype = merge_types (TREE_TYPE (t1), TREE_TYPE (t2));
    1038      4270439 :         tree p1 = TYPE_ARG_TYPES (t1);
    1039      4270439 :         tree p2 = TYPE_ARG_TYPES (t2);
    1040      4270439 :         tree parms;
    1041              : 
    1042              :         /* Save space: see if the result is identical to one of the args.  */
    1043      4270439 :         if (valtype == TREE_TYPE (t1) && ! p2)
    1044            0 :           return cp_build_type_attribute_variant (t1, attributes);
    1045      4270439 :         if (valtype == TREE_TYPE (t2) && ! p1)
    1046            0 :           return cp_build_type_attribute_variant (t2, attributes);
    1047              : 
    1048              :         /* Simple way if one arg fails to specify argument types.  */
    1049      8540878 :         if (p1 == NULL_TREE || TREE_VALUE (p1) == void_type_node)
    1050              :           parms = p2;
    1051      8253820 :         else if (p2 == NULL_TREE || TREE_VALUE (p2) == void_type_node)
    1052              :           parms = p1;
    1053              :         else
    1054      4126910 :           parms = commonparms (p1, p2);
    1055              : 
    1056      4270439 :         cp_cv_quals quals = type_memfn_quals (t1);
    1057      4270439 :         cp_ref_qualifier rqual = type_memfn_rqual (t1);
    1058      4270439 :         gcc_assert (quals == type_memfn_quals (t2));
    1059      4270439 :         gcc_assert (rqual == type_memfn_rqual (t2));
    1060              : 
    1061      4270439 :         tree rval = cp_build_function_type (valtype, parms);
    1062      4270439 :         rval = apply_memfn_quals (rval, quals);
    1063      4270439 :         tree raises = merge_exception_specifiers (TYPE_RAISES_EXCEPTIONS (t1),
    1064      4270439 :                                                   TYPE_RAISES_EXCEPTIONS (t2));
    1065      4270439 :         bool late_return_type_p = TYPE_HAS_LATE_RETURN_TYPE (t1);
    1066      4270439 :         t1 = build_cp_fntype_variant (rval, rqual, raises, late_return_type_p);
    1067      4270439 :         break;
    1068              :       }
    1069              : 
    1070      3883811 :     case METHOD_TYPE:
    1071      3883811 :       {
    1072              :         /* Get this value the long way, since TYPE_METHOD_BASETYPE
    1073              :            is just the main variant of this.  */
    1074      3883811 :         tree basetype = class_of_this_parm (t2);
    1075      3883811 :         tree raises = merge_exception_specifiers (TYPE_RAISES_EXCEPTIONS (t1),
    1076      3883811 :                                                   TYPE_RAISES_EXCEPTIONS (t2));
    1077      3883811 :         cp_ref_qualifier rqual = type_memfn_rqual (t1);
    1078      3883811 :         tree t3;
    1079      3883811 :         bool late_return_type_1_p = TYPE_HAS_LATE_RETURN_TYPE (t1);
    1080              : 
    1081              :         /* If this was a member function type, get back to the
    1082              :            original type of type member function (i.e., without
    1083              :            the class instance variable up front.  */
    1084      3883811 :         t1 = cp_build_function_type (TREE_TYPE (t1),
    1085      3883811 :                                      TREE_CHAIN (TYPE_ARG_TYPES (t1)));
    1086      3883811 :         t2 = cp_build_function_type (TREE_TYPE (t2),
    1087      3883811 :                                      TREE_CHAIN (TYPE_ARG_TYPES (t2)));
    1088      3883811 :         t3 = merge_types (t1, t2);
    1089      3883811 :         t3 = build_method_type_directly (basetype, TREE_TYPE (t3),
    1090      3883811 :                                          TYPE_ARG_TYPES (t3));
    1091      3883811 :         t1 = build_cp_fntype_variant (t3, rqual, raises, late_return_type_1_p);
    1092      3883811 :         break;
    1093              :       }
    1094              : 
    1095              :     case TYPENAME_TYPE:
    1096              :       /* There is no need to merge attributes into a TYPENAME_TYPE.
    1097              :          When the type is instantiated it will have whatever
    1098              :          attributes result from the instantiation.  */
    1099              :       return t1;
    1100              : 
    1101      5121329 :     default:;
    1102      5121329 :       if (attribute_list_equal (TYPE_ATTRIBUTES (t1), attributes))
    1103              :         return t1;
    1104           12 :       else if (attribute_list_equal (TYPE_ATTRIBUTES (t2), attributes))
    1105              :         return t2;
    1106              :       break;
    1107              :     }
    1108              : 
    1109      8154268 :   return cp_build_type_attribute_variant (t1, attributes);
    1110              : }
    1111              : 
    1112              : /* Return the ARRAY_TYPE type without its domain.  */
    1113              : 
    1114              : tree
    1115          387 : strip_array_domain (tree type)
    1116              : {
    1117          387 :   tree t2;
    1118          387 :   gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
    1119          387 :   if (TYPE_DOMAIN (type) == NULL_TREE)
    1120              :     return type;
    1121          226 :   t2 = build_cplus_array_type (TREE_TYPE (type), NULL_TREE);
    1122          226 :   return cp_build_type_attribute_variant (t2, TYPE_ATTRIBUTES (type));
    1123              : }
    1124              : 
    1125              : /* Wrapper around cp_common_type that is used by c-common.cc and other
    1126              :    front end optimizations that remove promotions.
    1127              : 
    1128              :    Return the common type for two arithmetic types T1 and T2 under the
    1129              :    usual arithmetic conversions.  The default conversions have already
    1130              :    been applied, and enumerated types converted to their compatible
    1131              :    integer types.  */
    1132              : 
    1133              : tree
    1134       621555 : common_type (tree t1, tree t2)
    1135              : {
    1136              :   /* If one type is nonsense, use the other  */
    1137       621555 :   if (t1 == error_mark_node)
    1138              :     return t2;
    1139       621555 :   if (t2 == error_mark_node)
    1140              :     return t1;
    1141              : 
    1142       621555 :   return cp_common_type (t1, t2);
    1143              : }
    1144              : 
    1145              : /* Return the common type of two pointer types T1 and T2.  This is the
    1146              :    type for the result of most arithmetic operations if the operands
    1147              :    have the given two types.
    1148              : 
    1149              :    We assume that comp_target_types has already been done and returned
    1150              :    nonzero; if that isn't so, this may crash.  */
    1151              : 
    1152              : tree
    1153      1461280 : common_pointer_type (tree t1, tree t2)
    1154              : {
    1155      1461280 :   gcc_assert ((TYPE_PTR_P (t1) && TYPE_PTR_P (t2))
    1156              :               || (TYPE_PTRDATAMEM_P (t1) && TYPE_PTRDATAMEM_P (t2))
    1157              :               || (TYPE_PTRMEMFUNC_P (t1) && TYPE_PTRMEMFUNC_P (t2)));
    1158              : 
    1159      1461280 :   return composite_pointer_type (input_location, t1, t2,
    1160              :                                  error_mark_node, error_mark_node,
    1161      1461280 :                                  CPO_CONVERSION, tf_warning_or_error);
    1162              : }
    1163              : 
    1164              : /* Compare two exception specifier types for exactness or subsetness, if
    1165              :    allowed. Returns false for mismatch, true for match (same, or
    1166              :    derived and !exact).
    1167              : 
    1168              :    [except.spec] "If a class X ... objects of class X or any class publicly
    1169              :    and unambiguously derived from X. Similarly, if a pointer type Y * ...
    1170              :    exceptions of type Y * or that are pointers to any type publicly and
    1171              :    unambiguously derived from Y. Otherwise a function only allows exceptions
    1172              :    that have the same type ..."
    1173              :    This does not mention cv qualifiers and is different to what throw
    1174              :    [except.throw] and catch [except.catch] will do. They will ignore the
    1175              :    top level cv qualifiers, and allow qualifiers in the pointer to class
    1176              :    example.
    1177              : 
    1178              :    We implement the letter of the standard.  */
    1179              : 
    1180              : static bool
    1181         1696 : comp_except_types (tree a, tree b, bool exact)
    1182              : {
    1183         1696 :   if (same_type_p (a, b))
    1184              :     return true;
    1185          506 :   else if (!exact)
    1186              :     {
    1187           11 :       if (cp_type_quals (a) || cp_type_quals (b))
    1188            0 :         return false;
    1189              : 
    1190           11 :       if (TYPE_PTR_P (a) && TYPE_PTR_P (b))
    1191              :         {
    1192            7 :           a = TREE_TYPE (a);
    1193            7 :           b = TREE_TYPE (b);
    1194            7 :           if (cp_type_quals (a) || cp_type_quals (b))
    1195            1 :             return false;
    1196              :         }
    1197              : 
    1198           10 :       if (TREE_CODE (a) != RECORD_TYPE
    1199           10 :           || TREE_CODE (b) != RECORD_TYPE)
    1200              :         return false;
    1201              : 
    1202            9 :       if (publicly_uniquely_derived_p (a, b))
    1203              :         return true;
    1204              :     }
    1205              :   return false;
    1206              : }
    1207              : 
    1208              : /* Return true if TYPE1 and TYPE2 are equivalent exception specifiers.
    1209              :    If EXACT is ce_derived, T2 can be stricter than T1 (according to 15.4/5).
    1210              :    If EXACT is ce_type, the C++17 type compatibility rules apply.
    1211              :    If EXACT is ce_normal, the compatibility rules in 15.4/3 apply.
    1212              :    If EXACT is ce_exact, the specs must be exactly the same. Exception lists
    1213              :    are unordered, but we've already filtered out duplicates. Most lists will
    1214              :    be in order, we should try to make use of that.  */
    1215              : 
    1216              : bool
    1217   1612100851 : comp_except_specs (const_tree t1, const_tree t2, int exact)
    1218              : {
    1219   1612100851 :   const_tree probe;
    1220   1612100851 :   const_tree base;
    1221   1612100851 :   int  length = 0;
    1222              : 
    1223   1612100851 :   if (t1 == t2)
    1224              :     return true;
    1225              : 
    1226              :   /* First handle noexcept.  */
    1227    657524801 :   if (exact < ce_exact)
    1228              :     {
    1229      9276214 :       if (exact == ce_type
    1230     18509787 :           && (canonical_eh_spec (const_cast<tree> (t1))
    1231      9233573 :               == canonical_eh_spec (const_cast<tree> (t2))))
    1232              :         return true;
    1233              : 
    1234              :       /* noexcept(false) is compatible with no exception-specification,
    1235              :          and less strict than any spec.  */
    1236      9256059 :       if (t1 == noexcept_false_spec)
    1237          177 :         return t2 == NULL_TREE || exact == ce_derived;
    1238              :       /* Even a derived noexcept(false) is compatible with no
    1239              :          exception-specification.  */
    1240      9255882 :       if (t2 == noexcept_false_spec)
    1241          958 :         return t1 == NULL_TREE;
    1242              : 
    1243              :       /* Otherwise, if we aren't looking for an exact match, noexcept is
    1244              :          equivalent to throw().  */
    1245      9254924 :       if (t1 == noexcept_true_spec)
    1246       695761 :         t1 = empty_except_spec;
    1247      9254924 :       if (t2 == noexcept_true_spec)
    1248      8378318 :         t2 = empty_except_spec;
    1249              :     }
    1250              : 
    1251              :   /* If any noexcept is left, it is only comparable to itself;
    1252              :      either we're looking for an exact match or we're redeclaring a
    1253              :      template with dependent noexcept.  */
    1254    628724490 :   if ((t1 && TREE_PURPOSE (t1))
    1255    689109390 :       || (t2 && TREE_PURPOSE (t2)))
    1256    646135431 :     return (t1 && t2
    1257    646135431 :             && (exact == ce_exact
    1258     79943731 :                 ? TREE_PURPOSE (t1) == TREE_PURPOSE (t2)
    1259       177812 :                 : cp_tree_equal (TREE_PURPOSE (t1), TREE_PURPOSE (t2))));
    1260              : 
    1261     11368080 :   if (t1 == NULL_TREE)                     /* T1 is ...  */
    1262      8604242 :     return t2 == NULL_TREE || exact == ce_derived;
    1263      2763838 :   if (!TREE_VALUE (t1))                    /* t1 is EMPTY */
    1264      2730426 :     return t2 != NULL_TREE && !TREE_VALUE (t2);
    1265        34820 :   if (t2 == NULL_TREE)                     /* T2 is ...  */
    1266              :     return false;
    1267         1574 :   if (TREE_VALUE (t1) && !TREE_VALUE (t2)) /* T2 is EMPTY, T1 is not */
    1268           76 :     return exact == ce_derived;
    1269              : 
    1270              :   /* Neither set is ... or EMPTY, make sure each part of T2 is in T1.
    1271              :      Count how many we find, to determine exactness. For exact matching and
    1272              :      ordered T1, T2, this is an O(n) operation, otherwise its worst case is
    1273              :      O(nm).  */
    1274         2691 :   for (base = t1; t2 != NULL_TREE; t2 = TREE_CHAIN (t2))
    1275              :     {
    1276         2092 :       for (probe = base; probe != NULL_TREE; probe = TREE_CHAIN (probe))
    1277              :         {
    1278         1696 :           tree a = TREE_VALUE (probe);
    1279         1696 :           tree b = TREE_VALUE (t2);
    1280              : 
    1281         1696 :           if (comp_except_types (a, b, exact))
    1282              :             {
    1283         1193 :               if (probe == base && exact > ce_derived)
    1284         1158 :                 base = TREE_CHAIN (probe);
    1285         1193 :               length++;
    1286         1193 :               break;
    1287              :             }
    1288              :         }
    1289         1193 :       if (probe == NULL_TREE)
    1290              :         return false;
    1291              :     }
    1292         1102 :   return exact == ce_derived || base == NULL_TREE || length == list_length (t1);
    1293              : }
    1294              : 
    1295              : /* Compare the array types T1 and T2.  CB says how we should behave when
    1296              :    comparing array bounds: bounds_none doesn't allow dimensionless arrays,
    1297              :    bounds_either says than any array can be [], bounds_first means that
    1298              :    onlt T1 can be an array with unknown bounds.  STRICT is true if
    1299              :    qualifiers must match when comparing the types of the array elements.  */
    1300              : 
    1301              : static bool
    1302      1795974 : comp_array_types (const_tree t1, const_tree t2, compare_bounds_t cb,
    1303              :                   bool strict)
    1304              : {
    1305      1795974 :   tree d1;
    1306      1795974 :   tree d2;
    1307      1795974 :   tree max1, max2;
    1308              : 
    1309      1795974 :   if (t1 == t2)
    1310              :     return true;
    1311              : 
    1312              :   /* The type of the array elements must be the same.  */
    1313      1795315 :   if (strict
    1314      1795315 :       ? !same_type_p (TREE_TYPE (t1), TREE_TYPE (t2))
    1315         8933 :       : !similar_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
    1316              :     return false;
    1317              : 
    1318      1163375 :   d1 = TYPE_DOMAIN (t1);
    1319      1163375 :   d2 = TYPE_DOMAIN (t2);
    1320              : 
    1321      1163375 :   if (d1 == d2)
    1322              :     return true;
    1323              : 
    1324              :   /* If one of the arrays is dimensionless, and the other has a
    1325              :      dimension, they are of different types.  However, it is valid to
    1326              :      write:
    1327              : 
    1328              :        extern int a[];
    1329              :        int a[3];
    1330              : 
    1331              :      by [basic.link]:
    1332              : 
    1333              :        declarations for an array object can specify
    1334              :        array types that differ by the presence or absence of a major
    1335              :        array bound (_dcl.array_).  */
    1336       642599 :   if (!d1 && d2)
    1337         5108 :     return cb >= bounds_either;
    1338       637491 :   else if (d1 && !d2)
    1339         7875 :     return cb == bounds_either;
    1340              : 
    1341              :   /* Check that the dimensions are the same.  */
    1342              : 
    1343       629616 :   if (!cp_tree_equal (TYPE_MIN_VALUE (d1), TYPE_MIN_VALUE (d2)))
    1344              :     return false;
    1345       629595 :   max1 = TYPE_MAX_VALUE (d1);
    1346       629595 :   max2 = TYPE_MAX_VALUE (d2);
    1347              : 
    1348       629595 :   if (!cp_tree_equal (max1, max2))
    1349              :     return false;
    1350              : 
    1351              :   return true;
    1352              : }
    1353              : 
    1354              : /* Compare the relative position of T1 and T2 into their respective
    1355              :    template parameter list.
    1356              :    T1 and T2 must be template parameter types.
    1357              :    Return TRUE if T1 and T2 have the same position, FALSE otherwise.  */
    1358              : 
    1359              : static bool
    1360   1898876208 : comp_template_parms_position (tree t1, tree t2)
    1361              : {
    1362   1898876208 :   tree index1, index2;
    1363   1898876208 :   gcc_assert (t1 && t2
    1364              :               && TREE_CODE (t1) == TREE_CODE (t2)
    1365              :               && (TREE_CODE (t1) == BOUND_TEMPLATE_TEMPLATE_PARM
    1366              :                   || TREE_CODE (t1) == TEMPLATE_TEMPLATE_PARM
    1367              :                   || TREE_CODE (t1) == TEMPLATE_TYPE_PARM));
    1368              : 
    1369   1898876208 :   index1 = TEMPLATE_TYPE_PARM_INDEX (TYPE_MAIN_VARIANT (t1));
    1370   1898876208 :   index2 = TEMPLATE_TYPE_PARM_INDEX (TYPE_MAIN_VARIANT (t2));
    1371              : 
    1372              :   /* Then compare their relative position.  */
    1373   1898876208 :   if (TEMPLATE_PARM_IDX (index1) != TEMPLATE_PARM_IDX (index2)
    1374   1301152297 :       || TEMPLATE_PARM_LEVEL (index1) != TEMPLATE_PARM_LEVEL (index2)
    1375   2755777338 :       || (TEMPLATE_PARM_PARAMETER_PACK (index1)
    1376    856901130 :           != TEMPLATE_PARM_PARAMETER_PACK (index2)))
    1377              :     return false;
    1378              : 
    1379              :   /* In C++14 we can end up comparing 'auto' to a normal template
    1380              :      parameter.  Don't confuse them.  */
    1381    769441741 :   if (cxx_dialect >= cxx14 && (is_auto (t1) || is_auto (t2)))
    1382    219591855 :     return TYPE_IDENTIFIER (t1) == TYPE_IDENTIFIER (t2);
    1383              : 
    1384              :   return true;
    1385              : }
    1386              : 
    1387              : /* Heuristic check if two parameter types can be considered ABI-equivalent.  */
    1388              : 
    1389              : static bool
    1390          512 : cxx_safe_arg_type_equiv_p (tree t1, tree t2)
    1391              : {
    1392          512 :   t1 = TYPE_MAIN_VARIANT (t1);
    1393          512 :   t2 = TYPE_MAIN_VARIANT (t2);
    1394              : 
    1395          512 :   if (TYPE_PTR_P (t1)
    1396          141 :       && TYPE_PTR_P (t2))
    1397              :     return true;
    1398              : 
    1399              :   /* Only the precision of the parameter matters.  This check should
    1400              :      make sure that the callee does not see undefined values in argument
    1401              :      registers.  */
    1402          377 :   if (INTEGRAL_TYPE_P (t1)
    1403           68 :       && INTEGRAL_TYPE_P (t2)
    1404          424 :       && TYPE_PRECISION (t1) == TYPE_PRECISION (t2))
    1405              :     return true;
    1406              : 
    1407          333 :   return same_type_p (t1, t2);
    1408              : }
    1409              : 
    1410              : /* Check if a type cast between two function types can be considered safe.  */
    1411              : 
    1412              : static bool
    1413          345 : cxx_safe_function_type_cast_p (tree t1, tree t2)
    1414              : {
    1415          345 :   if (TREE_TYPE (t1) == void_type_node &&
    1416          272 :       TYPE_ARG_TYPES (t1) == void_list_node)
    1417              :     return true;
    1418              : 
    1419          301 :   if (TREE_TYPE (t2) == void_type_node &&
    1420           95 :       TYPE_ARG_TYPES (t2) == void_list_node)
    1421              :     return true;
    1422              : 
    1423          273 :   if (!cxx_safe_arg_type_equiv_p (TREE_TYPE (t1), TREE_TYPE (t2)))
    1424              :     return false;
    1425              : 
    1426          112 :   for (t1 = TYPE_ARG_TYPES (t1), t2 = TYPE_ARG_TYPES (t2);
    1427          315 :        t1 && t2;
    1428          203 :        t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2))
    1429          239 :     if (!cxx_safe_arg_type_equiv_p (TREE_VALUE (t1), TREE_VALUE (t2)))
    1430              :       return false;
    1431              : 
    1432              :   return true;
    1433              : }
    1434              : 
    1435              : /* Subroutine in comptypes.  */
    1436              : 
    1437              : static bool
    1438  15940936657 : structural_comptypes (tree t1, tree t2, int strict)
    1439              : {
    1440              :   /* Both should be types that are not obviously the same.  */
    1441  15940936657 :   gcc_checking_assert (t1 != t2 && TYPE_P (t1) && TYPE_P (t2));
    1442              : 
    1443              :   /* Suppress typename resolution under spec_hasher::equal in place of calling
    1444              :      push_to_top_level there.  */
    1445  15940936657 :   if (!comparing_specializations)
    1446              :     {
    1447              :       /* TYPENAME_TYPEs should be resolved if the qualifying scope is the
    1448              :          current instantiation.  */
    1449  12594535903 :       if (TREE_CODE (t1) == TYPENAME_TYPE)
    1450     98005125 :         t1 = resolve_typename_type (t1, /*only_current_p=*/true);
    1451              : 
    1452  12594535903 :       if (TREE_CODE (t2) == TYPENAME_TYPE)
    1453    125931829 :         t2 = resolve_typename_type (t2, /*only_current_p=*/true);
    1454              :     }
    1455              : 
    1456  15940936657 :   if (TYPE_PTRMEMFUNC_P (t1))
    1457     25290046 :     t1 = TYPE_PTRMEMFUNC_FN_TYPE (t1);
    1458  15940936657 :   if (TYPE_PTRMEMFUNC_P (t2))
    1459     28459281 :     t2 = TYPE_PTRMEMFUNC_FN_TYPE (t2);
    1460              : 
    1461              :   /* Different classes of types can't be compatible.  */
    1462  15940936657 :   if (TREE_CODE (t1) != TREE_CODE (t2))
    1463              :     return false;
    1464              : 
    1465              :   /* Qualifiers must match.  For array types, we will check when we
    1466              :      recur on the array element types.  */
    1467  10616774329 :   if (TREE_CODE (t1) != ARRAY_TYPE
    1468  10616774329 :       && cp_type_quals (t1) != cp_type_quals (t2))
    1469              :     return false;
    1470   9968646260 :   if (TREE_CODE (t1) == FUNCTION_TYPE
    1471   9968646260 :       && type_memfn_quals (t1) != type_memfn_quals (t2))
    1472              :     return false;
    1473              :   /* Need to check this before TYPE_MAIN_VARIANT.
    1474              :      FIXME function qualifiers should really change the main variant.  */
    1475   9968582612 :   if (FUNC_OR_METHOD_TYPE_P (t1))
    1476              :     {
    1477     36847442 :       if (type_memfn_rqual (t1) != type_memfn_rqual (t2))
    1478              :         return false;
    1479     22036706 :       if (flag_noexcept_type
    1480     43999417 :           && !comp_except_specs (TYPE_RAISES_EXCEPTIONS (t1),
    1481     21962711 :                                  TYPE_RAISES_EXCEPTIONS (t2),
    1482              :                                  ce_type))
    1483              :         return false;
    1484              :     }
    1485              : 
    1486              :   /* Allow for two different type nodes which have essentially the same
    1487              :      definition.  Note that we already checked for equality of the type
    1488              :      qualifiers (just above).  */
    1489   9944697828 :   if (TREE_CODE (t1) != ARRAY_TYPE
    1490   9944697828 :       && TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
    1491    457661758 :     goto check_alias;
    1492              : 
    1493              :   /* Compare the types.  Return false on known not-same. Break on not
    1494              :      known.   Never return true from this switch -- you'll break
    1495              :      specialization comparison.    */
    1496   9487036070 :   switch (TREE_CODE (t1))
    1497              :     {
    1498              :     case VOID_TYPE:
    1499              :     case BOOLEAN_TYPE:
    1500              :       /* All void and bool types are the same.  */
    1501              :       break;
    1502              : 
    1503    772329925 :     case OPAQUE_TYPE:
    1504    772329925 :     case INTEGER_TYPE:
    1505    772329925 :     case FIXED_POINT_TYPE:
    1506    772329925 :     case REAL_TYPE:
    1507              :       /* With these nodes, we can't determine type equivalence by
    1508              :          looking at what is stored in the nodes themselves, because
    1509              :          two nodes might have different TYPE_MAIN_VARIANTs but still
    1510              :          represent the same type.  For example, wchar_t and int could
    1511              :          have the same properties (TYPE_PRECISION, TYPE_MIN_VALUE,
    1512              :          TYPE_MAX_VALUE, etc.), but have different TYPE_MAIN_VARIANTs
    1513              :          and are distinct types. On the other hand, int and the
    1514              :          following typedef
    1515              : 
    1516              :            typedef int INT __attribute((may_alias));
    1517              : 
    1518              :          have identical properties, different TYPE_MAIN_VARIANTs, but
    1519              :          represent the same type.  The canonical type system keeps
    1520              :          track of equivalence in this case, so we fall back on it.  */
    1521    772329925 :       if (TYPE_CANONICAL (t1) != TYPE_CANONICAL (t2))
    1522              :         return false;
    1523              : 
    1524              :       /* We don't need or want the attribute comparison.  */
    1525         9317 :       goto check_alias;
    1526              : 
    1527      1561750 :     case TEMPLATE_TEMPLATE_PARM:
    1528      1561750 :     case BOUND_TEMPLATE_TEMPLATE_PARM:
    1529      1561750 :       if (!comp_template_parms_position (t1, t2))
    1530              :         return false;
    1531      1262858 :       if (!comp_template_parms
    1532      2525716 :           (DECL_TEMPLATE_PARMS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (t1)),
    1533      3577128 :            DECL_TEMPLATE_PARMS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (t2))))
    1534              :         return false;
    1535       875915 :       if (TREE_CODE (t1) == TEMPLATE_TEMPLATE_PARM)
    1536              :         break;
    1537              :       /* Don't check inheritance.  */
    1538              :       strict = COMPARE_STRICT;
    1539              :       /* Fall through.  */
    1540              : 
    1541   4366309857 :     case RECORD_TYPE:
    1542   4366309857 :     case UNION_TYPE:
    1543   7668934442 :       if (TYPE_TEMPLATE_INFO (t1) && TYPE_TEMPLATE_INFO (t2)
    1544   2735012660 :           && (TYPE_TI_TEMPLATE (t1) == TYPE_TI_TEMPLATE (t2)
    1545   1939451748 :               || TREE_CODE (t1) == BOUND_TEMPLATE_TEMPLATE_PARM)
    1546   5161937596 :           && comp_template_args (TYPE_TI_ARGS (t1), TYPE_TI_ARGS (t2)))
    1547              :         break;
    1548              : 
    1549   4307248303 :       if ((strict & COMPARE_BASE) && DERIVED_FROM_P (t1, t2))
    1550              :         break;
    1551   4307248269 :       else if ((strict & COMPARE_DERIVED) && DERIVED_FROM_P (t2, t1))
    1552              :         break;
    1553              : 
    1554              :       return false;
    1555              : 
    1556        52334 :     case OFFSET_TYPE:
    1557        52334 :       if (!comptypes (TYPE_OFFSET_BASETYPE (t1), TYPE_OFFSET_BASETYPE (t2),
    1558              :                       strict & ~COMPARE_REDECLARATION))
    1559              :         return false;
    1560        48421 :       if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
    1561              :         return false;
    1562              :       break;
    1563              : 
    1564   1365017651 :     case REFERENCE_TYPE:
    1565   1365017651 :       if (TYPE_REF_IS_RVALUE (t1) != TYPE_REF_IS_RVALUE (t2))
    1566              :         return false;
    1567              :       /* fall through to checks for pointer types */
    1568   1696806161 :       gcc_fallthrough ();
    1569              : 
    1570   1696806161 :     case POINTER_TYPE:
    1571   1696806161 :       if (TYPE_MODE (t1) != TYPE_MODE (t2)
    1572   1696806161 :           || !same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
    1573   1551968399 :         return false;
    1574              :       break;
    1575              : 
    1576      5544376 :     case FUNCTION_TYPE:
    1577      5544376 :       if (TYPE_NO_NAMED_ARGS_STDARG_P (t1) != TYPE_NO_NAMED_ARGS_STDARG_P (t2))
    1578              :         return false;
    1579              :       /* FALLTHRU */
    1580     12674349 :     case METHOD_TYPE:
    1581              :       /* Exception specs and memfn_rquals were checked above.  */
    1582     12674349 :       if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
    1583              :         return false;
    1584     12024818 :       if (!compparms (TYPE_ARG_TYPES (t1), TYPE_ARG_TYPES (t2)))
    1585              :         return false;
    1586              :       break;
    1587              : 
    1588      1786382 :     case ARRAY_TYPE:
    1589              :       /* Target types must match incl. qualifiers.  */
    1590      1786382 :       if (!comp_array_types (t1, t2, ((strict & COMPARE_REDECLARATION)
    1591      1786382 :                                       ? bounds_either : bounds_none),
    1592              :                              /*strict=*/true))
    1593              :         return false;
    1594              :       break;
    1595              : 
    1596   1897314458 :     case TEMPLATE_TYPE_PARM:
    1597              :       /* If T1 and T2 don't have the same relative position in their
    1598              :          template parameters set, they can't be equal.  */
    1599   1897314458 :       if (!comp_template_parms_position (t1, t2))
    1600              :         return false;
    1601              :       /* If T1 and T2 don't represent the same class template deduction,
    1602              :          they aren't equal.  */
    1603   1234504324 :       if (!cp_tree_equal (CLASS_PLACEHOLDER_TEMPLATE (t1),
    1604    617252162 :                           CLASS_PLACEHOLDER_TEMPLATE (t2)))
    1605              :         return false;
    1606              :       /* Constrained 'auto's are distinct from parms that don't have the same
    1607              :          constraints.  */
    1608    583739438 :       if (!equivalent_placeholder_constraints (t1, t2))
    1609              :         return false;
    1610              :       break;
    1611              : 
    1612    289646423 :     case TYPENAME_TYPE:
    1613    579292846 :       if (!cp_tree_equal (TYPENAME_TYPE_FULLNAME (t1),
    1614    289646423 :                           TYPENAME_TYPE_FULLNAME (t2)))
    1615              :         return false;
    1616              :       /* Qualifiers don't matter on scopes.  */
    1617    253826817 :       if (!same_type_ignoring_top_level_qualifiers_p (TYPE_CONTEXT (t1),
    1618    253826817 :                                                       TYPE_CONTEXT (t2)))
    1619              :         return false;
    1620              :       break;
    1621              : 
    1622        27275 :     case UNBOUND_CLASS_TEMPLATE:
    1623        27275 :       if (!cp_tree_equal (TYPE_IDENTIFIER (t1), TYPE_IDENTIFIER (t2)))
    1624              :         return false;
    1625        27275 :       if (!same_type_p (TYPE_CONTEXT (t1), TYPE_CONTEXT (t2)))
    1626              :         return false;
    1627              :       break;
    1628              : 
    1629      2138437 :     case COMPLEX_TYPE:
    1630      2138437 :       if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
    1631              :         return false;
    1632              :       break;
    1633              : 
    1634     12722170 :     case VECTOR_TYPE:
    1635     12722170 :       if (gnu_vector_type_p (t1) != gnu_vector_type_p (t2)
    1636     23755004 :           || maybe_ne (TYPE_VECTOR_SUBPARTS (t1), TYPE_VECTOR_SUBPARTS (t2))
    1637     23811409 :           || !same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
    1638      1689336 :         return false;
    1639              :       break;
    1640              : 
    1641      7420152 :     case TYPE_PACK_EXPANSION:
    1642      7420152 :       return (same_type_p (PACK_EXPANSION_PATTERN (t1),
    1643              :                            PACK_EXPANSION_PATTERN (t2))
    1644     14680104 :               && comp_template_args (PACK_EXPANSION_EXTRA_ARGS (t1),
    1645      7259952 :                                      PACK_EXPANSION_EXTRA_ARGS (t2)));
    1646              : 
    1647           34 :     case PACK_INDEX_TYPE:
    1648           34 :       return (cp_tree_equal (PACK_INDEX_PACK (t1),
    1649           34 :                              PACK_INDEX_PACK (t2))
    1650           40 :               && cp_tree_equal (PACK_INDEX_INDEX (t1),
    1651            6 :                                 PACK_INDEX_INDEX (t2)));
    1652              : 
    1653     30328135 :     case DECLTYPE_TYPE:
    1654     60656270 :       if (DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t1)
    1655     30328135 :           != DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t2))
    1656              :         return false;
    1657     30288817 :       if (DECLTYPE_FOR_LAMBDA_CAPTURE (t1) != DECLTYPE_FOR_LAMBDA_CAPTURE (t2))
    1658              :         return false;
    1659     30288817 :       if (DECLTYPE_FOR_LAMBDA_PROXY (t1) != DECLTYPE_FOR_LAMBDA_PROXY (t2))
    1660              :         return false;
    1661     30288817 :       if (!cp_tree_equal (DECLTYPE_TYPE_EXPR (t1), DECLTYPE_TYPE_EXPR (t2)))
    1662              :         return false;
    1663              :       break;
    1664              : 
    1665       727188 :     case TRAIT_TYPE:
    1666       727188 :       if (TRAIT_TYPE_KIND (t1) != TRAIT_TYPE_KIND (t2))
    1667              :         return false;
    1668         1458 :       if (!cp_tree_equal (TRAIT_TYPE_TYPE1 (t1), TRAIT_TYPE_TYPE1 (t2))
    1669         2916 :           || !cp_tree_equal (TRAIT_TYPE_TYPE2 (t1), TRAIT_TYPE_TYPE2 (t2)))
    1670            0 :         return false;
    1671              :       break;
    1672              : 
    1673            3 :     case TYPEOF_TYPE:
    1674            3 :       if (!cp_tree_equal (TYPEOF_TYPE_EXPR (t1), TYPEOF_TYPE_EXPR (t2)))
    1675              :         return false;
    1676              :       break;
    1677              : 
    1678              :     default:
    1679              :       return false;
    1680              :     }
    1681              : 
    1682              :   /* If we get here, we know that from a target independent POV the
    1683              :      types are the same.  Make sure the target attributes are also
    1684              :      the same.  */
    1685    813228872 :   if (!comp_type_attributes (t1, t2))
    1686              :     return false;
    1687              : 
    1688    813227685 :  check_alias:
    1689   1270898760 :   if (comparing_dependent_aliases
    1690   1270898760 :       && (typedef_variant_p (t1) || typedef_variant_p (t2)))
    1691              :     {
    1692      4243538 :       tree dep1 = dependent_opaque_alias_p (t1) ? t1 : NULL_TREE;
    1693      4243538 :       tree dep2 = dependent_opaque_alias_p (t2) ? t2 : NULL_TREE;
    1694      4243538 :       if ((dep1 || dep2)
    1695      4243538 :           && (!(dep1 && dep2)
    1696            0 :               || !comp_type_attributes (DECL_ATTRIBUTES (TYPE_NAME (dep1)),
    1697            0 :                                         DECL_ATTRIBUTES (TYPE_NAME (dep2)))))
    1698           32 :         return false;
    1699              : 
    1700              :       /* Don't treat an alias template specialization with dependent
    1701              :          arguments as equivalent to its underlying type when used as a
    1702              :          template argument; we need them to be distinct so that we
    1703              :          substitute into the specialization arguments at instantiation
    1704              :          time.  And aliases can't be equivalent without being ==, so
    1705              :          we don't need to look any deeper.  */
    1706      4243506 :       ++processing_template_decl;
    1707      4243506 :       dep1 = dependent_alias_template_spec_p (t1, nt_transparent);
    1708      4243506 :       dep2 = dependent_alias_template_spec_p (t2, nt_transparent);
    1709      4243506 :       --processing_template_decl;
    1710      4243506 :       if ((dep1 || dep2) && dep1 != dep2)
    1711              :         return false;
    1712              :     }
    1713              : 
    1714              :   return true;
    1715              : }
    1716              : 
    1717              : /* C++ implementation of compatible_types_for_indirection_note_p.  */
    1718              : 
    1719              : bool
    1720         1611 : compatible_types_for_indirection_note_p (tree type1, tree type2)
    1721              : {
    1722         1611 :   return same_type_p (type1, type2);
    1723              : }
    1724              : 
    1725              : /* Return true if T1 and T2 are related as allowed by STRICT.  STRICT
    1726              :    is a bitwise-or of the COMPARE_* flags.  */
    1727              : 
    1728              : bool
    1729  24081250411 : comptypes (tree t1, tree t2, int strict)
    1730              : {
    1731  24081250411 :   gcc_checking_assert (t1 && t2);
    1732              : 
    1733              :   /* TYPE_ARGUMENT_PACKS are not really types.  */
    1734  24081250411 :   gcc_checking_assert (TREE_CODE (t1) != TYPE_ARGUMENT_PACK
    1735              :                        && TREE_CODE (t2) != TYPE_ARGUMENT_PACK);
    1736              : 
    1737  24081250411 :   if (t1 == t2)
    1738              :     return true;
    1739              : 
    1740              :   /* Suppress errors caused by previously reported errors.  */
    1741  15940937822 :   if (t1 == error_mark_node || t2 == error_mark_node)
    1742              :     return false;
    1743              : 
    1744  15940937660 :   if (strict == COMPARE_STRICT)
    1745              :     {
    1746  14337186257 :       if (TYPE_STRUCTURAL_EQUALITY_P (t1) || TYPE_STRUCTURAL_EQUALITY_P (t2))
    1747              :         /* At least one of the types requires structural equality, so
    1748              :            perform a deep check. */
    1749   1687759976 :         return structural_comptypes (t1, t2, strict);
    1750              : 
    1751  12649426281 :       if (flag_checking && param_use_canonical_types)
    1752              :         {
    1753  12649425278 :           bool result = structural_comptypes (t1, t2, strict);
    1754              : 
    1755  12649425278 :           if (result && TYPE_CANONICAL (t1) != TYPE_CANONICAL (t2))
    1756              :             /* The two types are structurally equivalent, but their
    1757              :                canonical types were different. This is a failure of the
    1758              :                canonical type propagation code.*/
    1759            0 :             internal_error
    1760            0 :               ("canonical types differ for identical types %qT and %qT",
    1761              :                t1, t2);
    1762  12649425278 :           else if (!result && TYPE_CANONICAL (t1) == TYPE_CANONICAL (t2))
    1763              :             /* Two types are structurally different, but the canonical
    1764              :                types are the same. This means we were over-eager in
    1765              :                assigning canonical types. */
    1766            0 :             internal_error
    1767            0 :               ("same canonical type node for different types %qT and %qT",
    1768              :                t1, t2);
    1769              : 
    1770              :           return result;
    1771              :         }
    1772         1003 :       if (!flag_checking && param_use_canonical_types)
    1773         1003 :         return TYPE_CANONICAL (t1) == TYPE_CANONICAL (t2);
    1774              :       else
    1775            0 :         return structural_comptypes (t1, t2, strict);
    1776              :     }
    1777   1603751403 :   else if (strict == COMPARE_STRUCTURAL)
    1778   1540755934 :     return structural_comptypes (t1, t2, COMPARE_STRICT);
    1779              :   else
    1780     62995469 :     return structural_comptypes (t1, t2, strict);
    1781              : }
    1782              : 
    1783              : /* Returns nonzero iff TYPE1 and TYPE2 are the same type, ignoring
    1784              :    top-level qualifiers.  */
    1785              : 
    1786              : bool
    1787   4047443786 : same_type_ignoring_top_level_qualifiers_p (tree type1, tree type2)
    1788              : {
    1789   4047443786 :   if (type1 == error_mark_node || type2 == error_mark_node)
    1790              :     return false;
    1791   4047443067 :   if (type1 == type2)
    1792              :     return true;
    1793              : 
    1794   2284337137 :   type1 = cp_build_qualified_type (type1, TYPE_UNQUALIFIED);
    1795   2284337137 :   type2 = cp_build_qualified_type (type2, TYPE_UNQUALIFIED);
    1796   2284337137 :   return same_type_p (type1, type2);
    1797              : }
    1798              : 
    1799              : /* Returns nonzero iff TYPE1 and TYPE2 are similar, as per [conv.qual].  */
    1800              : 
    1801              : bool
    1802    339361363 : similar_type_p (tree type1, tree type2)
    1803              : {
    1804    339361363 :   if (type1 == error_mark_node || type2 == error_mark_node)
    1805              :     return false;
    1806              : 
    1807              :   /* Informally, two types are similar if, ignoring top-level cv-qualification:
    1808              :      * they are the same type; or
    1809              :      * they are both pointers, and the pointed-to types are similar; or
    1810              :      * they are both pointers to member of the same class, and the types of
    1811              :        the pointed-to members are similar; or
    1812              :      * they are both arrays of the same size or both arrays of unknown bound,
    1813              :        and the array element types are similar.  */
    1814              : 
    1815    339361363 :   if (same_type_ignoring_top_level_qualifiers_p (type1, type2))
    1816              :     return true;
    1817              : 
    1818    147105434 :   if ((TYPE_PTR_P (type1) && TYPE_PTR_P (type2))
    1819    146883638 :       || (TYPE_PTRDATAMEM_P (type1) && TYPE_PTRDATAMEM_P (type2))
    1820    146882702 :       || (TREE_CODE (type1) == ARRAY_TYPE && TREE_CODE (type2) == ARRAY_TYPE))
    1821       224776 :     return comp_ptr_ttypes_const (type1, type2, bounds_either);
    1822              : 
    1823              :   return false;
    1824              : }
    1825              : 
    1826              : /* Helper function for layout_compatible_type_p and
    1827              :    is_corresponding_member_aggr.  Advance to next members (NULL if
    1828              :    no further ones) and return true if those members are still part of
    1829              :    the common initial sequence.  */
    1830              : 
    1831              : bool
    1832         2210 : next_common_initial_sequence (tree &memb1, tree &memb2)
    1833              : {
    1834         2733 :   while (memb1)
    1835              :     {
    1836         2772 :       if (TREE_CODE (memb1) != FIELD_DECL
    1837         2313 :           || (DECL_FIELD_IS_BASE (memb1) && is_empty_field (memb1)))
    1838              :         {
    1839          459 :           memb1 = DECL_CHAIN (memb1);
    1840          459 :           continue;
    1841              :         }
    1842         1854 :       if (DECL_FIELD_IS_BASE (memb1))
    1843              :         {
    1844           64 :           memb1 = TYPE_FIELDS (TREE_TYPE (memb1));
    1845           64 :           continue;
    1846              :         }
    1847              :       break;
    1848              :     }
    1849         2694 :   while (memb2)
    1850              :     {
    1851         2730 :       if (TREE_CODE (memb2) != FIELD_DECL
    1852         2274 :           || (DECL_FIELD_IS_BASE (memb2) && is_empty_field (memb2)))
    1853              :         {
    1854          456 :           memb2 = DECL_CHAIN (memb2);
    1855          456 :           continue;
    1856              :         }
    1857         1818 :       if (DECL_FIELD_IS_BASE (memb2))
    1858              :         {
    1859           28 :           memb2 = TYPE_FIELDS (TREE_TYPE (memb2));
    1860           28 :           continue;
    1861              :         }
    1862              :       break;
    1863              :     }
    1864         2210 :   if (memb1 == NULL_TREE && memb2 == NULL_TREE)
    1865              :     return true;
    1866         1790 :   if (memb1 == NULL_TREE || memb2 == NULL_TREE)
    1867              :     return false;
    1868         1790 :   if (DECL_BIT_FIELD_TYPE (memb1))
    1869              :     {
    1870          165 :       if (!DECL_BIT_FIELD_TYPE (memb2))
    1871              :         return false;
    1872           66 :       if (!layout_compatible_type_p (DECL_BIT_FIELD_TYPE (memb1),
    1873           66 :                                      DECL_BIT_FIELD_TYPE (memb2)))
    1874              :         return false;
    1875           66 :       if (TYPE_PRECISION (TREE_TYPE (memb1))
    1876           66 :           != TYPE_PRECISION (TREE_TYPE (memb2)))
    1877              :         return false;
    1878              :     }
    1879         1625 :   else if (DECL_BIT_FIELD_TYPE (memb2))
    1880              :     return false;
    1881         1598 :   else if (!layout_compatible_type_p (TREE_TYPE (memb1), TREE_TYPE (memb2)))
    1882              :     return false;
    1883         1598 :   if ((!lookup_attribute ("no_unique_address", DECL_ATTRIBUTES (memb1)))
    1884         1598 :       != !lookup_attribute ("no_unique_address", DECL_ATTRIBUTES (memb2)))
    1885              :     return false;
    1886         1571 :   if (DECL_ALIGN (memb1) != DECL_ALIGN (memb2))
    1887              :     return false;
    1888         1512 :   if (!tree_int_cst_equal (bit_position (memb1), bit_position (memb2)))
    1889              :     return false;
    1890              :   return true;
    1891              : }
    1892              : 
    1893              : /* Return true if TYPE1 and TYPE2 are layout-compatible types.  */
    1894              : 
    1895              : bool
    1896         2765 : layout_compatible_type_p (tree type1, tree type2, bool explain/*=false*/)
    1897              : {
    1898         2765 :   if (type1 == error_mark_node || type2 == error_mark_node)
    1899              :     return false;
    1900         2765 :   if (type1 == type2)
    1901              :     return true;
    1902              : 
    1903         1351 :   type1 = cp_build_qualified_type (type1, TYPE_UNQUALIFIED);
    1904         1351 :   type2 = cp_build_qualified_type (type2, TYPE_UNQUALIFIED);
    1905         1351 :   if (same_type_p (type1, type2))
    1906              :     return true;
    1907              : 
    1908          646 :   if (TREE_CODE (type1) != TREE_CODE (type2)
    1909          602 :       || (TREE_CODE (type1) != ENUMERAL_TYPE
    1910          564 :           && !CLASS_TYPE_P (type1))
    1911         1099 :       || (TREE_CODE (type2) != ENUMERAL_TYPE
    1912          415 :           && !CLASS_TYPE_P (type2)))
    1913              :     {
    1914          193 :       if (explain)
    1915            6 :         inform (input_location, "%q#T and %q#T are not both the same type, "
    1916              :                 "layout-compatible enumerations, or "
    1917              :                 "layout-compatible standard-layout class types",
    1918              :                 type1, type2);
    1919          193 :       return false;
    1920              :     }
    1921              : 
    1922          453 :   if (!std_layout_type_p (type1))
    1923              :     {
    1924           16 :       if (explain)
    1925            3 :         inform (location_of (type1),
    1926              :                 "%qT is not a standard-layout type", type1);
    1927           16 :       return false;
    1928              :     }
    1929          437 :   if (!std_layout_type_p (type2))
    1930              :     {
    1931            0 :       if (explain)
    1932            0 :         inform (location_of (type2),
    1933              :                 "%qT is not a standard-layout type", type2);
    1934            0 :       return false;
    1935              :     }
    1936              : 
    1937          437 :   if (TREE_CODE (type1) == ENUMERAL_TYPE)
    1938              :     {
    1939           38 :       tree underlying1 = finish_underlying_type (type1);
    1940           38 :       tree underlying2 = finish_underlying_type (type2);
    1941           38 :       if (!same_type_p (underlying1, underlying2))
    1942              :         {
    1943           25 :           if (explain)
    1944              :             {
    1945            3 :               inform (location_of (type1),
    1946              :                       "the underlying type of %qT is %qT, but",
    1947              :                       type1, underlying1);
    1948            3 :               inform (location_of (type2),
    1949              :                       "the underlying type of %qT is %qT",
    1950              :                       type2, underlying2);
    1951              :             }
    1952           25 :           return false;
    1953              :         }
    1954              :     }
    1955          399 :   else if (TREE_CODE (type1) == RECORD_TYPE)
    1956              :     {
    1957          315 :       tree field1 = TYPE_FIELDS (type1);
    1958          315 :       tree field2 = TYPE_FIELDS (type2);
    1959         1179 :       while (1)
    1960              :         {
    1961          747 :           if (!next_common_initial_sequence (field1, field2))
    1962              :             {
    1963           27 :               if (explain)
    1964              :                 {
    1965            6 :                   if (field1 && field2)
    1966              :                     {
    1967            6 :                       inform (DECL_SOURCE_LOCATION (field1),
    1968              :                               "%qD and %qD do not correspond",
    1969              :                               field1, field2);
    1970            6 :                       inform (DECL_SOURCE_LOCATION (field2),
    1971              :                               "%qD declared here", field2);
    1972              :                     }
    1973            0 :                   else if (field1)
    1974            0 :                     inform (DECL_SOURCE_LOCATION (field1),
    1975              :                             "%qT has no member corresponding to %qD",
    1976              :                             type2, field1);
    1977            0 :                   else if (field2)
    1978            0 :                     inform (DECL_SOURCE_LOCATION (field2),
    1979              :                             "%qT has no member corresponding to %qD",
    1980              :                             type1, field2);
    1981              :                 }
    1982           27 :               return false;
    1983              :             }
    1984          720 :           if (field1 == NULL_TREE)
    1985              :             break;
    1986          432 :           field1 = DECL_CHAIN (field1);
    1987          432 :           field2 = DECL_CHAIN (field2);
    1988              :         }
    1989              :     }
    1990           84 :   else if (TREE_CODE (type1) == UNION_TYPE)
    1991              :     {
    1992              :       /* The standard says:
    1993              :          "Two standard-layout unions are layout-compatible if they have
    1994              :          the same number of non-static data members and corresponding
    1995              :          non-static data members (in any order) have layout-compatible
    1996              :          types."
    1997              :          but the code anticipates that bitfield vs. non-bitfield,
    1998              :          different bitfield widths or presence/absence of
    1999              :          [[no_unique_address]] should be checked as well.  */
    2000           84 :       tree field1 = TYPE_FIELDS (type1);
    2001           84 :       tree field2 = TYPE_FIELDS (type2);
    2002           84 :       auto_vec<tree, 16> vec;
    2003           84 :       unsigned int count = 0;
    2004          378 :       for (; field1; field1 = DECL_CHAIN (field1))
    2005          294 :         if (TREE_CODE (field1) == FIELD_DECL)
    2006          195 :           count++;
    2007          372 :       for (; field2; field2 = DECL_CHAIN (field2))
    2008          288 :         if (TREE_CODE (field2) == FIELD_DECL)
    2009          189 :           vec.safe_push (field2);
    2010              : 
    2011              :       /* Discussions on core lean towards treating multiple union fields
    2012              :          of the same type as the same field, so this might need changing
    2013              :          in the future.  */
    2014          168 :       if (count != vec.length ())
    2015              :         {
    2016            6 :           if (explain)
    2017              :             {
    2018            3 :               inform_n (location_of (type1), count,
    2019              :                         "%qT has %u field, but",
    2020              :                         "%qT has %u fields, but",
    2021              :                         type1, count);
    2022            6 :               inform_n (location_of (type2), vec.length (),
    2023              :                         "%qT has %u field",
    2024              :                         "%qT has %u fields",
    2025              :                         type2, vec.length ());
    2026              :             }
    2027            6 :           return false;
    2028              :         }
    2029              : 
    2030          324 :       for (field1 = TYPE_FIELDS (type1); field1; field1 = DECL_CHAIN (field1))
    2031              :         {
    2032          258 :           if (TREE_CODE (field1) != FIELD_DECL)
    2033           81 :             continue;
    2034          177 :           unsigned int j;
    2035          177 :           tree t1 = DECL_BIT_FIELD_TYPE (field1);
    2036          177 :           if (t1 == NULL_TREE)
    2037          174 :             t1 = TREE_TYPE (field1);
    2038          297 :           FOR_EACH_VEC_ELT (vec, j, field2)
    2039              :             {
    2040          285 :               tree t2 = DECL_BIT_FIELD_TYPE (field2);
    2041          285 :               if (t2 == NULL_TREE)
    2042          273 :                 t2 = TREE_TYPE (field2);
    2043          285 :               if (DECL_BIT_FIELD_TYPE (field1))
    2044              :                 {
    2045            6 :                   if (!DECL_BIT_FIELD_TYPE (field2))
    2046            0 :                     continue;
    2047            6 :                   if (TYPE_PRECISION (TREE_TYPE (field1))
    2048            6 :                       != TYPE_PRECISION (TREE_TYPE (field2)))
    2049            6 :                     continue;
    2050              :                 }
    2051          279 :               else if (DECL_BIT_FIELD_TYPE (field2))
    2052            6 :                 continue;
    2053          273 :               if (!layout_compatible_type_p (t1, t2))
    2054          108 :                 continue;
    2055          165 :               if ((!lookup_attribute ("no_unique_address",
    2056          165 :                                       DECL_ATTRIBUTES (field1)))
    2057          165 :                   != !lookup_attribute ("no_unique_address",
    2058          165 :                                         DECL_ATTRIBUTES (field2)))
    2059            0 :                 continue;
    2060              :               break;
    2061              :             }
    2062          354 :           if (j == vec.length ())
    2063              :             {
    2064           12 :               if (explain)
    2065              :                 {
    2066            3 :                   inform (DECL_SOURCE_LOCATION (field1),
    2067              :                           "%qT has no member corresponding to %qD",
    2068              :                           type2, field1);
    2069            3 :                   inform (location_of (type2), "%qT declared here", type2);
    2070              :                 }
    2071           12 :               return false;
    2072              :             }
    2073          165 :           vec.unordered_remove (j);
    2074              :         }
    2075           84 :     }
    2076              :   else
    2077            0 :     gcc_unreachable ();
    2078              : 
    2079              :   return true;
    2080              : }
    2081              : 
    2082              : /* Returns 1 if TYPE1 is at least as qualified as TYPE2.  */
    2083              : 
    2084              : bool
    2085    238564961 : at_least_as_qualified_p (const_tree type1, const_tree type2)
    2086              : {
    2087    238564961 :   int q1 = cp_type_quals (type1);
    2088    238564961 :   int q2 = cp_type_quals (type2);
    2089              : 
    2090              :   /* All qualifiers for TYPE2 must also appear in TYPE1.  */
    2091    238564961 :   return (q1 & q2) == q2;
    2092              : }
    2093              : 
    2094              : /* Returns 1 if TYPE1 is more cv-qualified than TYPE2, -1 if TYPE2 is
    2095              :    more cv-qualified that TYPE1, and 0 otherwise.  */
    2096              : 
    2097              : int
    2098     14340292 : comp_cv_qualification (int q1, int q2)
    2099              : {
    2100     14340292 :   if (q1 == q2)
    2101              :     return 0;
    2102              : 
    2103      3480797 :   if ((q1 & q2) == q2)
    2104              :     return 1;
    2105       349463 :   else if ((q1 & q2) == q1)
    2106       348878 :     return -1;
    2107              : 
    2108              :   return 0;
    2109              : }
    2110              : 
    2111              : int
    2112            0 : comp_cv_qualification (const_tree type1, const_tree type2)
    2113              : {
    2114            0 :   int q1 = cp_type_quals (type1);
    2115            0 :   int q2 = cp_type_quals (type2);
    2116            0 :   return comp_cv_qualification (q1, q2);
    2117              : }
    2118              : 
    2119              : /* Returns 1 if the cv-qualification signature of TYPE1 is a proper
    2120              :    subset of the cv-qualification signature of TYPE2, and the types
    2121              :    are similar.  Returns -1 if the other way 'round, and 0 otherwise.  */
    2122              : 
    2123              : int
    2124          351 : comp_cv_qual_signature (tree type1, tree type2)
    2125              : {
    2126          351 :   if (comp_ptr_ttypes_real (type2, type1, -1))
    2127              :     return 1;
    2128          277 :   else if (comp_ptr_ttypes_real (type1, type2, -1))
    2129              :     return -1;
    2130              :   else
    2131          265 :     return 0;
    2132              : }
    2133              : 
    2134              : /* Subroutines of `comptypes'.  */
    2135              : 
    2136              : /* Return true if two parameter type lists PARMS1 and PARMS2 are
    2137              :    equivalent in the sense that functions with those parameter types
    2138              :    can have equivalent types.  The two lists must be equivalent,
    2139              :    element by element.  */
    2140              : 
    2141              : bool
    2142   1030988922 : compparms (const_tree parms1, const_tree parms2)
    2143              : {
    2144   1030988922 :   const_tree t1, t2;
    2145              : 
    2146              :   /* An unspecified parmlist matches any specified parmlist
    2147              :      whose argument types don't need default promotions.  */
    2148              : 
    2149   1030988922 :   for (t1 = parms1, t2 = parms2;
    2150   1654029547 :        t1 || t2;
    2151    623040625 :        t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2))
    2152              :     {
    2153              :       /* If one parmlist is shorter than the other,
    2154              :          they fail to match.  */
    2155   1546742533 :       if (!t1 || !t2)
    2156              :         return false;
    2157   1546168525 :       if (!same_type_p (TREE_VALUE (t1), TREE_VALUE (t2)))
    2158              :         return false;
    2159              :     }
    2160              :   return true;
    2161              : }
    2162              : 
    2163              : 
    2164              : /* Process a sizeof or alignof expression where the operand is a type.
    2165              :    STD_ALIGNOF indicates whether an alignof has C++11 (minimum alignment)
    2166              :    or GNU (preferred alignment) semantics; it is ignored if OP is
    2167              :    SIZEOF_EXPR.  */
    2168              : 
    2169              : tree
    2170     27424709 : cxx_sizeof_or_alignof_type (location_t loc, tree type, enum tree_code op,
    2171              :                             bool std_alignof, bool complain)
    2172              : {
    2173     27424709 :   gcc_assert (op == SIZEOF_EXPR || op == ALIGNOF_EXPR);
    2174     27424709 :   if (type == error_mark_node)
    2175              :     return error_mark_node;
    2176              : 
    2177     27424707 :   type = non_reference (type);
    2178     27424707 :   if (TREE_CODE (type) == METHOD_TYPE)
    2179              :     {
    2180            0 :       if (complain)
    2181              :         {
    2182            0 :           pedwarn (loc, OPT_Wpointer_arith,
    2183              :                    "invalid application of %qs to a member function",
    2184            0 :                    OVL_OP_INFO (false, op)->name);
    2185            0 :           return size_one_node;
    2186              :         }
    2187              :       else
    2188            0 :         return error_mark_node;
    2189              :     }
    2190     27424707 :   else if (VOID_TYPE_P (type) && std_alignof)
    2191              :     {
    2192           12 :       if (complain)
    2193           12 :         error_at (loc, "invalid application of %qs to a void type",
    2194           12 :                   OVL_OP_INFO (false, op)->name);
    2195           12 :       return error_mark_node;
    2196              :     }
    2197              : 
    2198     27424695 :   bool dependent_p = dependent_type_p (type);
    2199     27424695 :   if (!dependent_p)
    2200              :     {
    2201     22619976 :       complete_type (type);
    2202     22619976 :       if (!COMPLETE_TYPE_P (type))
    2203              :         /* Call this here because the incompleteness diagnostic comes from
    2204              :            c_sizeof_or_alignof_type instead of
    2205              :            complete_type_or_maybe_complain.  */
    2206          204 :         note_failed_type_completion (type, complain);
    2207              :     }
    2208     22619976 :   if (dependent_p
    2209              :       /* VLA types will have a non-constant size.  In the body of an
    2210              :          uninstantiated template, we don't need to try to compute the
    2211              :          value, because the sizeof expression is not an integral
    2212              :          constant expression in that case.  And, if we do try to
    2213              :          compute the value, we'll likely end up with SAVE_EXPRs, which
    2214              :          the template substitution machinery does not expect to see.  */
    2215     22619976 :       || (processing_template_decl
    2216      2021571 :           && COMPLETE_TYPE_P (type)
    2217      2021565 :           && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST))
    2218              :     {
    2219      4804719 :       tree value = build_min (op, size_type_node, type);
    2220      4804719 :       TREE_READONLY (value) = 1;
    2221      4804719 :       if (op == ALIGNOF_EXPR && std_alignof)
    2222       560448 :         ALIGNOF_EXPR_STD_P (value) = true;
    2223      4804719 :       SET_EXPR_LOCATION (value, loc);
    2224      4804719 :       return value;
    2225              :     }
    2226              : 
    2227     22619976 :   return c_sizeof_or_alignof_type (loc, complete_type (type),
    2228              :                                    op == SIZEOF_EXPR, std_alignof,
    2229     22619976 :                                    complain & (tf_warning_or_error));
    2230              : }
    2231              : 
    2232              : /* Return the size of the type, without producing any warnings for
    2233              :    types whose size cannot be taken.  This routine should be used only
    2234              :    in some other routine that has already produced a diagnostic about
    2235              :    using the size of such a type.  */
    2236              : tree
    2237      2715027 : cxx_sizeof_nowarn (tree type)
    2238              : {
    2239      2715027 :   if (TREE_CODE (type) == FUNCTION_TYPE
    2240      2715027 :       || VOID_TYPE_P (type)
    2241      2714945 :       || TREE_CODE (type) == ERROR_MARK)
    2242           82 :     return size_one_node;
    2243      2714945 :   else if (!COMPLETE_TYPE_P (type))
    2244           25 :     return size_zero_node;
    2245              :   else
    2246      2714920 :     return cxx_sizeof_or_alignof_type (input_location, type,
    2247      2714920 :                                        SIZEOF_EXPR, false, false);
    2248              : }
    2249              : 
    2250              : /* Process a sizeof expression where the operand is an expression.  */
    2251              : 
    2252              : static tree
    2253      1210194 : cxx_sizeof_expr (location_t loc, tree e, tsubst_flags_t complain)
    2254              : {
    2255      1210194 :   if (e == error_mark_node)
    2256              :     return error_mark_node;
    2257              : 
    2258      1209459 :   if (instantiation_dependent_uneval_expression_p (e))
    2259              :     {
    2260       347602 :       e = build_min (SIZEOF_EXPR, size_type_node, e);
    2261       347602 :       TREE_SIDE_EFFECTS (e) = 0;
    2262       347602 :       TREE_READONLY (e) = 1;
    2263       347602 :       SET_EXPR_LOCATION (e, loc);
    2264              : 
    2265       347602 :       return e;
    2266              :     }
    2267              : 
    2268       861857 :   location_t e_loc = cp_expr_loc_or_loc (e, loc);
    2269       861857 :   STRIP_ANY_LOCATION_WRAPPER (e);
    2270              : 
    2271       861857 :   if (TREE_CODE (e) == PARM_DECL
    2272        26151 :       && DECL_ARRAY_PARAMETER_P (e)
    2273       862234 :       && (complain & tf_warning))
    2274              :     {
    2275          120 :       auto_diagnostic_group d;
    2276          120 :       if (warning_at (e_loc, OPT_Wsizeof_array_argument,
    2277              :                       "%<sizeof%> on array function parameter %qE "
    2278          120 :                       "will return size of %qT", e, TREE_TYPE (e)))
    2279           24 :         inform (DECL_SOURCE_LOCATION (e), "declared here");
    2280          120 :     }
    2281              : 
    2282       861857 :   e = mark_type_use (e);
    2283              : 
    2284       861857 :   if (bitfield_p (e))
    2285              :     {
    2286           12 :       if (complain & tf_error)
    2287            6 :         error_at (e_loc,
    2288              :                   "invalid application of %<sizeof%> to a bit-field");
    2289              :       else
    2290            6 :         return error_mark_node;
    2291            6 :       e = char_type_node;
    2292              :     }
    2293       861845 :   else if (is_overloaded_fn (e))
    2294              :     {
    2295           33 :       if (complain & tf_error)
    2296           12 :         permerror (e_loc, "ISO C++ forbids applying %<sizeof%> to "
    2297              :                    "an expression of function type");
    2298              :       else
    2299           21 :         return error_mark_node;
    2300           12 :       e = char_type_node;
    2301              :     }
    2302       861812 :   else if (type_unknown_p (e))
    2303              :     {
    2304            0 :       if (complain & tf_error)
    2305            0 :         cxx_incomplete_type_error (e_loc, e, TREE_TYPE (e));
    2306              :       else
    2307            0 :         return error_mark_node;
    2308            0 :       e = char_type_node;
    2309              :     }
    2310              :   else
    2311       861812 :     e = TREE_TYPE (e);
    2312              : 
    2313       861830 :   return cxx_sizeof_or_alignof_type (loc, e, SIZEOF_EXPR, false,
    2314       861830 :                                      complain & tf_error);
    2315              : }
    2316              : 
    2317              : /* Implement the __alignof keyword: Return the minimum required
    2318              :    alignment of E, measured in bytes.  For VAR_DECL's and
    2319              :    FIELD_DECL's return DECL_ALIGN (which can be set from an
    2320              :    "aligned" __attribute__ specification).  STD_ALIGNOF acts
    2321              :    like in cxx_sizeof_or_alignof_type.  */
    2322              : 
    2323              : static tree
    2324       100249 : cxx_alignof_expr (location_t loc, tree e, bool std_alignof,
    2325              :                   tsubst_flags_t complain)
    2326              : {
    2327       100249 :   tree t;
    2328              : 
    2329       100249 :   if (e == error_mark_node)
    2330              :     return error_mark_node;
    2331              : 
    2332       100241 :   if (processing_template_decl)
    2333              :     {
    2334        18534 :       e = build_min (ALIGNOF_EXPR, size_type_node, e);
    2335        18534 :       TREE_SIDE_EFFECTS (e) = 0;
    2336        18534 :       TREE_READONLY (e) = 1;
    2337        18534 :       SET_EXPR_LOCATION (e, loc);
    2338        18534 :       ALIGNOF_EXPR_STD_P (e) = std_alignof;
    2339              : 
    2340        18534 :       return e;
    2341              :     }
    2342              : 
    2343        81707 :   location_t e_loc = cp_expr_loc_or_loc (e, loc);
    2344        81707 :   STRIP_ANY_LOCATION_WRAPPER (e);
    2345              : 
    2346        81707 :   e = mark_type_use (e);
    2347              : 
    2348        81707 :   if (!verify_type_context (loc, TCTX_ALIGNOF, TREE_TYPE (e),
    2349              :                             !(complain & tf_error)))
    2350              :     {
    2351            0 :       if (!(complain & tf_error))
    2352            0 :         return error_mark_node;
    2353            0 :       t = size_one_node;
    2354              :     }
    2355        81707 :   else if (VAR_P (e))
    2356        12270 :     t = size_int (DECL_ALIGN_UNIT (e));
    2357        69437 :   else if (bitfield_p (e))
    2358              :     {
    2359            6 :       if (complain & tf_error)
    2360            6 :         error_at (e_loc,
    2361              :                   "invalid application of %<__alignof%> to a bit-field");
    2362              :       else
    2363            0 :         return error_mark_node;
    2364            6 :       t = size_one_node;
    2365              :     }
    2366        69431 :   else if (TREE_CODE (e) == COMPONENT_REF
    2367        69431 :            && TREE_CODE (TREE_OPERAND (e, 1)) == FIELD_DECL)
    2368        37792 :     t = size_int (DECL_ALIGN_UNIT (TREE_OPERAND (e, 1)));
    2369        31639 :   else if (is_overloaded_fn (e))
    2370              :     {
    2371            6 :       if (complain & tf_error)
    2372            6 :         permerror (e_loc, "ISO C++ forbids applying %<__alignof%> to "
    2373              :                    "an expression of function type");
    2374              :       else
    2375            0 :         return error_mark_node;
    2376            6 :       if (TREE_CODE (e) == FUNCTION_DECL)
    2377            3 :         t = size_int (DECL_ALIGN_UNIT (e));
    2378              :       else
    2379            3 :         t = size_one_node;
    2380              :     }
    2381        31633 :   else if (type_unknown_p (e))
    2382              :     {
    2383            0 :       if (complain & tf_error)
    2384            0 :         cxx_incomplete_type_error (e_loc, e, TREE_TYPE (e));
    2385              :       else
    2386            0 :         return error_mark_node;
    2387            0 :       t = size_one_node;
    2388              :     }
    2389              :   else
    2390        31633 :     return cxx_sizeof_or_alignof_type (loc, TREE_TYPE (e),
    2391              :                                        ALIGNOF_EXPR, std_alignof,
    2392        31633 :                                        complain & tf_error);
    2393              : 
    2394        50074 :   return fold_convert_loc (loc, size_type_node, t);
    2395              : }
    2396              : 
    2397              : /* Process a sizeof or alignof expression E with code OP where the operand
    2398              :    is an expression. STD_ALIGNOF acts like in cxx_sizeof_or_alignof_type.  */
    2399              : 
    2400              : tree
    2401      1310443 : cxx_sizeof_or_alignof_expr (location_t loc, tree e, enum tree_code op,
    2402              :                             bool std_alignof, bool complain)
    2403              : {
    2404      1310443 :   gcc_assert (op == SIZEOF_EXPR || op == ALIGNOF_EXPR);
    2405      1310443 :   if (op == SIZEOF_EXPR)
    2406      1760928 :     return cxx_sizeof_expr (loc, e, complain? tf_warning_or_error : tf_none);
    2407              :   else
    2408       100276 :     return cxx_alignof_expr (loc, e, std_alignof,
    2409       100249 :                              complain? tf_warning_or_error : tf_none);
    2410              : }
    2411              : 
    2412              : /*  Build a representation of an expression 'alignas(E).'  Return the
    2413              :     folded integer value of E if it is an integral constant expression
    2414              :     that resolves to a valid alignment.  If E depends on a template
    2415              :     parameter, return a syntactic representation tree of kind
    2416              :     ALIGNOF_EXPR.  Otherwise, return an error_mark_node if the
    2417              :     expression is ill formed, or NULL_TREE if E is NULL_TREE.  */
    2418              : 
    2419              : tree
    2420       267120 : cxx_alignas_expr (tree e)
    2421              : {
    2422       267120 :   if (e == NULL_TREE || e == error_mark_node
    2423       534240 :       || (!TYPE_P (e) && !require_potential_rvalue_constant_expression (e)))
    2424            0 :     return e;
    2425              : 
    2426       267120 :   if (TYPE_P (e))
    2427              :     /* [dcl.align]/3:
    2428              : 
    2429              :            When the alignment-specifier is of the form
    2430              :            alignas(type-id), it shall have the same effect as
    2431              :            alignas(alignof(type-id)).  */
    2432              : 
    2433       140194 :     return cxx_sizeof_or_alignof_type (input_location,
    2434              :                                        e, ALIGNOF_EXPR,
    2435              :                                        /*std_alignof=*/true,
    2436       140194 :                                        /*complain=*/true);
    2437              : 
    2438              :   /* If we reach this point, it means the alignas expression if of
    2439              :      the form "alignas(assignment-expression)", so we should follow
    2440              :      what is stated by [dcl.align]/2.  */
    2441              : 
    2442       126926 :   if (value_dependent_expression_p (e))
    2443              :     /* Leave value-dependent expression alone for now. */
    2444              :     return e;
    2445              : 
    2446        65340 :   e = instantiate_non_dependent_expr (e);
    2447        65340 :   e = mark_rvalue_use (e);
    2448              : 
    2449              :   /* [dcl.align]/2 says:
    2450              : 
    2451              :          the assignment-expression shall be an integral constant
    2452              :          expression.  */
    2453              : 
    2454        65340 :   if (!INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (e)))
    2455              :     {
    2456           18 :       error ("%<alignas%> argument has non-integral type %qT", TREE_TYPE (e));
    2457           18 :       return error_mark_node;
    2458              :     }
    2459              : 
    2460        65322 :   return cxx_constant_value (e);
    2461              : }
    2462              : 
    2463              : 
    2464              : /* EXPR is being used in a context that is not a function call.
    2465              :    Enforce:
    2466              : 
    2467              :      [expr.ref]
    2468              : 
    2469              :      The expression can be used only as the left-hand operand of a
    2470              :      member function call.
    2471              : 
    2472              :      [expr.mptr.operator]
    2473              : 
    2474              :      If the result of .* or ->* is a function, then that result can be
    2475              :      used only as the operand for the function call operator ().
    2476              : 
    2477              :    by issuing an error message if appropriate.  Returns true iff EXPR
    2478              :    violates these rules.  */
    2479              : 
    2480              : bool
    2481   1449941458 : invalid_nonstatic_memfn_p (location_t loc, tree expr, tsubst_flags_t complain)
    2482              : {
    2483   1449941458 :   if (expr == NULL_TREE)
    2484              :     return false;
    2485              :   /* Don't enforce this in MS mode.  */
    2486   1449940016 :   if (flag_ms_extensions)
    2487              :     return false;
    2488   1449931955 :   if (is_overloaded_fn (expr) && !really_overloaded_fn (expr))
    2489    117879146 :     expr = get_first_fn (expr);
    2490   1449931955 :   if (TREE_TYPE (expr)
    2491   1449931955 :       && DECL_IOBJ_MEMBER_FUNCTION_P (expr))
    2492              :     {
    2493           96 :       if (complain & tf_error)
    2494              :         {
    2495           88 :           if (DECL_P (expr))
    2496              :             {
    2497           70 :               auto_diagnostic_group d;
    2498           70 :               error_at (loc, "invalid use of non-static member function %qD",
    2499              :                         expr);
    2500           70 :               inform (DECL_SOURCE_LOCATION (expr), "declared here");
    2501           70 :             }
    2502              :           else
    2503           18 :             error_at (loc, "invalid use of non-static member function of "
    2504           18 :                       "type %qT", TREE_TYPE (expr));
    2505              :         }
    2506           96 :       return true;
    2507              :     }
    2508              :   return false;
    2509              : }
    2510              : 
    2511              : /* If EXP is a reference to a bit-field, and the type of EXP does not
    2512              :    match the declared type of the bit-field, return the declared type
    2513              :    of the bit-field.  Otherwise, return NULL_TREE.  */
    2514              : 
    2515              : tree
    2516   3451317404 : is_bitfield_expr_with_lowered_type (const_tree exp)
    2517              : {
    2518   4717110085 :   switch (TREE_CODE (exp))
    2519              :     {
    2520      8314423 :     case COND_EXPR:
    2521     16628846 :       if (!is_bitfield_expr_with_lowered_type (TREE_OPERAND (exp, 1)
    2522      8314397 :                                                ? TREE_OPERAND (exp, 1)
    2523           26 :                                                : TREE_OPERAND (exp, 0)))
    2524              :         return NULL_TREE;
    2525          141 :       return is_bitfield_expr_with_lowered_type (TREE_OPERAND (exp, 2));
    2526              : 
    2527       886331 :     case COMPOUND_EXPR:
    2528       886331 :       return is_bitfield_expr_with_lowered_type (TREE_OPERAND (exp, 1));
    2529              : 
    2530    404729231 :     case MODIFY_EXPR:
    2531    404729231 :     case SAVE_EXPR:
    2532    404729231 :     case UNARY_PLUS_EXPR:
    2533    404729231 :     case PREDECREMENT_EXPR:
    2534    404729231 :     case PREINCREMENT_EXPR:
    2535    404729231 :     case POSTDECREMENT_EXPR:
    2536    404729231 :     case POSTINCREMENT_EXPR:
    2537    404729231 :     case NEGATE_EXPR:
    2538    404729231 :     case NON_LVALUE_EXPR:
    2539    404729231 :     case BIT_NOT_EXPR:
    2540    404729231 :     case CLEANUP_POINT_EXPR:
    2541    404729231 :       return is_bitfield_expr_with_lowered_type (TREE_OPERAND (exp, 0));
    2542              : 
    2543    248038636 :     case COMPONENT_REF:
    2544    248038636 :       {
    2545    248038636 :         tree field;
    2546              : 
    2547    248038636 :         field = TREE_OPERAND (exp, 1);
    2548    248038636 :         if (TREE_CODE (field) != FIELD_DECL || !DECL_BIT_FIELD_TYPE (field))
    2549              :           return NULL_TREE;
    2550     17824832 :         if (same_type_ignoring_top_level_qualifiers_p
    2551     17824832 :             (TREE_TYPE (exp), DECL_BIT_FIELD_TYPE (field)))
    2552              :           return NULL_TREE;
    2553     17656925 :         return DECL_BIT_FIELD_TYPE (field);
    2554              :       }
    2555              : 
    2556    648651749 :     case VAR_DECL:
    2557    648651749 :       if (DECL_HAS_VALUE_EXPR_P (exp))
    2558      1131337 :         return is_bitfield_expr_with_lowered_type (DECL_VALUE_EXPR
    2559      1131337 :                                                    (const_cast<tree> (exp)));
    2560              :       return NULL_TREE;
    2561              : 
    2562    865921478 :     case VIEW_CONVERT_EXPR:
    2563    865921478 :       if (location_wrapper_p (exp))
    2564    859045641 :         return is_bitfield_expr_with_lowered_type (TREE_OPERAND (exp, 0));
    2565              :       else
    2566              :         return NULL_TREE;
    2567              : 
    2568              :     default:
    2569              :       return NULL_TREE;
    2570              :     }
    2571              : }
    2572              : 
    2573              : /* Like is_bitfield_with_lowered_type, except that if EXP is not a
    2574              :    bitfield with a lowered type, the type of EXP is returned, rather
    2575              :    than NULL_TREE.  */
    2576              : 
    2577              : tree
    2578   1636085373 : unlowered_expr_type (const_tree exp)
    2579              : {
    2580   1636085373 :   tree type;
    2581   1636085373 :   tree etype = TREE_TYPE (exp);
    2582              : 
    2583   1636085373 :   type = is_bitfield_expr_with_lowered_type (exp);
    2584   1636085373 :   if (type)
    2585     14058975 :     type = cp_build_qualified_type (type, cp_type_quals (etype));
    2586              :   else
    2587              :     type = etype;
    2588              : 
    2589   1636085373 :   return type;
    2590              : }
    2591              : 
    2592              : /* Perform the conversions in [expr] that apply when an lvalue appears
    2593              :    in an rvalue context: the lvalue-to-rvalue, array-to-pointer, and
    2594              :    function-to-pointer conversions.  In addition, bitfield references are
    2595              :    converted to their declared types. Note that this function does not perform
    2596              :    the lvalue-to-rvalue conversion for class types. If you need that conversion
    2597              :    for class types, then you probably need to use force_rvalue.
    2598              : 
    2599              :    Although the returned value is being used as an rvalue, this
    2600              :    function does not wrap the returned expression in a
    2601              :    NON_LVALUE_EXPR; the caller is expected to be mindful of the fact
    2602              :    that the return value is no longer an lvalue.  */
    2603              : 
    2604              : tree
    2605   1150444525 : decay_conversion (tree exp,
    2606              :                   tsubst_flags_t complain,
    2607              :                   bool reject_builtin /* = true */)
    2608              : {
    2609   1150444525 :   tree type;
    2610   1150444525 :   enum tree_code code;
    2611   1150444525 :   location_t loc = cp_expr_loc_or_input_loc (exp);
    2612              : 
    2613   1150444525 :   type = TREE_TYPE (exp);
    2614   1150444525 :   if (type == error_mark_node)
    2615              :     return error_mark_node;
    2616              : 
    2617   1150444313 :   exp = resolve_nondeduced_context_or_error (exp, complain);
    2618              : 
    2619   1150444313 :   code = TREE_CODE (type);
    2620              : 
    2621   1150444313 :   if (error_operand_p (exp))
    2622           90 :     return error_mark_node;
    2623              : 
    2624   1150444223 :   if (NULLPTR_TYPE_P (type) && !TREE_SIDE_EFFECTS (exp))
    2625              :     {
    2626      1702599 :       mark_rvalue_use (exp, loc, reject_builtin);
    2627      1702599 :       return nullptr_node;
    2628              :     }
    2629              : 
    2630              :   /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
    2631              :      Leave such NOP_EXPRs, since RHS is being used in non-lvalue context.  */
    2632   1148741624 :   if (code == VOID_TYPE)
    2633              :     {
    2634         5778 :       if (complain & tf_error)
    2635            3 :         error_at (loc, "void value not ignored as it ought to be");
    2636         5778 :       return error_mark_node;
    2637              :     }
    2638   1148735846 :   if (invalid_nonstatic_memfn_p (loc, exp, complain))
    2639            6 :     return error_mark_node;
    2640   1148735840 :   if (code == FUNCTION_TYPE || is_overloaded_fn (exp))
    2641              :     {
    2642    123156324 :       exp = mark_lvalue_use (exp);
    2643    123156324 :       if (reject_builtin && reject_gcc_builtin (exp, loc))
    2644          109 :         return error_mark_node;
    2645    123156215 :       return cp_build_addr_expr (exp, complain);
    2646              :     }
    2647   1025579516 :   if (code == ARRAY_TYPE)
    2648              :     {
    2649      6225638 :       tree adr;
    2650      6225638 :       tree ptrtype;
    2651              : 
    2652      6225638 :       exp = mark_lvalue_use (exp);
    2653              : 
    2654      6225638 :       if (INDIRECT_REF_P (exp))
    2655       160185 :         return build_nop (build_pointer_type (TREE_TYPE (type)),
    2656       320370 :                           TREE_OPERAND (exp, 0));
    2657              : 
    2658      6065453 :       if (TREE_CODE (exp) == COMPOUND_EXPR)
    2659              :         {
    2660            3 :           tree op1 = decay_conversion (TREE_OPERAND (exp, 1), complain);
    2661            3 :           if (op1 == error_mark_node)
    2662              :             return error_mark_node;
    2663            3 :           return build2 (COMPOUND_EXPR, TREE_TYPE (op1),
    2664            6 :                          TREE_OPERAND (exp, 0), op1);
    2665              :         }
    2666              : 
    2667      6065450 :       if (!obvalue_p (exp)
    2668      6065450 :           && ! (TREE_CODE (exp) == CONSTRUCTOR && TREE_STATIC (exp)))
    2669              :         {
    2670            0 :           if (complain & tf_error)
    2671            0 :             error_at (loc, "invalid use of non-lvalue array");
    2672            0 :           return error_mark_node;
    2673              :         }
    2674              : 
    2675      6065450 :       ptrtype = build_pointer_type (TREE_TYPE (type));
    2676              : 
    2677      6065450 :       if (VAR_P (exp))
    2678              :         {
    2679       553591 :           if (!cxx_mark_addressable (exp))
    2680            0 :             return error_mark_node;
    2681       553591 :           adr = build_nop (ptrtype, build_address (exp));
    2682       553591 :           return adr;
    2683              :         }
    2684              :       /* This way is better for a COMPONENT_REF since it can
    2685              :          simplify the offset for a component.  */
    2686      5511859 :       adr = cp_build_addr_expr (exp, complain);
    2687      5511859 :       return cp_convert (ptrtype, adr, complain);
    2688              :     }
    2689              : 
    2690              :   /* Otherwise, it's the lvalue-to-rvalue conversion.  */
    2691   1019353878 :   exp = mark_rvalue_use (exp, loc, reject_builtin);
    2692              : 
    2693              :   /* If a bitfield is used in a context where integral promotion
    2694              :      applies, then the caller is expected to have used
    2695              :      default_conversion.  That function promotes bitfields correctly
    2696              :      before calling this function.  At this point, if we have a
    2697              :      bitfield referenced, we may assume that is not subject to
    2698              :      promotion, and that, therefore, the type of the resulting rvalue
    2699              :      is the declared type of the bitfield.  */
    2700   1019353878 :   exp = convert_bitfield_to_declared_type (exp);
    2701              : 
    2702              :   /* We do not call rvalue() here because we do not want to wrap EXP
    2703              :      in a NON_LVALUE_EXPR.  */
    2704              : 
    2705              :   /* [basic.lval]
    2706              : 
    2707              :      Non-class rvalues always have cv-unqualified types.  */
    2708   1019353878 :   type = TREE_TYPE (exp);
    2709   1019353878 :   if (!CLASS_TYPE_P (type) && cv_qualified_p (type))
    2710    316614861 :     exp = build_nop (cv_unqualified (type), exp);
    2711              : 
    2712   1019353878 :   if (!complete_type_or_maybe_complain (type, exp, complain))
    2713           42 :     return error_mark_node;
    2714              : 
    2715              :   return exp;
    2716              : }
    2717              : 
    2718              : /* Perform preparatory conversions, as part of the "usual arithmetic
    2719              :    conversions".  In particular, as per [expr]:
    2720              : 
    2721              :      Whenever an lvalue expression appears as an operand of an
    2722              :      operator that expects the rvalue for that operand, the
    2723              :      lvalue-to-rvalue, array-to-pointer, or function-to-pointer
    2724              :      standard conversions are applied to convert the expression to an
    2725              :      rvalue.
    2726              : 
    2727              :    In addition, we perform integral promotions here, as those are
    2728              :    applied to both operands to a binary operator before determining
    2729              :    what additional conversions should apply.  */
    2730              : 
    2731              : static tree
    2732    303924039 : cp_default_conversion (tree exp, tsubst_flags_t complain)
    2733              : {
    2734              :   /* Check for target-specific promotions.  */
    2735    303924039 :   tree promoted_type = targetm.promoted_type (TREE_TYPE (exp));
    2736    303924039 :   if (promoted_type)
    2737            0 :     exp = cp_convert (promoted_type, exp, complain);
    2738              :   /* Perform the integral promotions first so that bitfield
    2739              :      expressions (which may promote to "int", even if the bitfield is
    2740              :      declared "unsigned") are promoted correctly.  */
    2741    303924039 :   else if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (exp)))
    2742    210648761 :     exp = cp_perform_integral_promotions (exp, complain);
    2743              :   /* Perform the other conversions.  */
    2744    303924039 :   exp = decay_conversion (exp, complain);
    2745              : 
    2746    303924039 :   return exp;
    2747              : }
    2748              : 
    2749              : /* C version.  */
    2750              : 
    2751              : tree
    2752     41070234 : default_conversion (tree exp)
    2753              : {
    2754     41070234 :   return cp_default_conversion (exp, tf_warning_or_error);
    2755              : }
    2756              : 
    2757              : /* EXPR is an expression with an integral or enumeration type.
    2758              :    Perform the integral promotions in [conv.prom], and return the
    2759              :    converted value.  */
    2760              : 
    2761              : tree
    2762    216569263 : cp_perform_integral_promotions (tree expr, tsubst_flags_t complain)
    2763              : {
    2764    216569263 :   tree type;
    2765    216569263 :   tree promoted_type;
    2766              : 
    2767    216569263 :   expr = mark_rvalue_use (expr);
    2768    216569263 :   if (error_operand_p (expr))
    2769            6 :     return error_mark_node;
    2770              : 
    2771    216569257 :   type = TREE_TYPE (expr);
    2772              : 
    2773              :   /* [conv.prom]
    2774              : 
    2775              :      A prvalue for an integral bit-field (11.3.9) can be converted to a prvalue
    2776              :      of type int if int can represent all the values of the bit-field;
    2777              :      otherwise, it can be converted to unsigned int if unsigned int can
    2778              :      represent all the values of the bit-field. If the bit-field is larger yet,
    2779              :      no integral promotion applies to it. If the bit-field has an enumerated
    2780              :      type, it is treated as any other value of that type for promotion
    2781              :      purposes.  */
    2782    216569257 :   tree bitfield_type = is_bitfield_expr_with_lowered_type (expr);
    2783    216569257 :   if (bitfield_type
    2784    216569257 :       && (TREE_CODE (bitfield_type) == ENUMERAL_TYPE
    2785       512392 :           || TYPE_PRECISION (type) > TYPE_PRECISION (integer_type_node)))
    2786              :     type = bitfield_type;
    2787              : 
    2788    216569257 :   gcc_assert (INTEGRAL_OR_ENUMERATION_TYPE_P (type));
    2789              :   /* Scoped enums don't promote.  */
    2790    216569257 :   if (SCOPED_ENUM_P (type))
    2791              :     return expr;
    2792    216130217 :   promoted_type = type_promotes_to (type);
    2793    216130217 :   if (type != promoted_type)
    2794     64637622 :     expr = cp_convert (promoted_type, expr, complain);
    2795    151492595 :   else if (bitfield_type && bitfield_type != type)
    2796              :     /* Prevent decay_conversion from converting to bitfield_type.  */
    2797          159 :     expr = build_nop (type, expr);
    2798              :   return expr;
    2799              : }
    2800              : 
    2801              : /* C version.  */
    2802              : 
    2803              : tree
    2804      1629372 : perform_integral_promotions (tree expr)
    2805              : {
    2806      1629372 :   return cp_perform_integral_promotions (expr, tf_warning_or_error);
    2807              : }
    2808              : 
    2809              : /* Returns nonzero iff exp is a STRING_CST or the result of applying
    2810              :    decay_conversion to one.  */
    2811              : 
    2812              : int
    2813      3631467 : string_conv_p (const_tree totype, const_tree exp, int warn)
    2814              : {
    2815      3631467 :   tree t;
    2816              : 
    2817      3631467 :   if (!TYPE_PTR_P (totype))
    2818              :     return 0;
    2819              : 
    2820      3630996 :   t = TREE_TYPE (totype);
    2821      3630996 :   if (!same_type_p (t, char_type_node)
    2822      3486246 :       && !same_type_p (t, char8_type_node)
    2823      3425283 :       && !same_type_p (t, char16_type_node)
    2824      3375517 :       && !same_type_p (t, char32_type_node)
    2825      6956748 :       && !same_type_p (t, wchar_type_node))
    2826              :     return 0;
    2827              : 
    2828       344625 :   location_t loc = EXPR_LOC_OR_LOC (exp, input_location);
    2829              : 
    2830       344625 :   STRIP_ANY_LOCATION_WRAPPER (exp);
    2831              : 
    2832       344625 :   if (TREE_CODE (exp) == STRING_CST)
    2833              :     {
    2834              :       /* Make sure that we don't try to convert between char and wide chars.  */
    2835          108 :       if (!same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (exp))), t))
    2836              :         return 0;
    2837              :     }
    2838              :   else
    2839              :     {
    2840              :       /* Is this a string constant which has decayed to 'const char *'?  */
    2841       344517 :       t = build_pointer_type (cp_build_qualified_type (t, TYPE_QUAL_CONST));
    2842       344517 :       if (!same_type_p (TREE_TYPE (exp), t))
    2843              :         return 0;
    2844        14043 :       STRIP_NOPS (exp);
    2845        14043 :       if (TREE_CODE (exp) != ADDR_EXPR
    2846        14043 :           || TREE_CODE (TREE_OPERAND (exp, 0)) != STRING_CST)
    2847              :         return 0;
    2848              :     }
    2849          306 :   if (warn)
    2850              :     {
    2851          102 :       if (cxx_dialect >= cxx11)
    2852           87 :         pedwarn (loc, OPT_Wwrite_strings,
    2853              :                  "ISO C++ forbids converting a string constant to %qT",
    2854              :                  totype);
    2855              :       else
    2856           15 :         warning_at (loc, OPT_Wwrite_strings,
    2857              :                     "deprecated conversion from string constant to %qT",
    2858              :                     totype);
    2859              :     }
    2860              : 
    2861              :   return 1;
    2862              : }
    2863              : 
    2864              : /* Given a COND_EXPR, MIN_EXPR, or MAX_EXPR in T, return it in a form that we
    2865              :    can, for example, use as an lvalue.  This code used to be in
    2866              :    unary_complex_lvalue, but we needed it to deal with `a = (d == c) ? b : c'
    2867              :    expressions, where we're dealing with aggregates.  But now it's again only
    2868              :    called from unary_complex_lvalue.  The case (in particular) that led to
    2869              :    this was with CODE == ADDR_EXPR, since it's not an lvalue when we'd
    2870              :    get it there.  */
    2871              : 
    2872              : static tree
    2873        76712 : rationalize_conditional_expr (enum tree_code code, tree t,
    2874              :                               tsubst_flags_t complain)
    2875              : {
    2876        76712 :   location_t loc = cp_expr_loc_or_input_loc (t);
    2877              : 
    2878              :   /* For MIN_EXPR or MAX_EXPR, fold-const.cc has arranged things so that
    2879              :      the first operand is always the one to be used if both operands
    2880              :      are equal, so we know what conditional expression this used to be.  */
    2881        76712 :   if (TREE_CODE (t) == MIN_EXPR || TREE_CODE (t) == MAX_EXPR)
    2882              :     {
    2883            0 :       tree op0 = TREE_OPERAND (t, 0);
    2884            0 :       tree op1 = TREE_OPERAND (t, 1);
    2885              : 
    2886              :       /* The following code is incorrect if either operand side-effects.  */
    2887            0 :       gcc_assert (!TREE_SIDE_EFFECTS (op0)
    2888              :                   && !TREE_SIDE_EFFECTS (op1));
    2889            0 :       return
    2890            0 :         build_conditional_expr (loc,
    2891            0 :                                 build_x_binary_op (loc,
    2892            0 :                                                    (TREE_CODE (t) == MIN_EXPR
    2893              :                                                     ? LE_EXPR : GE_EXPR),
    2894            0 :                                                    op0, TREE_CODE (op0),
    2895            0 :                                                    op1, TREE_CODE (op1),
    2896              :                                                    NULL_TREE,
    2897              :                                                    /*overload=*/NULL,
    2898              :                                                    complain),
    2899              :                                 cp_build_unary_op (code, op0, false, complain),
    2900              :                                 cp_build_unary_op (code, op1, false, complain),
    2901              :                                 complain);
    2902              :     }
    2903              : 
    2904        76712 :   tree op1 = TREE_OPERAND (t, 1);
    2905        76712 :   if (TREE_CODE (op1) != THROW_EXPR)
    2906        76709 :     op1 = cp_build_unary_op (code, op1, false, complain);
    2907        76712 :   tree op2 = TREE_OPERAND (t, 2);
    2908        76712 :   if (TREE_CODE (op2) != THROW_EXPR)
    2909        76706 :     op2 = cp_build_unary_op (code, op2, false, complain);
    2910              : 
    2911        76712 :   return
    2912        76712 :     build_conditional_expr (loc, TREE_OPERAND (t, 0), op1, op2, complain);
    2913              : }
    2914              : 
    2915              : /* Given the TYPE of an anonymous union field inside T, return the
    2916              :    FIELD_DECL for the field.  If not found return NULL_TREE.  Because
    2917              :    anonymous unions can nest, we must also search all anonymous unions
    2918              :    that are directly reachable.  */
    2919              : 
    2920              : tree
    2921      1430207 : lookup_anon_field (tree, tree type)
    2922              : {
    2923      1430207 :   tree field;
    2924              : 
    2925      1430207 :   type = TYPE_MAIN_VARIANT (type);
    2926      1430207 :   field = ANON_AGGR_TYPE_FIELD (type);
    2927      1430207 :   gcc_assert (field);
    2928      1430207 :   return field;
    2929              : }
    2930              : 
    2931              : /* Build an expression representing OBJECT.MEMBER.  OBJECT is an
    2932              :    expression; MEMBER is a DECL or baselink.  If ACCESS_PATH is
    2933              :    non-NULL, it indicates the path to the base used to name MEMBER.
    2934              :    If PRESERVE_REFERENCE is true, the expression returned will have
    2935              :    REFERENCE_TYPE if the MEMBER does.  Otherwise, the expression
    2936              :    returned will have the type referred to by the reference.
    2937              : 
    2938              :    This function does not perform access control; that is either done
    2939              :    earlier by the parser when the name of MEMBER is resolved to MEMBER
    2940              :    itself, or later when overload resolution selects one of the
    2941              :    functions indicated by MEMBER.  */
    2942              : 
    2943              : tree
    2944    117720974 : build_class_member_access_expr (cp_expr object, tree member,
    2945              :                                 tree access_path, bool preserve_reference,
    2946              :                                 tsubst_flags_t complain)
    2947              : {
    2948    117720974 :   tree object_type;
    2949    117720974 :   tree member_scope;
    2950    117720974 :   tree result = NULL_TREE;
    2951    117720974 :   tree using_decl = NULL_TREE;
    2952              : 
    2953    117720974 :   if (error_operand_p (object) || error_operand_p (member))
    2954           59 :     return error_mark_node;
    2955              : 
    2956    117720915 :   gcc_assert (DECL_P (member) || BASELINK_P (member));
    2957              : 
    2958              :   /* [expr.ref]
    2959              : 
    2960              :      The type of the first expression shall be "class object" (of a
    2961              :      complete type).  */
    2962    117720915 :   object_type = TREE_TYPE (object);
    2963    117720915 :   if (!currently_open_class (object_type)
    2964    117720915 :       && !complete_type_or_maybe_complain (object_type, object, complain))
    2965            0 :     return error_mark_node;
    2966    117720915 :   if (!CLASS_TYPE_P (object_type))
    2967              :     {
    2968            0 :       if (complain & tf_error)
    2969              :         {
    2970            0 :           if (INDIRECT_TYPE_P (object_type)
    2971            0 :               && CLASS_TYPE_P (TREE_TYPE (object_type)))
    2972            0 :             error ("request for member %qD in %qE, which is of pointer "
    2973              :                    "type %qT (maybe you meant to use %<->%> ?)",
    2974              :                    member, object.get_value (), object_type);
    2975              :           else
    2976            0 :             error ("request for member %qD in %qE, which is of non-class "
    2977              :                    "type %qT", member, object.get_value (), object_type);
    2978              :         }
    2979            0 :       return error_mark_node;
    2980              :     }
    2981              : 
    2982              :   /* The standard does not seem to actually say that MEMBER must be a
    2983              :      member of OBJECT_TYPE.  However, that is clearly what is
    2984              :      intended.  */
    2985    117720915 :   if (DECL_P (member))
    2986              :     {
    2987     50912272 :       member_scope = DECL_CLASS_CONTEXT (member);
    2988     50912272 :       if (!mark_used (member, complain) && !(complain & tf_error))
    2989            0 :         return error_mark_node;
    2990              : 
    2991     50912272 :       if (TREE_UNAVAILABLE (member))
    2992           30 :         error_unavailable_use (member, NULL_TREE);
    2993     50912242 :       else if (TREE_DEPRECATED (member))
    2994           30 :         warn_deprecated_use (member, NULL_TREE);
    2995              :     }
    2996              :   else
    2997     66808643 :     member_scope = BINFO_TYPE (BASELINK_ACCESS_BINFO (member));
    2998              :   /* If MEMBER is from an anonymous aggregate, MEMBER_SCOPE will
    2999              :      presently be the anonymous union.  Go outwards until we find a
    3000              :      type related to OBJECT_TYPE.  */
    3001    119154727 :   while ((ANON_AGGR_TYPE_P (member_scope) || UNSCOPED_ENUM_P (member_scope))
    3002    120589095 :          && !same_type_ignoring_top_level_qualifiers_p (member_scope,
    3003              :                                                         object_type))
    3004      1433812 :     member_scope = TYPE_CONTEXT (member_scope);
    3005    117720915 :   if (!member_scope || !DERIVED_FROM_P (member_scope, object_type))
    3006              :     {
    3007           19 :       if (complain & tf_error)
    3008              :         {
    3009           19 :           if (TREE_CODE (member) == FIELD_DECL)
    3010            4 :             error ("invalid use of non-static data member %qE", member);
    3011              :           else
    3012           15 :             error ("%qD is not a member of %qT", member, object_type);
    3013              :         }
    3014           19 :       return error_mark_node;
    3015              :     }
    3016              : 
    3017              :   /* Transform `(a, b).x' into `(*(a, &b)).x', `(a ? b : c).x' into
    3018              :      `(*(a ?  &b : &c)).x', and so on.  A COND_EXPR is only an lvalue
    3019              :      in the front end; only _DECLs and _REFs are lvalues in the back end.  */
    3020    117720896 :   if (tree temp = unary_complex_lvalue (ADDR_EXPR, object))
    3021              :     {
    3022           44 :       temp = cp_build_fold_indirect_ref (temp);
    3023           44 :       if (!lvalue_p (object) && lvalue_p (temp))
    3024              :         /* Preserve rvalueness.  */
    3025            6 :         temp = move (temp);
    3026           44 :       object = temp;
    3027              :     }
    3028              : 
    3029              :   /* In [expr.ref], there is an explicit list of the valid choices for
    3030              :      MEMBER.  We check for each of those cases here.  */
    3031    117720896 :   if (VAR_P (member))
    3032              :     {
    3033              :       /* A static data member.  */
    3034        73828 :       result = member;
    3035        73828 :       mark_exp_read (object);
    3036              : 
    3037        73828 :       if (tree wrap = maybe_get_tls_wrapper_call (result))
    3038              :         /* Replace an evaluated use of the thread_local variable with
    3039              :            a call to its wrapper.  */
    3040          102 :         result = wrap;
    3041              : 
    3042              :       /* If OBJECT has side-effects, they are supposed to occur.  */
    3043        73828 :       if (TREE_SIDE_EFFECTS (object))
    3044         2559 :         result = build2 (COMPOUND_EXPR, TREE_TYPE (result), object, result);
    3045              :     }
    3046    117647068 :   else if (TREE_CODE (member) == FIELD_DECL)
    3047              :     {
    3048              :       /* A non-static data member.  */
    3049     50838213 :       bool null_object_p;
    3050     50838213 :       int type_quals;
    3051     50838213 :       tree member_type;
    3052              : 
    3053     50838213 :       if (INDIRECT_REF_P (object))
    3054     38366483 :         null_object_p =
    3055     38366483 :           integer_zerop (tree_strip_nop_conversions (TREE_OPERAND (object, 0)));
    3056              :       else
    3057              :         null_object_p = false;
    3058              : 
    3059              :       /* Convert OBJECT to the type of MEMBER.  */
    3060     50838213 :       if (!same_type_p (TYPE_MAIN_VARIANT (object_type),
    3061              :                         TYPE_MAIN_VARIANT (member_scope)))
    3062              :         {
    3063      1939438 :           tree binfo;
    3064      1939438 :           base_kind kind;
    3065              : 
    3066              :           /* We didn't complain above about a currently open class, but now we
    3067              :              must: we don't know how to refer to a base member before layout is
    3068              :              complete.  But still don't complain in a template.  */
    3069      1939438 :           if (!cp_unevaluated_operand
    3070      1938975 :               && !dependent_type_p (object_type)
    3071      3601462 :               && !complete_type_or_maybe_complain (object_type, object,
    3072              :                                                    complain))
    3073           17 :             return error_mark_node;
    3074              : 
    3075      2635219 :           binfo = lookup_base (access_path ? access_path : object_type,
    3076              :                                member_scope, ba_unique, &kind, complain);
    3077      1939435 :           if (binfo == error_mark_node)
    3078              :             return error_mark_node;
    3079              : 
    3080              :           /* It is invalid to try to get to a virtual base of a
    3081              :              NULL object.  The most common cause is invalid use of
    3082              :              offsetof macro.  */
    3083      1939427 :           if (null_object_p && kind == bk_via_virtual)
    3084              :             {
    3085            6 :               if (complain & tf_error)
    3086              :                 {
    3087            6 :                   error ("invalid access to non-static data member %qD in "
    3088              :                          "virtual base of NULL object", member);
    3089              :                 }
    3090            6 :               return error_mark_node;
    3091              :             }
    3092              : 
    3093              :           /* Convert to the base.  */
    3094      1939421 :           object = build_base_path (PLUS_EXPR, object, binfo,
    3095              :                                     /*nonnull=*/1, complain);
    3096              :           /* If we found the base successfully then we should be able
    3097              :              to convert to it successfully.  */
    3098      1939421 :           gcc_assert (object != error_mark_node || seen_error ());
    3099              :         }
    3100              : 
    3101              :       /* If MEMBER is from an anonymous aggregate, we have converted
    3102              :          OBJECT so that it refers to the class containing the
    3103              :          anonymous union.  Generate a reference to the anonymous union
    3104              :          itself, and recur to find MEMBER.  */
    3105    101676392 :       if (ANON_AGGR_TYPE_P (DECL_CONTEXT (member))
    3106              :           /* When this code is called from build_field_call, the
    3107              :              object already has the type of the anonymous union.
    3108              :              That is because the COMPONENT_REF was already
    3109              :              constructed, and was then disassembled before calling
    3110              :              build_field_call.  After the function-call code is
    3111              :              cleaned up, this waste can be eliminated.  */
    3112     52268813 :           && (!same_type_ignoring_top_level_qualifiers_p
    3113      1430617 :               (TREE_TYPE (object), DECL_CONTEXT (member))))
    3114              :         {
    3115      1430067 :           tree anonymous_union;
    3116              : 
    3117      1430067 :           anonymous_union = lookup_anon_field (TREE_TYPE (object),
    3118      1430067 :                                                DECL_CONTEXT (member));
    3119      1430067 :           object = build_class_member_access_expr (object,
    3120              :                                                    anonymous_union,
    3121              :                                                    /*access_path=*/NULL_TREE,
    3122              :                                                    preserve_reference,
    3123              :                                                    complain);
    3124              :         }
    3125              : 
    3126              :       /* Compute the type of the field, as described in [expr.ref].  */
    3127     50838196 :       type_quals = TYPE_UNQUALIFIED;
    3128     50838196 :       member_type = TREE_TYPE (member);
    3129     50838196 :       if (!TYPE_REF_P (member_type))
    3130              :         {
    3131     50031881 :           type_quals = (cp_type_quals (member_type)
    3132     50031881 :                         | cp_type_quals (object_type));
    3133              : 
    3134              :           /* A field is const (volatile) if the enclosing object, or the
    3135              :              field itself, is const (volatile).  But, a mutable field is
    3136              :              not const, even within a const object.  */
    3137     50031881 :           if (DECL_MUTABLE_P (member))
    3138       311075 :             type_quals &= ~TYPE_QUAL_CONST;
    3139     50031881 :           member_type = cp_build_qualified_type (member_type, type_quals);
    3140              :         }
    3141              : 
    3142     50838196 :       result = build3_loc (input_location, COMPONENT_REF, member_type,
    3143              :                            object, member, NULL_TREE);
    3144              : 
    3145              :       /* Mark the expression const or volatile, as appropriate.  Even
    3146              :          though we've dealt with the type above, we still have to mark the
    3147              :          expression itself.  */
    3148     50838196 :       if (type_quals & TYPE_QUAL_CONST)
    3149     15815463 :         TREE_READONLY (result) = 1;
    3150     50838196 :       if (type_quals & TYPE_QUAL_VOLATILE)
    3151       180173 :         TREE_THIS_VOLATILE (result) = 1;
    3152              :     }
    3153     66808855 :   else if (BASELINK_P (member))
    3154              :     {
    3155              :       /* The member is a (possibly overloaded) member function.  */
    3156     66808628 :       tree functions;
    3157     66808628 :       tree type;
    3158              : 
    3159              :       /* If the MEMBER is exactly one static member function, then we
    3160              :          know the type of the expression.  Otherwise, we must wait
    3161              :          until overload resolution has been performed.  */
    3162     66808628 :       functions = BASELINK_FUNCTIONS (member);
    3163     66808628 :       if (TREE_CODE (functions) == OVERLOAD && OVL_SINGLE_P (functions))
    3164     66808628 :         functions = OVL_FIRST (functions);
    3165     66808628 :       if (TREE_CODE (functions) == FUNCTION_DECL
    3166     66808628 :           && DECL_STATIC_FUNCTION_P (functions))
    3167       599069 :         type = TREE_TYPE (functions);
    3168              :       else
    3169     66209559 :         type = unknown_type_node;
    3170              :       /* Note that we do not convert OBJECT to the BASELINK_BINFO
    3171              :          base.  That will happen when the function is called.  */
    3172     66808628 :       result = build3_loc (input_location, COMPONENT_REF, type, object, member,
    3173              :                            NULL_TREE);
    3174              :     }
    3175          227 :   else if (TREE_CODE (member) == CONST_DECL)
    3176              :     {
    3177              :       /* The member is an enumerator.  */
    3178          215 :       result = member;
    3179              :       /* If OBJECT has side-effects, they are supposed to occur.  */
    3180          215 :       if (TREE_SIDE_EFFECTS (object))
    3181            6 :         result = build2 (COMPOUND_EXPR, TREE_TYPE (result),
    3182              :                          object, result);
    3183              :     }
    3184           12 :   else if ((using_decl = strip_using_decl (member)) != member)
    3185            0 :     result = build_class_member_access_expr (object,
    3186              :                                              using_decl,
    3187              :                                              access_path, preserve_reference,
    3188              :                                              complain);
    3189              :   else
    3190              :     {
    3191           12 :       if (complain & tf_error)
    3192           12 :         error ("invalid use of %qD", member);
    3193           12 :       return error_mark_node;
    3194              :     }
    3195              : 
    3196    117720867 :   if (!preserve_reference)
    3197              :     /* [expr.ref]
    3198              : 
    3199              :        If E2 is declared to have type "reference to T", then ... the
    3200              :        type of E1.E2 is T.  */
    3201    111130274 :     result = convert_from_reference (result);
    3202              : 
    3203              :   return result;
    3204              : }
    3205              : 
    3206              : /* Return the destructor denoted by OBJECT.SCOPE::DTOR_NAME, or, if
    3207              :    SCOPE is NULL, by OBJECT.DTOR_NAME, where DTOR_NAME is ~type.  */
    3208              : 
    3209              : tree
    3210       202199 : lookup_destructor (tree object, tree scope, tree dtor_name,
    3211              :                    tsubst_flags_t complain)
    3212              : {
    3213       202199 :   tree object_type = TREE_TYPE (object);
    3214       202199 :   tree dtor_type = TREE_OPERAND (dtor_name, 0);
    3215       202199 :   tree expr;
    3216              : 
    3217              :   /* We've already complained about this destructor.  */
    3218       202199 :   if (dtor_type == error_mark_node)
    3219              :     return error_mark_node;
    3220              : 
    3221       202193 :   if (scope && !check_dtor_name (scope, dtor_type))
    3222              :     {
    3223            3 :       if (complain & tf_error)
    3224            3 :         error ("qualified type %qT does not match destructor name ~%qT",
    3225              :                scope, dtor_type);
    3226            3 :       return error_mark_node;
    3227              :     }
    3228       202190 :   if (is_auto (dtor_type))
    3229              :     dtor_type = object_type;
    3230       202187 :   else if (identifier_p (dtor_type))
    3231              :     {
    3232              :       /* In a template, names we can't find a match for are still accepted
    3233              :          destructor names, and we check them here.  */
    3234           23 :       if (check_dtor_name (object_type, dtor_type))
    3235              :         dtor_type = object_type;
    3236              :       else
    3237              :         {
    3238            3 :           if (complain & tf_error)
    3239            3 :             error ("object type %qT does not match destructor name ~%qT",
    3240              :                    object_type, dtor_type);
    3241            3 :           return error_mark_node;
    3242              :         }
    3243              : 
    3244              :     }
    3245       202164 :   else if (!DERIVED_FROM_P (dtor_type, TYPE_MAIN_VARIANT (object_type)))
    3246              :     {
    3247            8 :       if (complain & tf_error)
    3248            8 :         error ("the type being destroyed is %qT, but the destructor "
    3249            8 :                "refers to %qT", TYPE_MAIN_VARIANT (object_type), dtor_type);
    3250            8 :       return error_mark_node;
    3251              :     }
    3252       202179 :   expr = lookup_member (dtor_type, complete_dtor_identifier,
    3253              :                         /*protect=*/1, /*want_type=*/false,
    3254              :                         tf_warning_or_error);
    3255       202179 :   if (!expr)
    3256              :     {
    3257            6 :       if (complain & tf_error)
    3258            6 :         cxx_incomplete_type_error (dtor_name, dtor_type);
    3259            6 :       return error_mark_node;
    3260              :     }
    3261       202173 :   expr = (adjust_result_of_qualified_name_lookup
    3262       202173 :           (expr, dtor_type, object_type));
    3263       202173 :   if (scope == NULL_TREE)
    3264              :     /* We need to call adjust_result_of_qualified_name_lookup in case the
    3265              :        destructor names a base class, but we unset BASELINK_QUALIFIED_P so
    3266              :        that we still get virtual function binding.  */
    3267       202030 :     BASELINK_QUALIFIED_P (expr) = false;
    3268              :   return expr;
    3269              : }
    3270              : 
    3271              : /* An expression of the form "A::template B" has been resolved to
    3272              :    DECL.  Issue a diagnostic if B is not a template or template
    3273              :    specialization.  */
    3274              : 
    3275              : void
    3276       252594 : check_template_keyword (tree decl)
    3277              : {
    3278              :   /* The standard says:
    3279              : 
    3280              :       [temp.names]
    3281              : 
    3282              :       If a name prefixed by the keyword template is not a member
    3283              :       template, the program is ill-formed.
    3284              : 
    3285              :      DR 228 removed the restriction that the template be a member
    3286              :      template.
    3287              : 
    3288              :      DR 96, if accepted would add the further restriction that explicit
    3289              :      template arguments must be provided if the template keyword is
    3290              :      used, but, as of 2005-10-16, that DR is still in "drafting".  If
    3291              :      this DR is accepted, then the semantic checks here can be
    3292              :      simplified, as the entity named must in fact be a template
    3293              :      specialization, rather than, as at present, a set of overloaded
    3294              :      functions containing at least one template function.  */
    3295       252594 :   if (TREE_CODE (decl) != TEMPLATE_DECL
    3296       252594 :       && TREE_CODE (decl) != TEMPLATE_ID_EXPR)
    3297              :     {
    3298        60385 :       if (VAR_P (decl))
    3299              :         {
    3300         9728 :           if (DECL_USE_TEMPLATE (decl)
    3301         9728 :               && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (decl)))
    3302              :             ;
    3303              :           else
    3304            0 :             permerror (input_location, "%qD is not a template", decl);
    3305              :         }
    3306        50657 :       else if (!is_overloaded_fn (decl))
    3307            0 :         permerror (input_location, "%qD is not a template", decl);
    3308              :       else
    3309              :         {
    3310        50657 :           bool found = false;
    3311              : 
    3312       101314 :           for (lkp_iterator iter (MAYBE_BASELINK_FUNCTIONS (decl));
    3313       101316 :                !found && iter; ++iter)
    3314              :             {
    3315        50659 :               tree fn = *iter;
    3316        50659 :               if (TREE_CODE (fn) == TEMPLATE_DECL
    3317        50263 :                   || TREE_CODE (fn) == TEMPLATE_ID_EXPR
    3318        50673 :                   || (TREE_CODE (fn) == FUNCTION_DECL
    3319           14 :                       && DECL_USE_TEMPLATE (fn)
    3320            6 :                       && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (fn))))
    3321              :                 found = true;
    3322              :             }
    3323        50657 :           if (!found)
    3324           12 :             permerror (input_location, "%qD is not a template", decl);
    3325              :         }
    3326              :     }
    3327       252594 : }
    3328              : 
    3329              : /* Record that an access failure occurred on BASETYPE_PATH attempting
    3330              :    to access DECL, where DIAG_DECL should be used for diagnostics.  */
    3331              : 
    3332              : void
    3333          412 : access_failure_info::record_access_failure (tree basetype_path,
    3334              :                                             tree decl, tree diag_decl)
    3335              : {
    3336          412 :   m_was_inaccessible = true;
    3337          412 :   m_basetype_path = basetype_path;
    3338          412 :   m_decl = decl;
    3339          412 :   m_diag_decl = diag_decl;
    3340          412 : }
    3341              : 
    3342              : /* If an access failure was recorded, then attempt to locate an
    3343              :    accessor function for the pertinent field.
    3344              :    Otherwise, return NULL_TREE.  */
    3345              : 
    3346              : tree
    3347     94722416 : access_failure_info::get_any_accessor (bool const_p) const
    3348              : {
    3349     94722416 :   if (!was_inaccessible_p ())
    3350              :     return NULL_TREE;
    3351              : 
    3352          412 :   tree accessor
    3353          412 :     = locate_field_accessor (m_basetype_path, m_diag_decl, const_p);
    3354          412 :   if (!accessor)
    3355              :     return NULL_TREE;
    3356              : 
    3357              :   /* The accessor must itself be accessible for it to be a reasonable
    3358              :      suggestion.  */
    3359          161 :   if (!accessible_p (m_basetype_path, accessor, true))
    3360              :     return NULL_TREE;
    3361              : 
    3362              :   return accessor;
    3363              : }
    3364              : 
    3365              : /* Add a fix-it hint to RICHLOC suggesting the use of ACCESSOR_DECL, by
    3366              :    replacing the primary location in RICHLOC with "accessor()".  */
    3367              : 
    3368              : void
    3369          140 : access_failure_info::add_fixit_hint (rich_location *richloc,
    3370              :                                      tree accessor_decl)
    3371              : {
    3372          140 :   pretty_printer pp;
    3373          140 :   pp_string (&pp, IDENTIFIER_POINTER (DECL_NAME (accessor_decl)));
    3374          140 :   pp_string (&pp, "()");
    3375          140 :   richloc->add_fixit_replace (pp_formatted_text (&pp));
    3376          140 : }
    3377              : 
    3378              : /* If an access failure was recorded, then attempt to locate an
    3379              :    accessor function for the pertinent field, and if one is
    3380              :    available, add a note and fix-it hint suggesting using it.  */
    3381              : 
    3382              : void
    3383     94722346 : access_failure_info::maybe_suggest_accessor (bool const_p) const
    3384              : {
    3385     94722346 :   tree accessor = get_any_accessor (const_p);
    3386     94722346 :   if (accessor == NULL_TREE)
    3387     94722248 :     return;
    3388           98 :   rich_location richloc (line_table, input_location);
    3389           98 :   add_fixit_hint (&richloc, accessor);
    3390           98 :   inform (&richloc, "field %q#D can be accessed via %q#D",
    3391           98 :           m_diag_decl, accessor);
    3392           98 : }
    3393              : 
    3394              : /* Subroutine of finish_class_member_access_expr.
    3395              :    Issue an error about NAME not being a member of ACCESS_PATH (or
    3396              :    OBJECT_TYPE), potentially providing a fix-it hint for misspelled
    3397              :    names.  */
    3398              : 
    3399              : static void
    3400          330 : complain_about_unrecognized_member (tree access_path, tree name,
    3401              :                                     tree object_type)
    3402              : {
    3403              :   /* Attempt to provide a hint about misspelled names.  */
    3404          330 :   tree guessed_id = lookup_member_fuzzy (access_path, name,
    3405              :                                          /*want_type=*/false);
    3406          330 :   if (guessed_id == NULL_TREE)
    3407              :     {
    3408              :       /* No hint.  */
    3409          223 :       error ("%q#T has no member named %qE",
    3410          223 :              TREE_CODE (access_path) == TREE_BINFO
    3411            6 :              ? TREE_TYPE (access_path) : object_type, name);
    3412          223 :       return;
    3413              :     }
    3414              : 
    3415          107 :   location_t bogus_component_loc = input_location;
    3416          107 :   gcc_rich_location rich_loc (bogus_component_loc);
    3417              : 
    3418              :   /* Check that the guessed name is accessible along access_path.  */
    3419          107 :   access_failure_info afi;
    3420          107 :   lookup_member (access_path, guessed_id, /*protect=*/1,
    3421              :                  /*want_type=*/false, /*complain=*/false,
    3422              :                  &afi);
    3423          107 :   if (afi.was_inaccessible_p ())
    3424              :     {
    3425           70 :       tree accessor = afi.get_any_accessor (TYPE_READONLY (object_type));
    3426           70 :       if (accessor)
    3427              :         {
    3428              :           /* The guessed name isn't directly accessible, but can be accessed
    3429              :              via an accessor member function.  */
    3430           42 :           afi.add_fixit_hint (&rich_loc, accessor);
    3431           42 :           error_at (&rich_loc,
    3432              :                     "%q#T has no member named %qE;"
    3433              :                     " did you mean %q#D? (accessible via %q#D)",
    3434           42 :                     TREE_CODE (access_path) == TREE_BINFO
    3435            0 :                     ? TREE_TYPE (access_path) : object_type,
    3436              :                     name, afi.get_diag_decl (), accessor);
    3437              :         }
    3438              :       else
    3439              :         {
    3440              :           /* The guessed name isn't directly accessible, and no accessor
    3441              :              member function could be found.  */
    3442           28 :           auto_diagnostic_group d;
    3443           28 :           error_at (&rich_loc,
    3444              :                     "%q#T has no member named %qE;"
    3445              :                     " did you mean %q#D? (not accessible from this context)",
    3446           28 :                     TREE_CODE (access_path) == TREE_BINFO
    3447            0 :                     ? TREE_TYPE (access_path) : object_type,
    3448              :                     name, afi.get_diag_decl ());
    3449           28 :           complain_about_access (afi.get_decl (), afi.get_diag_decl (),
    3450              :                                  afi.get_diag_decl (), false, ak_none);
    3451           28 :         }
    3452              :     }
    3453              :   else
    3454              :     {
    3455              :       /* The guessed name is directly accessible; suggest it.  */
    3456           37 :       rich_loc.add_fixit_misspelled_id (bogus_component_loc,
    3457              :                                         guessed_id);
    3458           37 :       error_at (&rich_loc,
    3459              :                 "%q#T has no member named %qE;"
    3460              :                 " did you mean %qE?",
    3461           37 :                 TREE_CODE (access_path) == TREE_BINFO
    3462            0 :                 ? TREE_TYPE (access_path) : object_type,
    3463              :                 name, guessed_id);
    3464              :     }
    3465          107 : }
    3466              : 
    3467              : /* This function is called by the parser to process a class member
    3468              :    access expression of the form OBJECT.NAME.  NAME is a node used by
    3469              :    the parser to represent a name; it is not yet a DECL, except when
    3470              :    SPLICE_P.  It may, however, be a BASELINK where the BASELINK_FUNCTIONS
    3471              :    is a TEMPLATE_ID_EXPR.  Templates must be looked up by the parser, and
    3472              :    there is no reason to do the lookup twice, so the parser keeps the
    3473              :    BASELINK.  TEMPLATE_P is true iff NAME was explicitly declared to
    3474              :    be a template via the use of the "A::template B" syntax.  SPLICE_P
    3475              :    is true if NAME was designated by a splice-expression.  */
    3476              : 
    3477              : tree
    3478    189469974 : finish_class_member_access_expr (cp_expr object, tree name, bool template_p,
    3479              :                                  tsubst_flags_t complain,
    3480              :                                  bool splice_p/*=false*/)
    3481              : {
    3482    189469974 :   tree expr;
    3483    189469974 :   tree object_type;
    3484    189469974 :   tree member;
    3485    189469974 :   tree access_path = NULL_TREE;
    3486    189469974 :   tree orig_object = object;
    3487    189469974 :   tree orig_name = name;
    3488              : 
    3489    189469974 :   if (object == error_mark_node || name == error_mark_node)
    3490              :     return error_mark_node;
    3491              : 
    3492              :   /* If OBJECT is an ObjC class instance, we must obey ObjC access rules.  */
    3493    189469431 :   if (!objc_is_public (object, name))
    3494            0 :     return error_mark_node;
    3495              : 
    3496    189469431 :   object_type = TREE_TYPE (object);
    3497              : 
    3498    189469431 :   if (processing_template_decl)
    3499              :     {
    3500    157055026 :       if (/* If OBJECT is dependent, so is OBJECT.NAME.  */
    3501    157055026 :           type_dependent_object_expression_p (object)
    3502              :           /* If NAME is "f<args>", where either 'f' or 'args' is
    3503              :              dependent, then the expression is dependent.  */
    3504     73810491 :           || (TREE_CODE (name) == TEMPLATE_ID_EXPR
    3505       579479 :               && dependent_template_id_p (TREE_OPERAND (name, 0),
    3506       579479 :                                           TREE_OPERAND (name, 1)))
    3507              :           /* If NAME is "T::X" where "T" is dependent, then the
    3508              :              expression is dependent.  */
    3509     73523178 :           || (TREE_CODE (name) == SCOPE_REF
    3510       103411 :               && TYPE_P (TREE_OPERAND (name, 0))
    3511       103411 :               && dependent_scope_p (TREE_OPERAND (name, 0)))
    3512              :           /* If NAME is operator T where "T" is dependent, we can't
    3513              :              lookup until we instantiate the T.  */
    3514     73419990 :           || (TREE_CODE (name) == IDENTIFIER_NODE
    3515     72806121 :               && IDENTIFIER_CONV_OP_P (name)
    3516           57 :               && dependent_type_p (TREE_TYPE (name)))
    3517              :           /* This is OBJECT.[:R:], which is dependent.  */
    3518     73419939 :           || dependent_splice_p (name)
    3519              :           /* This is OBJECT.[:T::R:], which is dependent.  */
    3520    230474547 :           || (TREE_CODE (name) == SCOPE_REF
    3521          223 :               && dependent_splice_p (TREE_OPERAND (name, 1))))
    3522              :         {
    3523     97801991 :         dependent:
    3524     97801991 :           expr = build_min_nt_loc (UNKNOWN_LOCATION, COMPONENT_REF,
    3525              :                                    orig_object, orig_name, NULL_TREE);
    3526     97801991 :           COMPONENT_REF_SPLICE_P (expr) = splice_p;
    3527     97801991 :           return expr;
    3528              :         }
    3529              :     }
    3530     32414405 :   else if (c_dialect_objc ()
    3531    105833926 :            && identifier_p (name)
    3532     32414405 :            && (expr = objc_maybe_build_component_ref (object, name)))
    3533              :     return expr;
    3534              : 
    3535              :   /* [expr.ref]
    3536              : 
    3537              :      The type of the first expression shall be "class object" (of a
    3538              :      complete type).  */
    3539    105833926 :   if (!currently_open_class (object_type)
    3540    105833926 :       && !complete_type_or_maybe_complain (object_type, object, complain))
    3541          123 :     return error_mark_node;
    3542    105833803 :   if (!CLASS_TYPE_P (object_type))
    3543              :     {
    3544       270660 :       if (complain & tf_error)
    3545              :         {
    3546          135 :           if (INDIRECT_TYPE_P (object_type)
    3547          135 :               && CLASS_TYPE_P (TREE_TYPE (object_type)))
    3548           23 :             error ("request for member %qD in %qE, which is of pointer "
    3549              :                    "type %qT (maybe you meant to use %<->%> ?)",
    3550              :                    name, object.get_value (), object_type);
    3551              :           else
    3552          112 :             error ("request for member %qD in %qE, which is of non-class "
    3553              :                    "type %qT", name, object.get_value (), object_type);
    3554              :         }
    3555       270660 :       return error_mark_node;
    3556              :     }
    3557              : 
    3558    105563143 :   if (BASELINK_P (name))
    3559              :     /* A member function that has already been looked up.  */
    3560              :     member = name;
    3561     94972635 :   else if (TREE_CODE (name) == TREE_BINFO)
    3562              :     {
    3563              :       /* Splicing a base class subobject.  We can only get here via
    3564              :          e1.[:e2:].  */
    3565           92 :       expr = build_base_path (PLUS_EXPR, object, name, /*nonnull=*/true,
    3566              :                               complain);
    3567           92 :       if (expr == error_mark_node && (complain & tf_error))
    3568            4 :         error_not_base_type (BINFO_TYPE (name), object_type);
    3569           92 :       return expr;
    3570              :     }
    3571              :   else
    3572              :     {
    3573     94972543 :       bool is_template_id = false;
    3574     94972543 :       tree template_args = NULL_TREE;
    3575     94972543 :       tree scope = NULL_TREE;
    3576              : 
    3577     94972543 :       access_path = object_type;
    3578              : 
    3579     94972543 :       if (TREE_CODE (name) == SCOPE_REF)
    3580              :         {
    3581              :           /* A qualified name.  The qualifying class or namespace `S'
    3582              :              has already been looked up; it is either a TYPE or a
    3583              :              NAMESPACE_DECL.  */
    3584         1785 :           scope = TREE_OPERAND (name, 0);
    3585         1785 :           name = TREE_OPERAND (name, 1);
    3586              : 
    3587              :           /* If SCOPE is a namespace, then the qualified name does not
    3588              :              name a member of OBJECT_TYPE.  */
    3589         1785 :           if (TREE_CODE (scope) == NAMESPACE_DECL)
    3590              :             {
    3591            0 :               if (complain & tf_error)
    3592            0 :                 error ("%<%D::%D%> is not a member of %qT",
    3593              :                        scope, name, object_type);
    3594            0 :               return error_mark_node;
    3595              :             }
    3596              :         }
    3597     94970758 :       else if (splice_p && valid_splice_for_member_access_p (name))
    3598              :         {
    3599         1332 :           scope = context_for_name_lookup (OVL_FIRST (name));
    3600         1332 :           if (!CLASS_TYPE_P (scope))
    3601              :             {
    3602           10 :               if (complain & tf_error)
    3603              :                 {
    3604           10 :                   auto_diagnostic_group d;
    3605           10 :                   error ("%q#D is not a member of %qT", name, object_type);
    3606           20 :                   inform (DECL_SOURCE_LOCATION (OVL_FIRST (name)), "declared here");
    3607           10 :                 }
    3608           10 :               return error_mark_node;
    3609              :             }
    3610              :         }
    3611              : 
    3612     94972533 :       if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
    3613              :         {
    3614       433536 :           is_template_id = true;
    3615       433536 :           template_args = TREE_OPERAND (name, 1);
    3616       433536 :           name = TREE_OPERAND (name, 0);
    3617              : 
    3618       433536 :           if (splice_p
    3619       434994 :               && (DECL_FUNCTION_TEMPLATE_P (OVL_FIRST (name))
    3620          162 :                   || variable_template_p (name)))
    3621          486 :             scope = DECL_CONTEXT (OVL_FIRST (name));
    3622       845216 :           else if (!identifier_p (name))
    3623       412236 :             name = OVL_NAME (name);
    3624              :         }
    3625              : 
    3626     94972533 :       if (scope)
    3627              :         {
    3628         3593 :           if (TREE_CODE (scope) == ENUMERAL_TYPE)
    3629              :             {
    3630           12 :               gcc_assert (!is_template_id);
    3631              :               /* Looking up a member enumerator (c++/56793).  */
    3632           24 :               if (!TYPE_CLASS_SCOPE_P (scope)
    3633           21 :                   || !DERIVED_FROM_P (TYPE_CONTEXT (scope), object_type))
    3634              :                 {
    3635            3 :                   if (complain & tf_error)
    3636            3 :                     error ("%<%D::%D%> is not a member of %qT",
    3637              :                            scope, name, object_type);
    3638            3 :                   return error_mark_node;
    3639              :                 }
    3640            9 :               tree val;
    3641            9 :               if (splice_p && TREE_CODE (name) == CONST_DECL)
    3642              :                 val = name;
    3643              :               else
    3644            9 :                 val = lookup_enumerator (scope, name);
    3645            9 :               if (!val)
    3646              :                 {
    3647            6 :                   if (complain & tf_error)
    3648            6 :                     error ("%qD is not a member of %qD",
    3649              :                            name, scope);
    3650            6 :                   return error_mark_node;
    3651              :                 }
    3652              : 
    3653            3 :               if (TREE_SIDE_EFFECTS (object))
    3654            0 :                 val = build2 (COMPOUND_EXPR, TREE_TYPE (val), object, val);
    3655            3 :               return val;
    3656              :             }
    3657              : 
    3658         3581 :           gcc_assert (CLASS_TYPE_P (scope));
    3659         3581 :           gcc_assert (identifier_p (name)
    3660              :                       || TREE_CODE (name) == BIT_NOT_EXPR
    3661              :                       || (splice_p && valid_splice_for_member_access_p (name)));
    3662              : 
    3663         3581 :           if (constructor_name_p (name, scope))
    3664              :             {
    3665            3 :               if (complain & tf_error)
    3666            3 :                 error ("cannot call constructor %<%T::%D%> directly",
    3667              :                        scope, name);
    3668            3 :               return error_mark_node;
    3669              :             }
    3670              : 
    3671              :           /* NAME may refer to a static data member, in which case there is
    3672              :              one copy of the data member that is shared by all the objects of
    3673              :              the class.  So NAME can be unambiguously referred to even if
    3674              :              there are multiple indirect base classes containing NAME.  */
    3675        10734 :           const base_access ba = [scope, name, splice_p] ()
    3676              :             {
    3677              :               /* [class.access.base]/5: A member m is accessible at the
    3678              :                  point R when designated in class N if
    3679              :                  -- m is designated by a splice-expression  */
    3680         3578 :               if (splice_p)
    3681              :                 return ba_unique;
    3682         1770 :               if (identifier_p (name))
    3683              :                 {
    3684         1633 :                   tree m = lookup_member (scope, name, /*protect=*/0,
    3685              :                                           /*want_type=*/false, tf_none);
    3686         1633 :                   if (!m || shared_member_p (m))
    3687           32 :                     return ba_any;
    3688              :                 }
    3689              :               return ba_check;
    3690         3578 :             } ();
    3691              : 
    3692              :           /* Find the base of OBJECT_TYPE corresponding to SCOPE.  */
    3693         3578 :           access_path = lookup_base (object_type, scope, ba, NULL, complain);
    3694         3578 :           if (access_path == error_mark_node)
    3695              :             return error_mark_node;
    3696         3548 :           if (!access_path)
    3697              :             {
    3698           36 :               if (any_dependent_bases_p (object_type))
    3699            6 :                 goto dependent;
    3700           30 :               if (complain & tf_error)
    3701           30 :                 error ("%qT is not a base of %qT", scope, object_type);
    3702           30 :               return error_mark_node;
    3703              :             }
    3704              :         }
    3705              : 
    3706     94972452 :       if (TREE_CODE (name) == BIT_NOT_EXPR)
    3707              :         {
    3708       248340 :           if (dependent_type_p (object_type))
    3709              :             /* The destructor isn't declared yet.  */
    3710        46156 :             goto dependent;
    3711       202184 :           member = lookup_destructor (object, scope, name, complain);
    3712              :         }
    3713     94724112 :       else if (splice_p && valid_splice_for_member_access_p (name))
    3714              :         {
    3715         2630 :           member = name;
    3716         1766 :           name = OVL_FIRST (name);
    3717         1766 :           if (any_dependent_type_attributes_p (DECL_ATTRIBUTES (name)))
    3718              :             /* Dependent type attributes on the decl mean that the TREE_TYPE is
    3719              :                wrong, so don't use it.  */
    3720            0 :             goto dependent;
    3721         1766 :           if (is_overloaded_fn (name))
    3722         1414 :             member
    3723         1414 :               = build_baselink (access_path, TYPE_BINFO (object_type), member,
    3724         1414 :                                 IDENTIFIER_CONV_OP_P (DECL_NAME (name))
    3725            0 :                                 ? TREE_TYPE (DECL_NAME (name)) : NULL_TREE);
    3726              :         }
    3727              :       else
    3728              :         {
    3729              :           /* Look up the member.  */
    3730     94722346 :           {
    3731     94722346 :             auto_diagnostic_group d;
    3732     94722346 :             access_failure_info afi;
    3733     94722346 :             if (processing_template_decl)
    3734              :               /* Even though this class member access expression is at this
    3735              :                  point not dependent, the member itself may be dependent, and
    3736              :                  we must not potentially push a access check for a dependent
    3737              :                  member onto TI_DEFERRED_ACCESS_CHECKS.  So don't check access
    3738              :                  ahead of time here; we're going to redo this member lookup at
    3739              :                  instantiation time anyway.  */
    3740     73098277 :               push_deferring_access_checks (dk_no_check);
    3741     94722346 :             member = lookup_member (access_path, name, /*protect=*/1,
    3742              :                                     /*want_type=*/false, complain,
    3743              :                                     &afi);
    3744     94722346 :             if (processing_template_decl)
    3745     73098277 :               pop_deferring_access_checks ();
    3746     94722346 :             afi.maybe_suggest_accessor (TYPE_READONLY (object_type));
    3747     94722346 :           }
    3748     94722346 :           if (member == NULL_TREE)
    3749              :             {
    3750      8993213 :               if (dependentish_scope_p (object_type))
    3751              :                 /* Try again at instantiation time.  */
    3752      8976550 :                 goto dependent;
    3753        16663 :               if (complain & tf_error)
    3754          330 :                 complain_about_unrecognized_member (access_path, name,
    3755              :                                                     object_type);
    3756        16663 :               return error_mark_node;
    3757              :             }
    3758     85729133 :           if (member == error_mark_node)
    3759              :             return error_mark_node;
    3760     85729087 :           if (DECL_P (member)
    3761     85729087 :               && any_dependent_type_attributes_p (DECL_ATTRIBUTES (member)))
    3762              :             /* Dependent type attributes on the decl mean that the TREE_TYPE is
    3763              :                wrong, so don't use it.  */
    3764            6 :             goto dependent;
    3765     85729081 :           if (TREE_CODE (member) == USING_DECL && DECL_DEPENDENT_P (member))
    3766      5143768 :             goto dependent;
    3767              :         }
    3768              : 
    3769     80789263 :       if (is_template_id)
    3770              :         {
    3771       433428 :           tree templ = member;
    3772              : 
    3773       433428 :           if (BASELINK_P (templ))
    3774       433174 :             member = lookup_template_function (templ, template_args);
    3775          254 :           else if (variable_template_p (templ))
    3776          254 :             member = (lookup_and_finish_template_variable
    3777          254 :                       (templ, template_args, complain));
    3778              :           else
    3779              :             {
    3780            0 :               if (complain & tf_error)
    3781            0 :                 error ("%qD is not a member template function", name);
    3782            0 :               return error_mark_node;
    3783              :             }
    3784              :         }
    3785              :     }
    3786              : 
    3787     91379771 :   if (TREE_UNAVAILABLE (member))
    3788           30 :     error_unavailable_use (member, NULL_TREE);
    3789     91379741 :   else if (TREE_DEPRECATED (member))
    3790           30 :     warn_deprecated_use (member, NULL_TREE);
    3791              : 
    3792     91379771 :   if (template_p)
    3793         9241 :     check_template_keyword (member);
    3794              : 
    3795     91379771 :   expr = build_class_member_access_expr (object, member, access_path,
    3796              :                                          /*preserve_reference=*/false,
    3797              :                                          complain);
    3798     91379771 :   if (processing_template_decl && expr != error_mark_node)
    3799              :     {
    3800     59252947 :       if (BASELINK_P (member))
    3801              :         {
    3802     44225760 :           if (TREE_CODE (orig_name) == SCOPE_REF)
    3803          175 :             BASELINK_QUALIFIED_P (member) = 1;
    3804              :           orig_name = member;
    3805              :         }
    3806     59252947 :       expr = build_min_non_dep (COMPONENT_REF, expr,
    3807              :                                 orig_object, orig_name,
    3808              :                                 NULL_TREE);
    3809    118505894 :       COMPONENT_REF_SPLICE_P (STRIP_REFERENCE_REF (expr)) = splice_p;
    3810              :     }
    3811              : 
    3812              :   return expr;
    3813              : }
    3814              : 
    3815              : /* Build a COMPONENT_REF of OBJECT and MEMBER with the appropriate
    3816              :    type.  */
    3817              : 
    3818              : tree
    3819       167727 : build_simple_component_ref (tree object, tree member)
    3820              : {
    3821       167727 :   tree type = cp_build_qualified_type (TREE_TYPE (member),
    3822       167727 :                                        cp_type_quals (TREE_TYPE (object)));
    3823       167727 :   return build3_loc (input_location,
    3824              :                      COMPONENT_REF, type,
    3825       167727 :                      object, member, NULL_TREE);
    3826              : }
    3827              : 
    3828              : /* Return an expression for the MEMBER_NAME field in the internal
    3829              :    representation of PTRMEM, a pointer-to-member function.  (Each
    3830              :    pointer-to-member function type gets its own RECORD_TYPE so it is
    3831              :    more convenient to access the fields by name than by FIELD_DECL.)
    3832              :    This routine converts the NAME to a FIELD_DECL and then creates the
    3833              :    node for the complete expression.  */
    3834              : 
    3835              : tree
    3836       167631 : build_ptrmemfunc_access_expr (tree ptrmem, tree member_name)
    3837              : {
    3838       167631 :   tree ptrmem_type;
    3839       167631 :   tree member;
    3840              : 
    3841       167631 :   if (TREE_CODE (ptrmem) == CONSTRUCTOR)
    3842              :     {
    3843          198 :       for (auto &e: CONSTRUCTOR_ELTS (ptrmem))
    3844           78 :         if (e.index && DECL_P (e.index) && DECL_NAME (e.index) == member_name)
    3845           60 :           return e.value;
    3846            0 :       gcc_unreachable ();
    3847              :     }
    3848              : 
    3849              :   /* This code is a stripped down version of
    3850              :      build_class_member_access_expr.  It does not work to use that
    3851              :      routine directly because it expects the object to be of class
    3852              :      type.  */
    3853       167571 :   ptrmem_type = TREE_TYPE (ptrmem);
    3854       167571 :   gcc_assert (TYPE_PTRMEMFUNC_P (ptrmem_type));
    3855       251255 :   for (member = TYPE_FIELDS (ptrmem_type); member;
    3856        83684 :        member = DECL_CHAIN (member))
    3857       251255 :     if (DECL_NAME (member) == member_name)
    3858              :       break;
    3859       167571 :   return build_simple_component_ref (ptrmem, member);
    3860              : }
    3861              : 
    3862              : /* Return a TREE_LIST of namespace-scope overloads for the given operator,
    3863              :    and for any other relevant operator.  */
    3864              : 
    3865              : static tree
    3866    137450325 : op_unqualified_lookup (tree_code code, bool is_assign)
    3867              : {
    3868    137450325 :   tree lookups = NULL_TREE;
    3869              : 
    3870    137450325 :   if (cxx_dialect >= cxx20 && !is_assign)
    3871              :     {
    3872    129918033 :       if (code == NE_EXPR)
    3873              :         {
    3874              :           /* != can get rewritten in terms of ==.  */
    3875      8275332 :           tree fnname = ovl_op_identifier (false, EQ_EXPR);
    3876      8275332 :           if (tree fns = lookup_name (fnname, LOOK_where::BLOCK_NAMESPACE))
    3877      8176316 :             lookups = tree_cons (fnname, fns, lookups);
    3878              :         }
    3879    121642701 :       else if (code == GT_EXPR || code == LE_EXPR
    3880    121642701 :                || code == LT_EXPR || code == GE_EXPR)
    3881              :         {
    3882              :           /* These can get rewritten in terms of <=>.  */
    3883     11285089 :           tree fnname = ovl_op_identifier (false, SPACESHIP_EXPR);
    3884     11285089 :           if (tree fns = lookup_name (fnname, LOOK_where::BLOCK_NAMESPACE))
    3885     10672629 :             lookups = tree_cons (fnname, fns, lookups);
    3886              :         }
    3887              :     }
    3888              : 
    3889    137450325 :   tree fnname = ovl_op_identifier (is_assign, code);
    3890    137450325 :   if (tree fns = lookup_name (fnname, LOOK_where::BLOCK_NAMESPACE))
    3891     74651271 :     lookups = tree_cons (fnname, fns, lookups);
    3892              : 
    3893    137450325 :   if (lookups)
    3894              :     return lookups;
    3895              :   else
    3896     62575004 :     return build_tree_list (NULL_TREE, NULL_TREE);
    3897              : }
    3898              : 
    3899              : /* Create a DEPENDENT_OPERATOR_TYPE for a dependent operator expression of
    3900              :    the given operator.  LOOKUPS, if non-NULL, is the result of phase 1
    3901              :    name lookup for the given operator.  */
    3902              : 
    3903              : tree
    3904    143547100 : build_dependent_operator_type (tree lookups, tree_code code, bool is_assign)
    3905              : {
    3906    143547100 :   if (lookups)
    3907              :     /* We're partially instantiating a dependent operator expression, and
    3908              :        LOOKUPS is the result of phase 1 name lookup that we performed
    3909              :        earlier at template definition time, so just reuse the corresponding
    3910              :        DEPENDENT_OPERATOR_TYPE.  */
    3911      6096775 :     return TREE_TYPE (lookups);
    3912              : 
    3913              :   /* Otherwise we're processing a dependent operator expression at template
    3914              :      definition time, so perform phase 1 name lookup now.  */
    3915    137450325 :   lookups = op_unqualified_lookup (code, is_assign);
    3916              : 
    3917    137450325 :   tree type = cxx_make_type (DEPENDENT_OPERATOR_TYPE);
    3918    137450325 :   DEPENDENT_OPERATOR_TYPE_SAVED_LOOKUPS (type) = lookups;
    3919    137450325 :   TREE_TYPE (lookups) = type;
    3920    137450325 :   return type;
    3921              : }
    3922              : 
    3923              : /* Given an expression PTR for a pointer, return an expression
    3924              :    for the value pointed to.
    3925              :    ERRORSTRING is the name of the operator to appear in error messages.
    3926              : 
    3927              :    This function may need to overload OPERATOR_FNNAME.
    3928              :    Must also handle REFERENCE_TYPEs for C++.  */
    3929              : 
    3930              : tree
    3931     49272033 : build_x_indirect_ref (location_t loc, tree expr, ref_operator errorstring,
    3932              :                       tree lookups, tsubst_flags_t complain)
    3933              : {
    3934     49272033 :   tree orig_expr = expr;
    3935     49272033 :   tree rval;
    3936     49272033 :   tree overload = NULL_TREE;
    3937              : 
    3938     49272033 :   if (processing_template_decl)
    3939              :     {
    3940              :       /* Retain the type if we know the operand is a pointer.  */
    3941     28758292 :       if (TREE_TYPE (expr) && INDIRECT_TYPE_P (TREE_TYPE (expr)))
    3942              :         {
    3943     14120389 :           if (expr == current_class_ptr
    3944     14120389 :               || (TREE_CODE (expr) == NOP_EXPR
    3945      9334077 :                   && TREE_OPERAND (expr, 0) == current_class_ptr
    3946      9224336 :                   && (same_type_ignoring_top_level_qualifiers_p
    3947      9224336 :                         (TREE_TYPE (expr), TREE_TYPE (current_class_ptr)))))
    3948      9224335 :             return current_class_ref;
    3949      4896054 :           return build_min (INDIRECT_REF, TREE_TYPE (TREE_TYPE (expr)), expr);
    3950              :         }
    3951     14637903 :       if (type_dependent_expression_p (expr))
    3952              :         {
    3953     14502466 :           expr = build_min_nt_loc (loc, INDIRECT_REF, expr);
    3954     14502466 :           TREE_TYPE (expr)
    3955     14502466 :             = build_dependent_operator_type (lookups, INDIRECT_REF, false);
    3956     14502466 :           return expr;
    3957              :         }
    3958              :     }
    3959              : 
    3960     20649178 :   rval = build_new_op (loc, INDIRECT_REF, LOOKUP_NORMAL, expr,
    3961              :                        NULL_TREE, NULL_TREE, lookups,
    3962              :                        &overload, complain);
    3963     20649178 :   if (!rval)
    3964            0 :     rval = cp_build_indirect_ref (loc, expr, errorstring, complain);
    3965              : 
    3966     20649178 :   if (processing_template_decl && rval != error_mark_node)
    3967              :     {
    3968       133604 :       if (overload != NULL_TREE)
    3969       133573 :         return (build_min_non_dep_op_overload
    3970       133573 :                 (INDIRECT_REF, rval, overload, orig_expr));
    3971              : 
    3972           31 :       return build_min_non_dep (INDIRECT_REF, rval, orig_expr);
    3973              :     }
    3974              :   else
    3975              :     return rval;
    3976              : }
    3977              : 
    3978              : /* Like c-family strict_aliasing_warning, but don't warn for dependent
    3979              :    types or expressions.  */
    3980              : 
    3981              : static bool
    3982       645341 : cp_strict_aliasing_warning (location_t loc, tree type, tree expr)
    3983              : {
    3984       645341 :   if (processing_template_decl)
    3985              :     {
    3986        45559 :       tree e = expr;
    3987        45559 :       STRIP_NOPS (e);
    3988        45559 :       if (dependent_type_p (type) || type_dependent_expression_p (e))
    3989         7412 :         return false;
    3990              :     }
    3991       637929 :   return strict_aliasing_warning (loc, type, expr);
    3992              : }
    3993              : 
    3994              : /* The implementation of the above, and of indirection implied by other
    3995              :    constructs.  If DO_FOLD is true, fold away INDIRECT_REF of ADDR_EXPR.  */
    3996              : 
    3997              : static tree
    3998    349049719 : cp_build_indirect_ref_1 (location_t loc, tree ptr, ref_operator errorstring,
    3999              :                          tsubst_flags_t complain, bool do_fold)
    4000              : {
    4001    349049719 :   tree pointer, type;
    4002              : 
    4003              :   /* RO_NULL should only be used with the folding entry points below, not
    4004              :      cp_build_indirect_ref.  */
    4005    349049719 :   gcc_checking_assert (errorstring != RO_NULL || do_fold);
    4006              : 
    4007    349049719 :   if (ptr == current_class_ptr
    4008    349049719 :       || (TREE_CODE (ptr) == NOP_EXPR
    4009     37310623 :           && TREE_OPERAND (ptr, 0) == current_class_ptr
    4010     19757266 :           && (same_type_ignoring_top_level_qualifiers_p
    4011     19757266 :               (TREE_TYPE (ptr), TREE_TYPE (current_class_ptr)))))
    4012     21196038 :     return current_class_ref;
    4013              : 
    4014    327853681 :   pointer = (TYPE_REF_P (TREE_TYPE (ptr))
    4015    327853681 :              ? ptr : decay_conversion (ptr, complain));
    4016    327853681 :   if (pointer == error_mark_node)
    4017              :     return error_mark_node;
    4018              : 
    4019    327847842 :   type = TREE_TYPE (pointer);
    4020              : 
    4021    327847842 :   if (INDIRECT_TYPE_P (type))
    4022              :     {
    4023              :       /* [expr.unary.op]
    4024              : 
    4025              :          If the type of the expression is "pointer to T," the type
    4026              :          of  the  result  is  "T."  */
    4027    327847300 :       tree t = TREE_TYPE (type);
    4028              : 
    4029    309040102 :       if ((CONVERT_EXPR_P (ptr)
    4030    226468100 :            || TREE_CODE (ptr) == VIEW_CONVERT_EXPR)
    4031    412721617 :           && (!CLASS_TYPE_P (t) || !CLASSTYPE_EMPTY_P (t)))
    4032              :         {
    4033              :           /* If a warning is issued, mark it to avoid duplicates from
    4034              :              the backend.  This only needs to be done at
    4035              :              warn_strict_aliasing > 2.  */
    4036     81227587 :           if (warn_strict_aliasing > 2
    4037     81774096 :               && cp_strict_aliasing_warning (EXPR_LOCATION (ptr),
    4038       546509 :                                              type, TREE_OPERAND (ptr, 0)))
    4039            6 :             suppress_warning (ptr, OPT_Wstrict_aliasing);
    4040              :         }
    4041              : 
    4042    327847300 :       if (VOID_TYPE_P (t))
    4043              :         {
    4044              :           /* A pointer to incomplete type (other than cv void) can be
    4045              :              dereferenced [expr.unary.op]/1  */
    4046           48 :           if (complain & tf_error)
    4047           19 :             error_at (loc, "%qT is not a pointer-to-object type", type);
    4048           48 :           return error_mark_node;
    4049              :         }
    4050    317322385 :       else if (do_fold && TREE_CODE (pointer) == ADDR_EXPR
    4051    334992864 :                && same_type_p (t, TREE_TYPE (TREE_OPERAND (pointer, 0))))
    4052              :         /* The POINTER was something like `&x'.  We simplify `*&x' to
    4053              :            `x'.  This can change the value category: '*&TARGET_EXPR'
    4054              :            is an lvalue and folding it into 'TARGET_EXPR' turns it into
    4055              :            a prvalue of class type.  */
    4056      7145554 :         return TREE_OPERAND (pointer, 0);
    4057              :       else
    4058              :         {
    4059    320701698 :           tree ref = build1 (INDIRECT_REF, t, pointer);
    4060              : 
    4061              :           /* We *must* set TREE_READONLY when dereferencing a pointer to const,
    4062              :              so that we get the proper error message if the result is used
    4063              :              to assign to.  Also, &* is supposed to be a no-op.  */
    4064    320701698 :           TREE_READONLY (ref) = CP_TYPE_CONST_P (t);
    4065    320701698 :           TREE_THIS_VOLATILE (ref) = CP_TYPE_VOLATILE_P (t);
    4066    320701698 :           TREE_SIDE_EFFECTS (ref)
    4067    320701698 :             = (TREE_THIS_VOLATILE (ref) || TREE_SIDE_EFFECTS (pointer));
    4068    320701698 :           return ref;
    4069              :         }
    4070              :     }
    4071          542 :   else if (!(complain & tf_error))
    4072              :     /* Don't emit any errors; we'll just return ERROR_MARK_NODE later.  */
    4073              :     ;
    4074              :   /* `pointer' won't be an error_mark_node if we were given a
    4075              :      pointer to member, so it's cool to check for this here.  */
    4076           41 :   else if (TYPE_PTRMEM_P (type))
    4077           15 :     switch (errorstring)
    4078              :       {
    4079            0 :          case RO_ARRAY_INDEXING:
    4080            0 :            error_at (loc,
    4081              :                      "invalid use of array indexing on pointer to member");
    4082            0 :            break;
    4083           12 :          case RO_UNARY_STAR:
    4084           12 :            error_at (loc, "invalid use of unary %<*%> on pointer to member");
    4085           12 :            break;
    4086            0 :          case RO_IMPLICIT_CONVERSION:
    4087            0 :            error_at (loc, "invalid use of implicit conversion on pointer "
    4088              :                      "to member");
    4089            0 :            break;
    4090            3 :          case RO_ARROW_STAR:
    4091            3 :            error_at (loc, "left hand operand of %<->*%> must be a pointer to "
    4092              :                      "class, but is a pointer to member of type %qT", type);
    4093            3 :            break;
    4094            0 :          default:
    4095            0 :            gcc_unreachable ();
    4096              :       }
    4097           26 :   else if (pointer != error_mark_node)
    4098           26 :     invalid_indirection_error (loc, type, errorstring);
    4099              : 
    4100          542 :   return error_mark_node;
    4101              : }
    4102              : 
    4103              : /* Entry point used by c-common, which expects folding.  */
    4104              : 
    4105              : tree
    4106        67602 : build_indirect_ref (location_t loc, tree ptr, ref_operator errorstring)
    4107              : {
    4108        67602 :   return cp_build_indirect_ref_1 (loc, ptr, errorstring,
    4109        67602 :                                   tf_warning_or_error, true);
    4110              : }
    4111              : 
    4112              : /* Entry point used by internal indirection needs that don't correspond to any
    4113              :    syntactic construct.  */
    4114              : 
    4115              : tree
    4116    320950382 : cp_build_fold_indirect_ref (tree pointer)
    4117              : {
    4118    320950382 :   return cp_build_indirect_ref_1 (input_location, pointer, RO_NULL,
    4119    320950382 :                                   tf_warning_or_error, true);
    4120              : }
    4121              : 
    4122              : /* Entry point used by indirection needs that correspond to some syntactic
    4123              :    construct.  */
    4124              : 
    4125              : tree
    4126     28031735 : cp_build_indirect_ref (location_t loc, tree ptr, ref_operator errorstring,
    4127              :                        tsubst_flags_t complain)
    4128              : {
    4129     28031735 :   return cp_build_indirect_ref_1 (loc, ptr, errorstring, complain, false);
    4130              : }
    4131              : 
    4132              : /* This handles expressions of the form "a[i]", which denotes
    4133              :    an array reference.
    4134              : 
    4135              :    This is logically equivalent in C to *(a+i), but we may do it differently.
    4136              :    If A is a variable or a member, we generate a primitive ARRAY_REF.
    4137              :    This avoids forcing the array out of registers, and can work on
    4138              :    arrays that are not lvalues (for example, members of structures returned
    4139              :    by functions).
    4140              : 
    4141              :    If INDEX is of some user-defined type, it must be converted to
    4142              :    integer type.  Otherwise, to make a compatible PLUS_EXPR, it
    4143              :    will inherit the type of the array, which will be some pointer type.
    4144              : 
    4145              :    LOC is the location to use in building the array reference.  */
    4146              : 
    4147              : tree
    4148      5933758 : cp_build_array_ref (location_t loc, tree array, tree idx,
    4149              :                     tsubst_flags_t complain)
    4150              : {
    4151      5933758 :   tree ret;
    4152              : 
    4153      5933758 :   if (idx == 0)
    4154              :     {
    4155            0 :       if (complain & tf_error)
    4156            0 :         error_at (loc, "subscript missing in array reference");
    4157            0 :       return error_mark_node;
    4158              :     }
    4159              : 
    4160      5933758 :   if (TREE_TYPE (array) == error_mark_node
    4161      5933758 :       || TREE_TYPE (idx) == error_mark_node)
    4162              :     return error_mark_node;
    4163              : 
    4164              :   /* 0[array] */
    4165      5933758 :   if (TREE_CODE (TREE_TYPE (idx)) == ARRAY_TYPE
    4166      5933758 :       && TREE_CODE (TREE_TYPE (array)) != ARRAY_TYPE)
    4167              :     {
    4168           10 :       std::swap (array, idx);
    4169              : 
    4170           10 :       tree first = NULL_TREE;
    4171           10 :       if (flag_strong_eval_order == 2 && TREE_SIDE_EFFECTS (array))
    4172            9 :         idx = first = save_expr (idx);
    4173           10 :       ret = cp_build_array_ref (loc, array, idx, complain);
    4174              : 
    4175           10 :       if (first)
    4176            9 :         ret = build2 (COMPOUND_EXPR, TREE_TYPE (ret), first, ret);
    4177           10 :       return ret;
    4178              :     }
    4179              : 
    4180              :   /* If ARRAY is a COMPOUND_EXPR or COND_EXPR, move our reference
    4181              :      inside it.  */
    4182      5933748 :   switch (TREE_CODE (array))
    4183              :     {
    4184           28 :     case COMPOUND_EXPR:
    4185           28 :       {
    4186           28 :         tree value = cp_build_array_ref (loc, TREE_OPERAND (array, 1), idx,
    4187              :                                          complain);
    4188           28 :         ret = build2 (COMPOUND_EXPR, TREE_TYPE (value),
    4189           28 :                       TREE_OPERAND (array, 0), value);
    4190           28 :         SET_EXPR_LOCATION (ret, loc);
    4191           28 :         return ret;
    4192              :       }
    4193              : 
    4194           73 :     case COND_EXPR:
    4195           73 :       tree op0, op1, op2;
    4196           73 :       op0 = TREE_OPERAND (array, 0);
    4197           73 :       op1 = TREE_OPERAND (array, 1);
    4198           73 :       op2 = TREE_OPERAND (array, 2);
    4199           73 :       if (TREE_SIDE_EFFECTS (idx) || !tree_invariant_p (idx))
    4200              :         {
    4201              :           /* If idx could possibly have some SAVE_EXPRs, turning
    4202              :              (op0 ? op1 : op2)[idx] into
    4203              :              op0 ? op1[idx] : op2[idx] can lead into temporaries
    4204              :              initialized in one conditional path and uninitialized
    4205              :              uses of them in the other path.
    4206              :              And if idx is a really large expression, evaluating it
    4207              :              twice is also not optimal.
    4208              :              On the other side, op0 must be sequenced before evaluation
    4209              :              of op1 and op2 and for C++17 op0, op1 and op2 must be
    4210              :              sequenced before idx.
    4211              :              If idx is INTEGER_CST, we can just do the optimization
    4212              :              without any SAVE_EXPRs, if op1 and op2 are both ARRAY_TYPE
    4213              :              VAR_DECLs or COMPONENT_REFs thereof (so their address
    4214              :              is constant or relative to frame), optimize into
    4215              :              (SAVE_EXPR <op0>, SAVE_EXPR <idx>, SAVE_EXPR <op0>)
    4216              :              ? op1[SAVE_EXPR <idx>] : op2[SAVE_EXPR <idx>]
    4217              :              Otherwise avoid this optimization.  */
    4218           58 :           if (flag_strong_eval_order == 2)
    4219              :             {
    4220           39 :               if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE)
    4221              :                 {
    4222           30 :                   if (!address_invariant_p (op1) || !address_invariant_p (op2))
    4223              :                     {
    4224              :                       /* Force default conversion on array if
    4225              :                          we can't optimize this and array is ARRAY_TYPE
    4226              :                          COND_EXPR, we can't leave COND_EXPRs with
    4227              :                          ARRAY_TYPE in the IL.  */
    4228            8 :                       array = cp_default_conversion (array, complain);
    4229            8 :                       if (error_operand_p (array))
    4230            0 :                         return error_mark_node;
    4231              :                       break;
    4232              :                     }
    4233              :                 }
    4234           16 :               else if (!POINTER_TYPE_P (TREE_TYPE (array))
    4235            2 :                        || !tree_invariant_p (op1)
    4236           11 :                        || !tree_invariant_p (op2))
    4237              :                 break;
    4238              :             }
    4239           43 :           if (TREE_SIDE_EFFECTS (idx))
    4240              :             {
    4241           18 :               idx = save_expr (idx);
    4242           18 :               op0 = save_expr (op0);
    4243           18 :               warning_sentinel w (warn_unused_value);
    4244           18 :               tree tem = build_compound_expr (loc, op0, idx);
    4245           18 :               op0 = build_compound_expr (loc, tem, op0);
    4246           18 :             }
    4247              :         }
    4248           58 :       op1 = cp_build_array_ref (loc, op1, idx, complain);
    4249           58 :       op2 = cp_build_array_ref (loc, op2, idx, complain);
    4250           58 :       ret = build_conditional_expr (loc, op0, op1, op2, complain);
    4251           58 :       protected_set_expr_location (ret, loc);
    4252           58 :       return ret;
    4253              : 
    4254              :     default:
    4255              :       break;
    4256              :     }
    4257              : 
    4258      5933662 :   bool non_lvalue = convert_vector_to_array_for_subscript (loc, &array, idx);
    4259              : 
    4260      5933662 :   if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE)
    4261              :     {
    4262      1821768 :       tree rval, type;
    4263              : 
    4264      1821768 :       warn_array_subscript_with_type_char (loc, idx);
    4265              : 
    4266      1821768 :       if (!INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (idx)))
    4267              :         {
    4268            6 :           if (complain & tf_error)
    4269            6 :             error_at (loc, "array subscript is not an integer");
    4270            6 :           return error_mark_node;
    4271              :         }
    4272              : 
    4273              :       /* Apply integral promotions *after* noticing character types.
    4274              :          (It is unclear why we do these promotions -- the standard
    4275              :          does not say that we should.  In fact, the natural thing would
    4276              :          seem to be to convert IDX to ptrdiff_t; we're performing
    4277              :          pointer arithmetic.)  */
    4278      1821762 :       idx = cp_perform_integral_promotions (idx, complain);
    4279              : 
    4280      1821762 :       idx = maybe_fold_non_dependent_expr (idx, complain);
    4281              : 
    4282              :       /* An array that is indexed by a non-constant
    4283              :          cannot be stored in a register; we must be able to do
    4284              :          address arithmetic on its address.
    4285              :          Likewise an array of elements of variable size.  */
    4286      1821762 :       if (TREE_CODE (idx) != INTEGER_CST
    4287      1821762 :           || (COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (array)))
    4288       865124 :               && (TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))))
    4289              :                   != INTEGER_CST)))
    4290              :         {
    4291       957898 :           if (!cxx_mark_addressable (array, true))
    4292            0 :             return error_mark_node;
    4293              :         }
    4294              : 
    4295              :       /* An array that is indexed by a constant value which is not within
    4296              :          the array bounds cannot be stored in a register either; because we
    4297              :          would get a crash in store_bit_field/extract_bit_field when trying
    4298              :          to access a non-existent part of the register.  */
    4299      1821762 :       if (TREE_CODE (idx) == INTEGER_CST
    4300       865127 :           && TYPE_DOMAIN (TREE_TYPE (array))
    4301      2685500 :           && ! int_fits_type_p (idx, TYPE_DOMAIN (TREE_TYPE (array))))
    4302              :         {
    4303         3124 :           if (!cxx_mark_addressable (array))
    4304            0 :             return error_mark_node;
    4305              :         }
    4306              : 
    4307              :       /* Note in C++ it is valid to subscript a `register' array, since
    4308              :          it is valid to take the address of something with that
    4309              :          storage specification.  */
    4310      1821762 :       if (extra_warnings)
    4311              :         {
    4312        38844 :           tree foo = array;
    4313        59524 :           while (TREE_CODE (foo) == COMPONENT_REF)
    4314        20680 :             foo = TREE_OPERAND (foo, 0);
    4315            8 :           if (VAR_P (foo) && DECL_REGISTER (foo)
    4316        38844 :               && (complain & tf_warning))
    4317            0 :             warning_at (loc, OPT_Wextra,
    4318              :                         "subscripting array declared %<register%>");
    4319              :         }
    4320              : 
    4321      1821762 :       type = TREE_TYPE (TREE_TYPE (array));
    4322      1821762 :       rval = build4 (ARRAY_REF, type, array, idx, NULL_TREE, NULL_TREE);
    4323              :       /* Array ref is const/volatile if the array elements are
    4324              :          or if the array is..  */
    4325      5465286 :       TREE_READONLY (rval)
    4326      1821762 :         |= (CP_TYPE_CONST_P (type) | TREE_READONLY (array));
    4327      5465286 :       TREE_SIDE_EFFECTS (rval)
    4328      1821762 :         |= (CP_TYPE_VOLATILE_P (type) | TREE_SIDE_EFFECTS (array));
    4329      3643524 :       TREE_THIS_VOLATILE (rval)
    4330      1821762 :         |= (CP_TYPE_VOLATILE_P (type) | TREE_THIS_VOLATILE (array));
    4331      1821762 :       ret = require_complete_type (rval, complain);
    4332      1821762 :       protected_set_expr_location (ret, loc);
    4333      1821762 :       if (non_lvalue)
    4334        19994 :         ret = non_lvalue_loc (loc, ret);
    4335      1821762 :       return ret;
    4336              :     }
    4337              : 
    4338      4111894 :   {
    4339      4111894 :     tree ar = cp_default_conversion (array, complain);
    4340      4111894 :     tree ind = cp_default_conversion (idx, complain);
    4341      4111894 :     tree first = NULL_TREE;
    4342              : 
    4343      2656459 :     if (!processing_template_decl && flag_strong_eval_order == 2
    4344      6727838 :         && TREE_SIDE_EFFECTS (ind))
    4345        83619 :       ar = first = save_expr (ar);
    4346              : 
    4347              :     /* Put the integer in IND to simplify error checking.  */
    4348      4111894 :     if (TREE_CODE (TREE_TYPE (ar)) == INTEGER_TYPE)
    4349           57 :       std::swap (ar, ind);
    4350              : 
    4351      4111894 :     if (ar == error_mark_node || ind == error_mark_node)
    4352              :       return error_mark_node;
    4353              : 
    4354      4111894 :     if (!TYPE_PTR_P (TREE_TYPE (ar)))
    4355              :       {
    4356           33 :         if (complain & tf_error)
    4357            3 :           error_at (loc, "subscripted value is neither array nor pointer");
    4358           33 :         return error_mark_node;
    4359              :       }
    4360      4111861 :     if (TREE_CODE (TREE_TYPE (ind)) != INTEGER_TYPE)
    4361              :       {
    4362            0 :         if (complain & tf_error)
    4363            0 :           error_at (loc, "array subscript is not an integer");
    4364            0 :         return error_mark_node;
    4365              :       }
    4366              : 
    4367      4111861 :     warn_array_subscript_with_type_char (loc, idx);
    4368              : 
    4369      4111861 :     ret = cp_build_binary_op (input_location, PLUS_EXPR, ar, ind, complain);
    4370      4111861 :     if (first)
    4371        83619 :       ret = build2_loc (loc, COMPOUND_EXPR, TREE_TYPE (ret), first, ret);
    4372      4111861 :     ret = cp_build_indirect_ref (loc, ret, RO_ARRAY_INDEXING, complain);
    4373      4111861 :     protected_set_expr_location (ret, loc);
    4374      4111861 :     if (non_lvalue)
    4375            0 :       ret = non_lvalue_loc (loc, ret);
    4376              :     return ret;
    4377              :   }
    4378              : }
    4379              : 
    4380              : /* Entry point for Obj-C++.  */
    4381              : 
    4382              : tree
    4383      3622495 : build_array_ref (location_t loc, tree array, tree idx)
    4384              : {
    4385      3622495 :   return cp_build_array_ref (loc, array, idx, tf_warning_or_error);
    4386              : }
    4387              : 
    4388              : /* Resolve a pointer to member function.  INSTANCE is the object
    4389              :    instance to use, if the member points to a virtual member.
    4390              : 
    4391              :    This used to avoid checking for virtual functions if basetype
    4392              :    has no virtual functions, according to an earlier ANSI draft.
    4393              :    With the final ISO C++ rules, such an optimization is
    4394              :    incorrect: A pointer to a derived member can be static_cast
    4395              :    to pointer-to-base-member, as long as the dynamic object
    4396              :    later has the right member.  So now we only do this optimization
    4397              :    when we know the dynamic type of the object.  */
    4398              : 
    4399              : tree
    4400        83540 : get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function,
    4401              :                                   tsubst_flags_t complain)
    4402              : {
    4403        83540 :   if (TREE_CODE (function) == OFFSET_REF)
    4404            0 :     function = TREE_OPERAND (function, 1);
    4405              : 
    4406        83540 :   if (TYPE_PTRMEMFUNC_P (TREE_TYPE (function)))
    4407              :     {
    4408        83540 :       tree idx, delta, e1, e2, e3, vtbl;
    4409        83540 :       bool nonvirtual;
    4410        83540 :       tree fntype = TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (function));
    4411        83540 :       tree basetype = TYPE_METHOD_BASETYPE (TREE_TYPE (fntype));
    4412              : 
    4413        83540 :       tree instance_ptr = *instance_ptrptr;
    4414        83540 :       tree instance_save_expr = 0;
    4415        83540 :       if (instance_ptr == error_mark_node)
    4416              :         {
    4417            0 :           if (TREE_CODE (function) == PTRMEM_CST)
    4418              :             {
    4419              :               /* Extracting the function address from a pmf is only
    4420              :                  allowed with -Wno-pmf-conversions. It only works for
    4421              :                  pmf constants.  */
    4422            0 :               e1 = build_addr_func (PTRMEM_CST_MEMBER (function), complain);
    4423            0 :               e1 = convert (fntype, e1);
    4424            0 :               return e1;
    4425              :             }
    4426              :           else
    4427              :             {
    4428            0 :               if (complain & tf_error)
    4429            0 :                 error ("object missing in use of %qE", function);
    4430            0 :               return error_mark_node;
    4431              :             }
    4432              :         }
    4433              : 
    4434              :       /* True if we know that the dynamic type of the object doesn't have
    4435              :          virtual functions, so we can assume the PFN field is a pointer.  */
    4436        83540 :       nonvirtual = (COMPLETE_TYPE_P (basetype)
    4437        83504 :                     && !TYPE_POLYMORPHIC_P (basetype)
    4438       112298 :                     && resolves_to_fixed_type_p (instance_ptr, 0));
    4439              : 
    4440              :       /* If we don't really have an object (i.e. in an ill-formed
    4441              :          conversion from PMF to pointer), we can't resolve virtual
    4442              :          functions anyway.  */
    4443        83288 :       if (!nonvirtual && is_dummy_object (instance_ptr))
    4444              :         nonvirtual = true;
    4445              : 
    4446              :       /* Use force_target_expr even when instance_ptr doesn't have
    4447              :          side-effects, unless it is a simple decl or constant, so
    4448              :          that we don't ubsan instrument the expression multiple times.
    4449              :          Don't use save_expr, as save_expr can avoid building a SAVE_EXPR
    4450              :          and building a SAVE_EXPR manually can be optimized away during
    4451              :          cp_fold.  See PR116449 and PR117259.  */
    4452        83540 :       if (TREE_SIDE_EFFECTS (instance_ptr)
    4453        83540 :           || (!nonvirtual
    4454        46616 :               && !DECL_P (instance_ptr)
    4455        46616 :               && !TREE_CONSTANT (instance_ptr)))
    4456        82997 :         instance_ptr = instance_save_expr
    4457        82997 :           = get_internal_target_expr (instance_ptr);
    4458              : 
    4459              :       /* See above comment.  */
    4460        83540 :       if (TREE_SIDE_EFFECTS (function)
    4461        83540 :           || (!nonvirtual
    4462        64784 :               && !DECL_P (function)
    4463        64772 :               && !TREE_CONSTANT (function)))
    4464        83087 :         function = get_internal_target_expr (function);
    4465              : 
    4466              :       /* Start by extracting all the information from the PMF itself.  */
    4467        83540 :       e3 = pfn_from_ptrmemfunc (function);
    4468        83540 :       delta = delta_from_ptrmemfunc (function);
    4469        83540 :       idx = build1 (NOP_EXPR, vtable_index_type, e3);
    4470        83540 :       switch (TARGET_PTRMEMFUNC_VBIT_LOCATION)
    4471              :         {
    4472        83540 :           sanitize_code_type flag_sanitize_save;
    4473        83540 :         case ptrmemfunc_vbit_in_pfn:
    4474        83540 :           e1 = cp_build_binary_op (input_location,
    4475              :                                    BIT_AND_EXPR, idx, integer_one_node,
    4476              :                                    complain);
    4477        83540 :           idx = cp_build_binary_op (input_location,
    4478              :                                     MINUS_EXPR, idx, integer_one_node,
    4479              :                                     complain);
    4480        83540 :           if (idx == error_mark_node)
    4481              :             return error_mark_node;
    4482        83540 :           break;
    4483              : 
    4484              :         case ptrmemfunc_vbit_in_delta:
    4485              :           e1 = cp_build_binary_op (input_location,
    4486              :                                    BIT_AND_EXPR, delta, integer_one_node,
    4487              :                                    complain);
    4488              :           /* Don't instrument the RSHIFT_EXPR we're about to create because
    4489              :              we're going to use DELTA number of times, and that wouldn't play
    4490              :              well with SAVE_EXPRs therein.  */
    4491              :           flag_sanitize_save = flag_sanitize;
    4492              :           flag_sanitize = 0;
    4493              :           delta = cp_build_binary_op (input_location,
    4494              :                                       RSHIFT_EXPR, delta, integer_one_node,
    4495              :                                       complain);
    4496              :           flag_sanitize = flag_sanitize_save;
    4497              :           if (delta == error_mark_node)
    4498              :             return error_mark_node;
    4499              :           break;
    4500              : 
    4501              :         default:
    4502              :           gcc_unreachable ();
    4503              :         }
    4504              : 
    4505        83540 :       if (e1 == error_mark_node)
    4506              :         return error_mark_node;
    4507              : 
    4508              :       /* Convert down to the right base before using the instance.  A
    4509              :          special case is that in a pointer to member of class C, C may
    4510              :          be incomplete.  In that case, the function will of course be
    4511              :          a member of C, and no conversion is required.  In fact,
    4512              :          lookup_base will fail in that case, because incomplete
    4513              :          classes do not have BINFOs.  */
    4514        83540 :       if (!same_type_ignoring_top_level_qualifiers_p
    4515        83540 :           (basetype, TREE_TYPE (TREE_TYPE (instance_ptr))))
    4516              :         {
    4517           81 :           basetype = lookup_base (TREE_TYPE (TREE_TYPE (instance_ptr)),
    4518              :                                   basetype, ba_check, NULL, complain);
    4519           81 :           instance_ptr = build_base_path (PLUS_EXPR, instance_ptr, basetype,
    4520              :                                           1, complain);
    4521           81 :           if (instance_ptr == error_mark_node)
    4522              :             return error_mark_node;
    4523              :         }
    4524              :       /* ...and then the delta in the PMF.  */
    4525        83540 :       instance_ptr = fold_build_pointer_plus (instance_ptr, delta);
    4526              : 
    4527              :       /* Hand back the adjusted 'this' argument to our caller.  */
    4528        83540 :       *instance_ptrptr = instance_ptr;
    4529              : 
    4530        83540 :       if (nonvirtual)
    4531              :         /* Now just return the pointer.  */
    4532              :         return e3;
    4533              : 
    4534              :       /* Next extract the vtable pointer from the object.  */
    4535        83270 :       vtbl = build1 (NOP_EXPR, build_pointer_type (vtbl_ptr_type_node),
    4536              :                      instance_ptr);
    4537        83270 :       vtbl = cp_build_fold_indirect_ref (vtbl);
    4538        83270 :       if (vtbl == error_mark_node)
    4539              :         return error_mark_node;
    4540              : 
    4541              :       /* Finally, extract the function pointer from the vtable.  */
    4542        83270 :       e2 = fold_build_pointer_plus_loc (input_location, vtbl, idx);
    4543        83270 :       e2 = cp_build_fold_indirect_ref (e2);
    4544        83270 :       if (e2 == error_mark_node)
    4545              :         return error_mark_node;
    4546        83270 :       TREE_CONSTANT (e2) = 1;
    4547              : 
    4548              :       /* When using function descriptors, the address of the
    4549              :          vtable entry is treated as a function pointer.  */
    4550        83270 :       if (TARGET_VTABLE_USES_DESCRIPTORS)
    4551              :         e2 = build1 (NOP_EXPR, TREE_TYPE (e2),
    4552              :                      cp_build_addr_expr (e2, complain));
    4553              : 
    4554        83270 :       e2 = fold_convert (TREE_TYPE (e3), e2);
    4555        83270 :       e1 = build_conditional_expr (input_location, e1, e2, e3, complain);
    4556        83270 :       if (e1 == error_mark_node)
    4557              :         return error_mark_node;
    4558              : 
    4559              :       /* Make sure this doesn't get evaluated first inside one of the
    4560              :          branches of the COND_EXPR.  */
    4561        83270 :       if (instance_save_expr)
    4562        82949 :         e1 = build2 (COMPOUND_EXPR, TREE_TYPE (e1),
    4563              :                      instance_save_expr, e1);
    4564              : 
    4565              :       function = e1;
    4566              :     }
    4567              :   return function;
    4568              : }
    4569              : 
    4570              : /* Used by the C-common bits.  */
    4571              : tree
    4572            0 : build_function_call (location_t /*loc*/,
    4573              :                      tree function, tree params)
    4574              : {
    4575            0 :   return cp_build_function_call (function, params, tf_warning_or_error);
    4576              : }
    4577              : 
    4578              : /* Used by the C-common bits.  */
    4579              : tree
    4580       329276 : build_function_call_vec (location_t /*loc*/, vec<location_t> /*arg_loc*/,
    4581              :                          tree function, vec<tree, va_gc> *params,
    4582              :                          vec<tree, va_gc> * /*origtypes*/, tree orig_function)
    4583              : {
    4584       329276 :   vec<tree, va_gc> *orig_params = params;
    4585       329276 :   tree ret = cp_build_function_call_vec (function, &params,
    4586              :                                          tf_warning_or_error, orig_function);
    4587              : 
    4588              :   /* cp_build_function_call_vec can reallocate PARAMS by adding
    4589              :      default arguments.  That should never happen here.  Verify
    4590              :      that.  */
    4591       329276 :   gcc_assert (params == orig_params);
    4592              : 
    4593       329276 :   return ret;
    4594              : }
    4595              : 
    4596              : /* Build a function call using a tree list of arguments.  */
    4597              : 
    4598              : static tree
    4599            0 : cp_build_function_call (tree function, tree params, tsubst_flags_t complain)
    4600              : {
    4601            0 :   tree ret;
    4602              : 
    4603            0 :   releasing_vec vec;
    4604            0 :   for (; params != NULL_TREE; params = TREE_CHAIN (params))
    4605            0 :     vec_safe_push (vec, TREE_VALUE (params));
    4606            0 :   ret = cp_build_function_call_vec (function, &vec, complain);
    4607            0 :   return ret;
    4608            0 : }
    4609              : 
    4610              : /* Build a function call using varargs.  */
    4611              : 
    4612              : tree
    4613       572862 : cp_build_function_call_nary (tree function, tsubst_flags_t complain, ...)
    4614              : {
    4615       572862 :   va_list args;
    4616       572862 :   tree ret, t;
    4617              : 
    4618       572862 :   releasing_vec vec;
    4619       572862 :   va_start (args, complain);
    4620      1430283 :   for (t = va_arg (args, tree); t != NULL_TREE; t = va_arg (args, tree))
    4621       857421 :     vec_safe_push (vec, t);
    4622       572862 :   va_end (args);
    4623       572862 :   ret = cp_build_function_call_vec (function, &vec, complain);
    4624       572862 :   return ret;
    4625       572862 : }
    4626              : 
    4627              : /* C++ implementation of callback for use when checking param types.  */
    4628              : 
    4629              : bool
    4630           18 : cp_comp_parm_types (tree wanted_type, tree actual_type)
    4631              : {
    4632           18 :   if (TREE_CODE (wanted_type) == POINTER_TYPE
    4633           18 :       && TREE_CODE (actual_type) == POINTER_TYPE)
    4634           15 :     return same_or_base_type_p (TREE_TYPE (wanted_type),
    4635              :                                 TREE_TYPE (actual_type));
    4636              :   return false;
    4637              : }
    4638              : 
    4639              : /* Build a function call using a vector of arguments.
    4640              :    If FUNCTION is the result of resolving an overloaded target built-in,
    4641              :    ORIG_FNDECL is the original function decl, otherwise it is null.
    4642              :    PARAMS may be NULL if there are no parameters.  This changes the
    4643              :    contents of PARAMS.  */
    4644              : 
    4645              : tree
    4646      7351095 : cp_build_function_call_vec (tree function, vec<tree, va_gc> **params,
    4647              :                             tsubst_flags_t complain, tree orig_fndecl)
    4648              : {
    4649      7351095 :   tree fntype, fndecl;
    4650      7351095 :   int is_method;
    4651      7351095 :   tree original = function;
    4652      7351095 :   int nargs;
    4653      7351095 :   tree *argarray;
    4654      7351095 :   tree parm_types;
    4655      7351095 :   vec<tree, va_gc> *allocated = NULL;
    4656      7351095 :   tree ret;
    4657              : 
    4658              :   /* For Objective-C, convert any calls via a cast to OBJC_TYPE_REF
    4659              :      expressions, like those used for ObjC messenger dispatches.  */
    4660      7351095 :   if (params != NULL && !vec_safe_is_empty (*params))
    4661      2114453 :     function = objc_rewrite_function_call (function, (**params)[0]);
    4662              : 
    4663              :   /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
    4664              :      Strip such NOP_EXPRs, since FUNCTION is used in non-lvalue context.  */
    4665      7351095 :   if (TREE_CODE (function) == NOP_EXPR
    4666      7351095 :       && TREE_TYPE (function) == TREE_TYPE (TREE_OPERAND (function, 0)))
    4667           15 :     function = TREE_OPERAND (function, 0);
    4668              : 
    4669      7351095 :   if (TREE_CODE (function) == FUNCTION_DECL)
    4670              :     {
    4671      1590415 :       if (!mark_used (function, complain))
    4672           24 :         return error_mark_node;
    4673      1590391 :       fndecl = function;
    4674              : 
    4675              :       /* For target_version semantics, the function set cannot be called
    4676              :          if there is no default version in scope.  */
    4677      1590391 :       if (!TARGET_HAS_FMV_TARGET_ATTRIBUTE
    4678              :            && !is_function_default_version (fndecl))
    4679              :          {
    4680              :            if (complain & tf_error)
    4681              :             error ("no default version in scope");
    4682              :            return error_mark_node;
    4683              :          }
    4684              : 
    4685              :       /* Convert anything with function type to a pointer-to-function.  */
    4686      1590391 :       if (DECL_MAIN_P (function))
    4687              :         {
    4688            0 :           if (complain & tf_error)
    4689            0 :             pedwarn (input_location, OPT_Wpedantic,
    4690              :                      "ISO C++ forbids calling %<::main%> from within program");
    4691              :           else
    4692            0 :             return error_mark_node;
    4693              :         }
    4694      1590391 :       function = build_addr_func (function, complain);
    4695              :     }
    4696              :   else
    4697              :     {
    4698      5760680 :       fndecl = NULL_TREE;
    4699              : 
    4700      5760680 :       function = build_addr_func (function, complain);
    4701              :     }
    4702              : 
    4703      7351071 :   if (function == error_mark_node)
    4704              :     return error_mark_node;
    4705              : 
    4706      7350969 :   fntype = TREE_TYPE (function);
    4707              : 
    4708      7350969 :   if (TYPE_PTRMEMFUNC_P (fntype))
    4709              :     {
    4710           15 :       if (complain & tf_error)
    4711           15 :         error ("must use %<.*%> or %<->*%> to call pointer-to-member "
    4712              :                "function in %<%E (...)%>, e.g. %<(... ->* %E) (...)%>",
    4713              :                original, original);
    4714           15 :       return error_mark_node;
    4715              :     }
    4716              : 
    4717     14701908 :   is_method = (TYPE_PTR_P (fntype)
    4718      7350954 :                && TREE_CODE (TREE_TYPE (fntype)) == METHOD_TYPE);
    4719              : 
    4720      7350954 :   if (!(TYPE_PTRFN_P (fntype)
    4721        85251 :         || is_method
    4722         1768 :         || TREE_CODE (function) == TEMPLATE_ID_EXPR))
    4723              :     {
    4724         1768 :       if (complain & tf_error)
    4725              :         {
    4726          178 :           if (is_stub_object (original))
    4727            3 :             error_at (input_location,
    4728              :                       "%qT cannot be used as a function",
    4729            3 :                       TREE_TYPE (original));
    4730          175 :           else if (!flag_diagnostics_show_caret)
    4731          175 :             error_at (input_location,
    4732              :                       "%qE cannot be used as a function", original);
    4733            0 :           else if (DECL_P (original))
    4734            0 :             error_at (input_location,
    4735              :                       "%qD cannot be used as a function", original);
    4736              :           else
    4737            0 :             error_at (input_location,
    4738              :                       "expression cannot be used as a function");
    4739              :         }
    4740              : 
    4741         1768 :       return error_mark_node;
    4742              :     }
    4743              : 
    4744              :   /* fntype now gets the type of function pointed to.  */
    4745      7349186 :   fntype = TREE_TYPE (fntype);
    4746      7349186 :   parm_types = TYPE_ARG_TYPES (fntype);
    4747              : 
    4748      7349186 :   if (params == NULL)
    4749              :     {
    4750       151007 :       allocated = make_tree_vector ();
    4751       151007 :       params = &allocated;
    4752              :     }
    4753              : 
    4754      7349186 :     nargs = convert_arguments (parm_types, params, fndecl, LOOKUP_NORMAL,
    4755              :                                complain);
    4756      7349186 :   if (nargs < 0)
    4757         1918 :     return error_mark_node;
    4758              : 
    4759      7347268 :   argarray = (*params)->address ();
    4760              : 
    4761              :   /* Check for errors in format strings and inappropriately
    4762              :      null parameters.  */
    4763      7347268 :   bool warned_p
    4764      7347268 :     = ((complain & tf_warning)
    4765      7347268 :        && check_function_arguments (input_location, fndecl, fntype,
    4766              :                                     nargs, argarray, NULL,
    4767      7347268 :                                     cp_comp_parm_types));
    4768              : 
    4769      7347268 :   ret = build_cxx_call (function, nargs, argarray, complain, orig_fndecl);
    4770              : 
    4771      7347268 :   if (warned_p)
    4772              :     {
    4773           27 :       tree c = extract_call_expr (ret);
    4774           27 :       if (TREE_CODE (c) == CALL_EXPR)
    4775           27 :         suppress_warning (c, OPT_Wnonnull);
    4776              :     }
    4777              : 
    4778      7347268 :   if (allocated != NULL)
    4779       151007 :     release_tree_vector (allocated);
    4780              : 
    4781              :   return ret;
    4782              : }
    4783              : 
    4784              : /* Subroutine of convert_arguments.
    4785              :    Print an error message about a wrong number of arguments.  */
    4786              : 
    4787              : static void
    4788          162 : error_args_num (location_t loc, tree fndecl, bool too_many_p)
    4789              : {
    4790          162 :   if (fndecl)
    4791              :     {
    4792          126 :       auto_diagnostic_group d;
    4793          126 :       if (TREE_CODE (TREE_TYPE (fndecl)) == METHOD_TYPE)
    4794              :         {
    4795            0 :           if (DECL_NAME (fndecl) == NULL_TREE
    4796            0 :               || (DECL_NAME (fndecl)
    4797            0 :                   == DECL_NAME (TYPE_NAME (DECL_CONTEXT (fndecl)))))
    4798            0 :             error_at (loc,
    4799              :                       too_many_p
    4800              :                       ? G_("too many arguments to constructor %q#D")
    4801              :                       : G_("too few arguments to constructor %q#D"),
    4802              :                       fndecl);
    4803              :           else
    4804            0 :             error_at (loc,
    4805              :                       too_many_p
    4806              :                       ? G_("too many arguments to member function %q#D")
    4807              :                       : G_("too few arguments to member function %q#D"),
    4808              :                       fndecl);
    4809              :         }
    4810              :       else
    4811          189 :         error_at (loc,
    4812              :                   too_many_p
    4813              :                   ? G_("too many arguments to function %q#D")
    4814              :                   : G_("too few arguments to function %q#D"),
    4815              :                   fndecl);
    4816          126 :       if (!DECL_IS_UNDECLARED_BUILTIN (fndecl))
    4817           87 :         inform (DECL_SOURCE_LOCATION (fndecl), "declared here");
    4818          126 :     }
    4819              :   else
    4820              :     {
    4821           36 :       if (c_dialect_objc ()  &&  objc_message_selector ())
    4822            0 :         error_at (loc,
    4823              :                   too_many_p
    4824              :                   ? G_("too many arguments to method %q#D")
    4825              :                   : G_("too few arguments to method %q#D"),
    4826              :                   objc_message_selector ());
    4827              :       else
    4828           57 :         error_at (loc, too_many_p ? G_("too many arguments to function")
    4829              :                                   : G_("too few arguments to function"));
    4830              :     }
    4831          162 : }
    4832              : 
    4833              : /* Convert the actual parameter expressions in the list VALUES to the
    4834              :    types in the list TYPELIST.  The converted expressions are stored
    4835              :    back in the VALUES vector.
    4836              :    If parmdecls is exhausted, or when an element has NULL as its type,
    4837              :    perform the default conversions.
    4838              : 
    4839              :    NAME is an IDENTIFIER_NODE or 0.  It is used only for error messages.
    4840              : 
    4841              :    This is also where warnings about wrong number of args are generated.
    4842              : 
    4843              :    Returns the actual number of arguments processed (which might be less
    4844              :    than the length of the vector), or -1 on error.
    4845              : 
    4846              :    In C++, unspecified trailing parameters can be filled in with their
    4847              :    default arguments, if such were specified.  Do so here.  */
    4848              : 
    4849              : static int
    4850      7349186 : convert_arguments (tree typelist, vec<tree, va_gc> **values, tree fndecl,
    4851              :                    int flags, tsubst_flags_t complain)
    4852              : {
    4853      7349186 :   tree typetail;
    4854      7349186 :   unsigned int i;
    4855              : 
    4856              :   /* Argument passing is always copy-initialization.  */
    4857      7349186 :   flags |= LOOKUP_ONLYCONVERTING;
    4858              : 
    4859     11952301 :   for (i = 0, typetail = typelist;
    4860     11952301 :        i < vec_safe_length (*values);
    4861              :        i++)
    4862              :     {
    4863      9209286 :       tree type = typetail ? TREE_VALUE (typetail) : 0;
    4864      4604866 :       tree val = (**values)[i];
    4865              : 
    4866      4604866 :       if (val == error_mark_node || type == error_mark_node)
    4867              :         return -1;
    4868              : 
    4869      4604860 :       if (type == void_type_node)
    4870              :         {
    4871          212 :           if (complain & tf_error)
    4872           78 :             error_args_num (input_location, fndecl, /*too_many_p=*/true);
    4873          212 :           return -1;
    4874              :         }
    4875              : 
    4876              :       /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
    4877              :          Strip such NOP_EXPRs, since VAL is used in non-lvalue context.  */
    4878      4604648 :       if (TREE_CODE (val) == NOP_EXPR
    4879      1200726 :           && TREE_TYPE (val) == TREE_TYPE (TREE_OPERAND (val, 0))
    4880      4604666 :           && (type == 0 || !TYPE_REF_P (type)))
    4881           18 :         val = TREE_OPERAND (val, 0);
    4882              : 
    4883      4604648 :       if (type == 0 || !TYPE_REF_P (type))
    4884              :         {
    4885      4408630 :           if (TREE_CODE (TREE_TYPE (val)) == ARRAY_TYPE
    4886      4408630 :               || FUNC_OR_METHOD_TYPE_P (TREE_TYPE (val)))
    4887        11039 :             val = decay_conversion (val, complain);
    4888              :         }
    4889              : 
    4890      4604648 :       if (val == error_mark_node)
    4891              :         return -1;
    4892              : 
    4893      4604648 :       if (type != 0)
    4894              :         {
    4895              :           /* Formal parm type is specified by a function prototype.  */
    4896      4604202 :           tree parmval;
    4897              : 
    4898      4604202 :           if (!COMPLETE_TYPE_P (complete_type (type)))
    4899              :             {
    4900           18 :               if (complain & tf_error)
    4901              :                 {
    4902           12 :                   location_t loc = EXPR_LOC_OR_LOC (val, input_location);
    4903           12 :                   if (fndecl)
    4904              :                     {
    4905           12 :                       auto_diagnostic_group d;
    4906           12 :                       error_at (loc,
    4907              :                                 "parameter %P of %qD has incomplete type %qT",
    4908              :                                 i, fndecl, type);
    4909           12 :                       inform (get_fndecl_argument_location (fndecl, i),
    4910              :                               "  declared here");
    4911           12 :                     }
    4912              :                   else
    4913            0 :                     error_at (loc, "parameter %P has incomplete type %qT", i,
    4914              :                               type);
    4915              :                 }
    4916           18 :               parmval = error_mark_node;
    4917              :             }
    4918              :           else
    4919              :             {
    4920      4604184 :               parmval = convert_for_initialization
    4921      4604184 :                 (NULL_TREE, type, val, flags,
    4922              :                  ICR_ARGPASS, fndecl, i, complain);
    4923      4604184 :               parmval = convert_for_arg_passing (type, parmval, complain);
    4924              :             }
    4925              : 
    4926      4604202 :           if (parmval == error_mark_node)
    4927              :             return -1;
    4928              : 
    4929      4602669 :           (**values)[i] = parmval;
    4930              :         }
    4931              :       else
    4932              :         {
    4933          446 :           int magic = fndecl ? magic_varargs_p (fndecl) : 0;
    4934           21 :           if (magic)
    4935              :             {
    4936              :               /* Don't truncate excess precision to the semantic type.  */
    4937            0 :               if (magic == 1 && TREE_CODE (val) == EXCESS_PRECISION_EXPR)
    4938            0 :                 val = TREE_OPERAND (val, 0);
    4939              :               /* Don't do ellipsis conversion for __built_in_constant_p
    4940              :                  as this will result in spurious errors for non-trivial
    4941              :                  types.  */
    4942            0 :               val = require_complete_type (val, complain);
    4943              :             }
    4944              :           else
    4945          446 :             val = convert_arg_to_ellipsis (val, complain);
    4946              : 
    4947          446 :           (**values)[i] = val;
    4948              :         }
    4949              : 
    4950      4603115 :       if (typetail)
    4951      4602669 :         typetail = TREE_CHAIN (typetail);
    4952              :     }
    4953              : 
    4954      7347435 :   if (typetail != 0 && typetail != void_list_node)
    4955              :     {
    4956              :       /* See if there are default arguments that can be used.  Because
    4957              :          we hold default arguments in the FUNCTION_TYPE (which is so
    4958              :          wrong), we can see default parameters here from deduced
    4959              :          contexts (and via typeof) for indirect function calls.
    4960              :          Fortunately we know whether we have a function decl to
    4961              :          provide default arguments in a language conformant
    4962              :          manner.  */
    4963           63 :       if (fndecl && TREE_PURPOSE (typetail)
    4964          170 :           && TREE_CODE (TREE_PURPOSE (typetail)) != DEFERRED_PARSE)
    4965              :         {
    4966            6 :           for (; typetail != void_list_node; ++i)
    4967              :             {
    4968              :               /* After DR777, with explicit template args we can end up with a
    4969              :                  default argument followed by no default argument.  */
    4970            6 :               if (!TREE_PURPOSE (typetail))
    4971              :                 break;
    4972            3 :               tree parmval
    4973            3 :                 = convert_default_arg (TREE_VALUE (typetail),
    4974            3 :                                        TREE_PURPOSE (typetail),
    4975            3 :                                        fndecl, i, complain);
    4976              : 
    4977            3 :               if (parmval == error_mark_node)
    4978            0 :                 return -1;
    4979              : 
    4980            3 :               vec_safe_push (*values, parmval);
    4981            3 :               typetail = TREE_CHAIN (typetail);
    4982              :               /* ends with `...'.  */
    4983            3 :               if (typetail == NULL_TREE)
    4984              :                 break;
    4985              :             }
    4986              :         }
    4987              : 
    4988          167 :       if (typetail && typetail != void_list_node)
    4989              :         {
    4990          167 :           if (complain & tf_error)
    4991           84 :             error_args_num (input_location, fndecl, /*too_many_p=*/false);
    4992          167 :           return -1;
    4993              :         }
    4994              :     }
    4995              : 
    4996      7347268 :   return (int) i;
    4997              : }
    4998              : 
    4999              : /* Build a binary-operation expression, after performing default
    5000              :    conversions on the operands.  CODE is the kind of expression to
    5001              :    build.  ARG1 and ARG2 are the arguments.  ARG1_CODE and ARG2_CODE
    5002              :    are the tree codes which correspond to ARG1 and ARG2 when issuing
    5003              :    warnings about possibly misplaced parentheses.  They may differ
    5004              :    from the TREE_CODE of ARG1 and ARG2 if the parser has done constant
    5005              :    folding (e.g., if the parser sees "a | 1 + 1", it may call this
    5006              :    routine with ARG2 being an INTEGER_CST and ARG2_CODE == PLUS_EXPR).
    5007              :    To avoid issuing any parentheses warnings, pass ARG1_CODE and/or
    5008              :    ARG2_CODE as ERROR_MARK.  */
    5009              : 
    5010              : tree
    5011    226903543 : build_x_binary_op (const op_location_t &loc, enum tree_code code, tree arg1,
    5012              :                    enum tree_code arg1_code, tree arg2,
    5013              :                    enum tree_code arg2_code, tree lookups,
    5014              :                    tree *overload_p, tsubst_flags_t complain)
    5015              : {
    5016    226903543 :   tree orig_arg1;
    5017    226903543 :   tree orig_arg2;
    5018    226903543 :   tree expr;
    5019    226903543 :   tree overload = NULL_TREE;
    5020              : 
    5021    226903543 :   orig_arg1 = arg1;
    5022    226903543 :   orig_arg2 = arg2;
    5023              : 
    5024    226903543 :   if (processing_template_decl)
    5025              :     {
    5026    133290000 :       if (type_dependent_expression_p (arg1)
    5027    133290000 :           || type_dependent_expression_p (arg2))
    5028              :         {
    5029     91524422 :           expr = build_min_nt_loc (loc, code, arg1, arg2);
    5030     91524422 :           TREE_TYPE (expr)
    5031     91524422 :             = build_dependent_operator_type (lookups, code, false);
    5032     91524422 :           return expr;
    5033              :         }
    5034              :     }
    5035              : 
    5036    135379121 :   if (code == DOTSTAR_EXPR)
    5037        83676 :     expr = build_m_component_ref (arg1, arg2, complain);
    5038              :   else
    5039    135295445 :     expr = build_new_op (loc, code, LOOKUP_NORMAL, arg1, arg2, NULL_TREE,
    5040              :                          lookups, &overload, complain);
    5041              : 
    5042    135379088 :   if (overload_p != NULL)
    5043     60479992 :     *overload_p = overload;
    5044              : 
    5045              :   /* Check for cases such as x+y<<z which users are likely to
    5046              :      misinterpret.  But don't warn about obj << x + y, since that is a
    5047              :      common idiom for I/O.  */
    5048    135379088 :   if (warn_parentheses
    5049      1247902 :       && (complain & tf_warning)
    5050      1191118 :       && !processing_template_decl
    5051       816645 :       && !error_operand_p (arg1)
    5052       816639 :       && !error_operand_p (arg2)
    5053    136195715 :       && (code != LSHIFT_EXPR
    5054        71165 :           || !CLASS_TYPE_P (TREE_TYPE (arg1))))
    5055       815580 :     warn_about_parentheses (loc, code, arg1_code, orig_arg1,
    5056              :                             arg2_code, orig_arg2);
    5057              : 
    5058    135379088 :   if (processing_template_decl && expr != error_mark_node)
    5059              :     {
    5060     41765355 :       if (overload != NULL_TREE)
    5061      3790336 :         return (build_min_non_dep_op_overload
    5062      3790336 :                 (code, expr, overload, orig_arg1, orig_arg2));
    5063              : 
    5064     37975019 :       return build_min_non_dep (code, expr, orig_arg1, orig_arg2);
    5065              :     }
    5066              : 
    5067              :   return expr;
    5068              : }
    5069              : 
    5070              : /* Build and return an ARRAY_REF expression.  */
    5071              : 
    5072              : tree
    5073      2459620 : build_x_array_ref (location_t loc, tree arg1, tree arg2,
    5074              :                    tsubst_flags_t complain)
    5075              : {
    5076      2459620 :   tree orig_arg1 = arg1;
    5077      2459620 :   tree orig_arg2 = arg2;
    5078      2459620 :   tree expr;
    5079      2459620 :   tree overload = NULL_TREE;
    5080              : 
    5081      2459620 :   if (processing_template_decl)
    5082              :     {
    5083         4779 :       if (type_dependent_expression_p (arg1)
    5084         4779 :           || type_dependent_expression_p (arg2))
    5085         2584 :         return build_min_nt_loc (loc, ARRAY_REF, arg1, arg2,
    5086         2584 :                                  NULL_TREE, NULL_TREE);
    5087              :     }
    5088              : 
    5089      2457036 :   expr = build_new_op (loc, ARRAY_REF, LOOKUP_NORMAL, arg1, arg2,
    5090              :                        NULL_TREE, NULL_TREE, &overload, complain);
    5091              : 
    5092      2457036 :   if (processing_template_decl && expr != error_mark_node)
    5093              :     {
    5094         2192 :       if (overload != NULL_TREE)
    5095         2183 :         return (build_min_non_dep_op_overload
    5096         2183 :                 (ARRAY_REF, expr, overload, orig_arg1, orig_arg2));
    5097              : 
    5098            9 :       return build_min_non_dep (ARRAY_REF, expr, orig_arg1, orig_arg2,
    5099            9 :                                 NULL_TREE, NULL_TREE);
    5100              :     }
    5101              :   return expr;
    5102              : }
    5103              : 
    5104              : /* Build an OpenMP array section reference, creating an exact type for the
    5105              :    resulting expression based on the element type and bounds if possible.  If
    5106              :    we have variable bounds, create an incomplete array type for the result
    5107              :    instead.  */
    5108              : 
    5109              : tree
    5110        10500 : build_omp_array_section (location_t loc, tree array_expr, tree index,
    5111              :                          tree length)
    5112              : {
    5113        10500 :   if (TREE_CODE (array_expr) == TYPE_DECL
    5114        10500 :       || type_dependent_expression_p (array_expr))
    5115          258 :     return build3_loc (loc, OMP_ARRAY_SECTION, NULL_TREE, array_expr, index,
    5116          258 :                        length);
    5117              : 
    5118        10242 :   tree type = TREE_TYPE (array_expr);
    5119        10242 :   gcc_assert (type);
    5120        10242 :   type = non_reference (type);
    5121              : 
    5122        10242 :   tree sectype, eltype = TREE_TYPE (type);
    5123              : 
    5124              :   /* It's not an array or pointer type.  Just reuse the type of the
    5125              :      original expression as the type of the array section (an error will be
    5126              :      raised anyway, later).  */
    5127        10242 :   if (eltype == NULL_TREE)
    5128           39 :     sectype = TREE_TYPE (array_expr);
    5129              :   else
    5130              :     {
    5131        10203 :       tree idxtype = NULL_TREE;
    5132              : 
    5133              :       /* If we know the integer bounds, create an index type with exact
    5134              :          low/high (or zero/length) bounds.  Otherwise, create an incomplete
    5135              :          array type.  (This mostly only affects diagnostics.)  */
    5136        10203 :       if (index != NULL_TREE
    5137        10203 :           && length != NULL_TREE
    5138         7403 :           && TREE_CODE (index) == INTEGER_CST
    5139         6606 :           && TREE_CODE (length) == INTEGER_CST)
    5140              :         {
    5141         5111 :           tree low = fold_convert (sizetype, index);
    5142         5111 :           tree high = fold_convert (sizetype, length);
    5143         5111 :           high = size_binop (PLUS_EXPR, low, high);
    5144         5111 :           high = size_binop (MINUS_EXPR, high, size_one_node);
    5145         5111 :           idxtype = build_range_type (sizetype, low, high);
    5146         5111 :         }
    5147         2900 :       else if ((index == NULL_TREE || integer_zerop (index))
    5148         3503 :                && length != NULL_TREE
    5149         7187 :                && TREE_CODE (length) == INTEGER_CST)
    5150         1387 :         idxtype = build_index_type (length);
    5151              : 
    5152        10203 :       sectype = build_array_type (eltype, idxtype);
    5153              :     }
    5154              : 
    5155        10242 :   return build3_loc (loc, OMP_ARRAY_SECTION, sectype, array_expr, index,
    5156        10242 :                      length);
    5157              : }
    5158              : 
    5159              : /* Return whether OP is an expression of enum type cast to integer
    5160              :    type.  In C++ even unsigned enum types are cast to signed integer
    5161              :    types.  We do not want to issue warnings about comparisons between
    5162              :    signed and unsigned types when one of the types is an enum type.
    5163              :    Those warnings are always false positives in practice.  */
    5164              : 
    5165              : static bool
    5166       638826 : enum_cast_to_int (tree op)
    5167              : {
    5168       625846 :   if (CONVERT_EXPR_P (op)
    5169        14007 :       && TREE_TYPE (op) == integer_type_node
    5170          917 :       && TREE_CODE (TREE_TYPE (TREE_OPERAND (op, 0))) == ENUMERAL_TYPE
    5171       638841 :       && TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op, 0))))
    5172              :     return true;
    5173              : 
    5174              :   /* The cast may have been pushed into a COND_EXPR.  */
    5175       638819 :   if (TREE_CODE (op) == COND_EXPR)
    5176          765 :     return (enum_cast_to_int (TREE_OPERAND (op, 1))
    5177          765 :             || enum_cast_to_int (TREE_OPERAND (op, 2)));
    5178              : 
    5179              :   return false;
    5180              : }
    5181              : 
    5182              : /* For the c-common bits.  */
    5183              : tree
    5184      4648558 : build_binary_op (location_t location, enum tree_code code, tree op0, tree op1,
    5185              :                  bool /*convert_p*/)
    5186              : {
    5187      4648558 :   return cp_build_binary_op (location, code, op0, op1, tf_warning_or_error);
    5188              : }
    5189              : 
    5190              : /* Build a vector comparison of ARG0 and ARG1 using CODE opcode
    5191              :    into a value of TYPE type.  Comparison is done via VEC_COND_EXPR.  */
    5192              : 
    5193              : static tree
    5194         7718 : build_vec_cmp (tree_code code, tree type,
    5195              :                tree arg0, tree arg1)
    5196              : {
    5197         7718 :   tree zero_vec = build_zero_cst (type);
    5198         7718 :   tree minus_one_vec = build_minus_one_cst (type);
    5199         7718 :   tree cmp_type = truth_type_for (TREE_TYPE (arg0));
    5200         7718 :   tree cmp = build2 (code, cmp_type, arg0, arg1);
    5201         7718 :   return build3 (VEC_COND_EXPR, type, cmp, minus_one_vec, zero_vec);
    5202              : }
    5203              : 
    5204              : /* Possibly warn about an address never being NULL.  */
    5205              : 
    5206              : static void
    5207      1754052 : warn_for_null_address (location_t location, tree op, tsubst_flags_t complain)
    5208              : {
    5209              :   /* Prevent warnings issued for macro expansion.  */
    5210      1754052 :   if (!warn_address
    5211        41705 :       || (complain & tf_warning) == 0
    5212        24930 :       || c_inhibit_evaluation_warnings != 0
    5213        24914 :       || from_macro_expansion_at (location)
    5214      1772235 :       || warning_suppressed_p (op, OPT_Waddress))
    5215      1736192 :     return;
    5216              : 
    5217        18150 :   tree cop = fold_for_warn (op);
    5218              : 
    5219        18150 :   if (TREE_CODE (cop) == NON_LVALUE_EXPR)
    5220              :     /* Unwrap the expression for C++ 98.  */
    5221            1 :     cop = TREE_OPERAND (cop, 0);
    5222              : 
    5223        18150 :   if (TREE_CODE (cop) == PTRMEM_CST)
    5224              :     {
    5225              :       /* The address of a nonstatic data member is never null.  */
    5226           30 :       warning_at (location, OPT_Waddress,
    5227              :                   "the address %qE will never be NULL",
    5228              :                   cop);
    5229           30 :       return;
    5230              :     }
    5231              : 
    5232        18120 :   if (TREE_CODE (cop) == NOP_EXPR)
    5233              :     {
    5234              :       /* Allow casts to intptr_t to suppress the warning.  */
    5235         1243 :       tree type = TREE_TYPE (cop);
    5236         1243 :       if (TREE_CODE (type) == INTEGER_TYPE)
    5237              :         return;
    5238              : 
    5239         1243 :       STRIP_NOPS (cop);
    5240              :     }
    5241              : 
    5242        18120 :   auto_diagnostic_group d;
    5243        18120 :   bool warned = false;
    5244        18120 :   if (TREE_CODE (cop) == ADDR_EXPR)
    5245              :     {
    5246          789 :       cop = TREE_OPERAND (cop, 0);
    5247              : 
    5248              :       /* Set to true in the loop below if OP dereferences its operand.
    5249              :          In such a case the ultimate target need not be a decl for
    5250              :          the null [in]equality test to be necessarily constant.  */
    5251          789 :       bool deref = false;
    5252              : 
    5253              :       /* Get the outermost array or object, or member.  */
    5254          960 :       while (handled_component_p (cop))
    5255              :         {
    5256          270 :           if (TREE_CODE (cop) == COMPONENT_REF)
    5257              :             {
    5258              :               /* Get the member (its address is never null).  */
    5259           99 :               cop = TREE_OPERAND (cop, 1);
    5260           99 :               break;
    5261              :             }
    5262              : 
    5263              :           /* Get the outer array/object to refer to in the warning.  */
    5264          171 :           cop = TREE_OPERAND (cop, 0);
    5265          171 :           deref = true;
    5266              :         }
    5267              : 
    5268          639 :       if ((!deref && !decl_with_nonnull_addr_p (cop))
    5269          631 :           || from_macro_expansion_at (location)
    5270         1420 :           || warning_suppressed_p (cop, OPT_Waddress))
    5271          158 :         return;
    5272              : 
    5273          631 :       warned = warning_at (location, OPT_Waddress,
    5274              :                            "the address of %qD will never be NULL", cop);
    5275          631 :       op = cop;
    5276              :     }
    5277        17331 :   else if (TREE_CODE (cop) == POINTER_PLUS_EXPR)
    5278              :     {
    5279              :       /* Adding zero to the null pointer is well-defined in C++.  When
    5280              :          the offset is unknown (i.e., not a constant) warn anyway since
    5281              :          it's less likely that the pointer operand is null than not.  */
    5282          102 :       tree off = TREE_OPERAND (cop, 1);
    5283          102 :       if (!integer_zerop (off)
    5284          102 :           && !warning_suppressed_p (cop, OPT_Waddress))
    5285              :         {
    5286          102 :           tree base = TREE_OPERAND (cop, 0);
    5287          102 :           STRIP_NOPS (base);
    5288          102 :           if (TYPE_REF_P (TREE_TYPE (base)))
    5289           12 :             warning_at (location, OPT_Waddress, "the compiler can assume that "
    5290              :                         "the address of %qE will never be NULL", base);
    5291              :           else
    5292           90 :             warning_at (location, OPT_Waddress, "comparing the result of "
    5293              :                         "pointer addition %qE and NULL", cop);
    5294              :         }
    5295          102 :       return;
    5296              :     }
    5297        16267 :   else if (CONVERT_EXPR_P (op)
    5298        17291 :            && TYPE_REF_P (TREE_TYPE (TREE_OPERAND (op, 0))))
    5299              :     {
    5300           62 :       STRIP_NOPS (op);
    5301              : 
    5302           62 :       if (TREE_CODE (op) == COMPONENT_REF)
    5303           24 :         op = TREE_OPERAND (op, 1);
    5304              : 
    5305           62 :       if (DECL_P (op))
    5306           62 :         warned = warning_at (location, OPT_Waddress,
    5307              :                              "the compiler can assume that the address of "
    5308              :                              "%qD will never be NULL", op);
    5309              :     }
    5310              : 
    5311          693 :   if (warned && DECL_P (op))
    5312          657 :     inform (DECL_SOURCE_LOCATION (op), "%qD declared here", op);
    5313        18120 : }
    5314              : 
    5315              : /* Warn about [expr.arith.conv]/2: If one operand is of enumeration type and
    5316              :    the other operand is of a different enumeration type or a floating-point
    5317              :    type, this behavior is deprecated ([depr.arith.conv.enum]).  CODE is the
    5318              :    code of the binary operation, TYPE0 and TYPE1 are the types of the operands,
    5319              :    and LOC is the location for the whole binary expression.
    5320              :    For C++26 this is ill-formed rather than deprecated.
    5321              :    Return true for SFINAE errors.
    5322              :    TODO: Consider combining this with -Wenum-compare in build_new_op_1.  */
    5323              : 
    5324              : static bool
    5325    107434513 : do_warn_enum_conversions (location_t loc, enum tree_code code, tree type0,
    5326              :                           tree type1, tsubst_flags_t complain)
    5327              : {
    5328    107434513 :   if (TREE_CODE (type0) == ENUMERAL_TYPE
    5329      3163867 :       && TREE_CODE (type1) == ENUMERAL_TYPE
    5330    110087026 :       && TYPE_MAIN_VARIANT (type0) != TYPE_MAIN_VARIANT (type1))
    5331              :     {
    5332          200 :       if (cxx_dialect >= cxx26)
    5333              :         {
    5334           65 :           if ((complain & tf_warning_or_error) == 0)
    5335              :             return true;
    5336              :         }
    5337          135 :       else if ((complain & tf_warning) == 0)
    5338              :         return false;
    5339              :       /* In C++20, -Wdeprecated-enum-enum-conversion is on by default.
    5340              :          Otherwise, warn if -Wenum-conversion is on.  */
    5341          193 :       enum opt_code opt;
    5342          193 :       if (warn_deprecated_enum_enum_conv)
    5343              :         opt = OPT_Wdeprecated_enum_enum_conversion;
    5344           93 :       else if (warn_enum_conversion)
    5345              :         opt = OPT_Wenum_conversion;
    5346              :       else
    5347              :         return false;
    5348              : 
    5349          122 :       switch (code)
    5350              :         {
    5351              :         case GT_EXPR:
    5352              :         case LT_EXPR:
    5353              :         case GE_EXPR:
    5354              :         case LE_EXPR:
    5355              :         case EQ_EXPR:
    5356              :         case NE_EXPR:
    5357              :           /* Comparisons are handled by -Wenum-compare.  */
    5358              :           return false;
    5359              :         case SPACESHIP_EXPR:
    5360              :           /* This is invalid, don't warn.  */
    5361              :           return false;
    5362           18 :         case BIT_AND_EXPR:
    5363           18 :         case BIT_IOR_EXPR:
    5364           18 :         case BIT_XOR_EXPR:
    5365           18 :           if (cxx_dialect >= cxx26)
    5366            6 :             pedwarn (loc, opt, "bitwise operation between different "
    5367              :                      "enumeration types %qT and %qT", type0, type1);
    5368              :           else
    5369           12 :             warning_at (loc, opt, "bitwise operation between different "
    5370              :                         "enumeration types %qT and %qT is deprecated",
    5371              :                         type0, type1);
    5372           18 :           return false;
    5373           42 :         default:
    5374           42 :           if (cxx_dialect >= cxx26)
    5375           13 :             pedwarn (loc, opt, "arithmetic between different enumeration "
    5376              :                      "types %qT and %qT", type0, type1);
    5377              :           else
    5378           29 :             warning_at (loc, opt, "arithmetic between different enumeration "
    5379              :                         "types %qT and %qT is deprecated", type0, type1);
    5380           42 :           return false;
    5381              :         }
    5382              :     }
    5383    107434313 :   else if ((TREE_CODE (type0) == ENUMERAL_TYPE
    5384      3163667 :             && SCALAR_FLOAT_TYPE_P (type1))
    5385    107434241 :            || (SCALAR_FLOAT_TYPE_P (type0)
    5386     30639453 :                && TREE_CODE (type1) == ENUMERAL_TYPE))
    5387              :     {
    5388          151 :       if (cxx_dialect >= cxx26)
    5389              :         {
    5390           54 :           if ((complain & tf_warning_or_error) == 0)
    5391              :             return true;
    5392              :         }
    5393           97 :       else if ((complain & tf_warning) == 0)
    5394              :         return false;
    5395          139 :       const bool enum_first_p = TREE_CODE (type0) == ENUMERAL_TYPE;
    5396              :       /* In C++20, -Wdeprecated-enum-float-conversion is on by default.
    5397              :          Otherwise, warn if -Wenum-conversion is on.  */
    5398          139 :       enum opt_code opt;
    5399          139 :       if (warn_deprecated_enum_float_conv)
    5400              :         opt = OPT_Wdeprecated_enum_float_conversion;
    5401           68 :       else if (warn_enum_conversion)
    5402              :         opt = OPT_Wenum_conversion;
    5403              :       else
    5404              :         return false;
    5405              : 
    5406           88 :       switch (code)
    5407              :         {
    5408           36 :         case GT_EXPR:
    5409           36 :         case LT_EXPR:
    5410           36 :         case GE_EXPR:
    5411           36 :         case LE_EXPR:
    5412           36 :         case EQ_EXPR:
    5413           36 :         case NE_EXPR:
    5414           36 :           if (enum_first_p && cxx_dialect >= cxx26)
    5415            6 :             pedwarn (loc, opt, "comparison of enumeration type %qT with "
    5416              :                      "floating-point type %qT", type0, type1);
    5417           30 :           else if (cxx_dialect >= cxx26)
    5418            6 :             pedwarn (loc, opt, "comparison of floating-point type %qT "
    5419              :                       "with enumeration type %qT", type0, type1);
    5420           24 :           else if (enum_first_p)
    5421           12 :             warning_at (loc, opt, "comparison of enumeration type %qT with "
    5422              :                         "floating-point type %qT is deprecated",
    5423              :                         type0, type1);
    5424              :           else
    5425           12 :             warning_at (loc, opt, "comparison of floating-point type %qT "
    5426              :                         "with enumeration type %qT is deprecated",
    5427              :                         type0, type1);
    5428           36 :           return false;
    5429              :         case SPACESHIP_EXPR:
    5430              :           /* This is invalid, don't warn.  */
    5431              :           return false;
    5432           40 :         default:
    5433           40 :           if (enum_first_p && cxx_dialect >= cxx26)
    5434            6 :             pedwarn (loc, opt, "arithmetic between enumeration type %qT "
    5435              :                      "and floating-point type %qT", type0, type1);
    5436           34 :           else if (cxx_dialect >= cxx26)
    5437            7 :             pedwarn (loc, opt, "arithmetic between floating-point type %qT "
    5438              :                      "and enumeration type %qT", type0, type1);
    5439           27 :           else if (enum_first_p)
    5440           12 :             warning_at (loc, opt, "arithmetic between enumeration type %qT "
    5441              :                         "and floating-point type %qT is deprecated",
    5442              :                         type0, type1);
    5443              :           else
    5444           15 :             warning_at (loc, opt, "arithmetic between floating-point type %qT "
    5445              :                         "and enumeration type %qT is deprecated",
    5446              :                         type0, type1);
    5447           40 :           return false;
    5448              :         }
    5449              :     }
    5450              :   return false;
    5451              : }
    5452              : 
    5453              : /* Build a binary-operation expression without default conversions.
    5454              :    CODE is the kind of expression to build.
    5455              :    LOCATION is the location_t of the operator in the source code.
    5456              :    This function differs from `build' in several ways:
    5457              :    the data type of the result is computed and recorded in it,
    5458              :    warnings are generated if arg data types are invalid,
    5459              :    special handling for addition and subtraction of pointers is known,
    5460              :    and some optimization is done (operations on narrow ints
    5461              :    are done in the narrower type when that gives the same result).
    5462              :    Constant folding is also done before the result is returned.
    5463              : 
    5464              :    Note that the operands will never have enumeral types
    5465              :    because either they have just had the default conversions performed
    5466              :    or they have both just been converted to some other type in which
    5467              :    the arithmetic is to be done.
    5468              : 
    5469              :    C++: must do special pointer arithmetic when implementing
    5470              :    multiple inheritance, and deal with pointer to member functions.  */
    5471              : 
    5472              : tree
    5473    144528760 : cp_build_binary_op (const op_location_t &location,
    5474              :                     enum tree_code code, tree orig_op0, tree orig_op1,
    5475              :                     tsubst_flags_t complain)
    5476              : {
    5477    144528760 :   tree op0, op1;
    5478    144528760 :   enum tree_code code0, code1;
    5479    144528760 :   tree type0, type1, orig_type0, orig_type1;
    5480    144528760 :   const char *invalid_op_diag;
    5481              : 
    5482              :   /* Expression code to give to the expression when it is built.
    5483              :      Normally this is CODE, which is what the caller asked for,
    5484              :      but in some special cases we change it.  */
    5485    144528760 :   enum tree_code resultcode = code;
    5486              : 
    5487              :   /* Data type in which the computation is to be performed.
    5488              :      In the simplest cases this is the common type of the arguments.  */
    5489    144528760 :   tree result_type = NULL_TREE;
    5490              : 
    5491              :   /* When the computation is in excess precision, the type of the
    5492              :      final EXCESS_PRECISION_EXPR.  */
    5493    144528760 :   tree semantic_result_type = NULL;
    5494              : 
    5495              :   /* Nonzero means operands have already been type-converted
    5496              :      in whatever way is necessary.
    5497              :      Zero means they need to be converted to RESULT_TYPE.  */
    5498    144528760 :   int converted = 0;
    5499              : 
    5500              :   /* Nonzero means create the expression with this type, rather than
    5501              :      RESULT_TYPE.  */
    5502    144528760 :   tree build_type = 0;
    5503              : 
    5504              :   /* Nonzero means after finally constructing the expression
    5505              :      convert it to this type.  */
    5506    144528760 :   tree final_type = 0;
    5507              : 
    5508    144528760 :   tree result;
    5509              : 
    5510              :   /* Nonzero if this is an operation like MIN or MAX which can
    5511              :      safely be computed in short if both args are promoted shorts.
    5512              :      Also implies COMMON.
    5513              :      -1 indicates a bitwise operation; this makes a difference
    5514              :      in the exact conditions for when it is safe to do the operation
    5515              :      in a narrower mode.  */
    5516    144528760 :   int shorten = 0;
    5517              : 
    5518              :   /* Nonzero if this is a comparison operation;
    5519              :      if both args are promoted shorts, compare the original shorts.
    5520              :      Also implies COMMON.  */
    5521    144528760 :   int short_compare = 0;
    5522              : 
    5523              :   /* Nonzero if this is a right-shift operation, which can be computed on the
    5524              :      original short and then promoted if the operand is a promoted short.  */
    5525    144528760 :   int short_shift = 0;
    5526              : 
    5527              :   /* Nonzero means set RESULT_TYPE to the common type of the args.  */
    5528    144528760 :   int common = 0;
    5529              : 
    5530              :   /* True if both operands have arithmetic type.  */
    5531    144528760 :   bool arithmetic_types_p;
    5532              : 
    5533              :   /* Remember whether we're doing / or %.  */
    5534    144528760 :   bool doing_div_or_mod = false;
    5535              : 
    5536              :   /* Remember whether we're doing << or >>.  */
    5537    144528760 :   bool doing_shift = false;
    5538              : 
    5539              :   /* Tree holding instrumentation expression.  */
    5540    144528760 :   tree instrument_expr = NULL_TREE;
    5541              : 
    5542              :   /* True means this is an arithmetic operation that may need excess
    5543              :      precision.  */
    5544    144528760 :   bool may_need_excess_precision;
    5545              : 
    5546              :   /* Apply default conversions.  */
    5547    144528760 :   op0 = resolve_nondeduced_context (orig_op0, complain);
    5548    144528760 :   op1 = resolve_nondeduced_context (orig_op1, complain);
    5549              : 
    5550    144528760 :   if (code == TRUTH_AND_EXPR || code == TRUTH_ANDIF_EXPR
    5551    130717687 :       || code == TRUTH_OR_EXPR || code == TRUTH_ORIF_EXPR
    5552    127315031 :       || code == TRUTH_XOR_EXPR)
    5553              :     {
    5554     17213729 :       if (!really_overloaded_fn (op0) && !VOID_TYPE_P (TREE_TYPE (op0)))
    5555     17213711 :         op0 = decay_conversion (op0, complain);
    5556     17213729 :       if (!really_overloaded_fn (op1) && !VOID_TYPE_P (TREE_TYPE (op1)))
    5557     17213729 :         op1 = decay_conversion (op1, complain);
    5558              :     }
    5559              :   else
    5560              :     {
    5561    127315031 :       if (!really_overloaded_fn (op0) && !VOID_TYPE_P (TREE_TYPE (op0)))
    5562    127314982 :         op0 = cp_default_conversion (op0, complain);
    5563    127315031 :       if (!really_overloaded_fn (op1) && !VOID_TYPE_P (TREE_TYPE (op1)))
    5564    127315012 :         op1 = cp_default_conversion (op1, complain);
    5565              :     }
    5566              : 
    5567              :   /* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue.  */
    5568    152890441 :   STRIP_TYPE_NOPS (op0);
    5569    177474544 :   STRIP_TYPE_NOPS (op1);
    5570              : 
    5571              :   /* DTRT if one side is an overloaded function, but complain about it.  */
    5572    144528760 :   if (type_unknown_p (op0))
    5573              :     {
    5574            9 :       tree t = instantiate_type (TREE_TYPE (op1), op0, tf_none);
    5575            9 :       if (t != error_mark_node)
    5576              :         {
    5577            0 :           if (complain & tf_error)
    5578            0 :             permerror (location,
    5579              :                        "assuming cast to type %qT from overloaded function",
    5580            0 :                        TREE_TYPE (t));
    5581              :           op0 = t;
    5582              :         }
    5583              :     }
    5584    144528760 :   if (type_unknown_p (op1))
    5585              :     {
    5586            3 :       tree t = instantiate_type (TREE_TYPE (op0), op1, tf_none);
    5587            3 :       if (t != error_mark_node)
    5588              :         {
    5589            3 :           if (complain & tf_error)
    5590            3 :             permerror (location,
    5591              :                        "assuming cast to type %qT from overloaded function",
    5592            3 :                        TREE_TYPE (t));
    5593              :           op1 = t;
    5594              :         }
    5595              :     }
    5596              : 
    5597    144528760 :   orig_type0 = type0 = TREE_TYPE (op0);
    5598    144528760 :   orig_type1 = type1 = TREE_TYPE (op1);
    5599    144528760 :   tree non_ep_op0 = op0;
    5600    144528760 :   tree non_ep_op1 = op1;
    5601              : 
    5602              :   /* The expression codes of the data types of the arguments tell us
    5603              :      whether the arguments are integers, floating, pointers, etc.  */
    5604    144528760 :   code0 = TREE_CODE (type0);
    5605    144528760 :   code1 = TREE_CODE (type1);
    5606              : 
    5607              :   /* If an error was already reported for one of the arguments,
    5608              :      avoid reporting another error.  */
    5609    144528760 :   if (code0 == ERROR_MARK || code1 == ERROR_MARK)
    5610          100 :     return error_mark_node;
    5611              : 
    5612    289057320 :   if ((invalid_op_diag
    5613    144528660 :        = targetm.invalid_binary_op (code, type0, type1)))
    5614              :     {
    5615            0 :       if (complain & tf_error)
    5616              :         {
    5617            0 :           if (code0 == REAL_TYPE
    5618            0 :               && code1 == REAL_TYPE
    5619            0 :               && (extended_float_type_p (type0)
    5620            0 :                   || extended_float_type_p (type1))
    5621            0 :               && cp_compare_floating_point_conversion_ranks (type0,
    5622              :                                                              type1) == 3)
    5623              :             {
    5624            0 :               rich_location richloc (line_table, location);
    5625            0 :               binary_op_error (&richloc, code, type0, type1);
    5626            0 :             }
    5627              :           else
    5628            0 :             error (invalid_op_diag);
    5629              :         }
    5630            0 :       return error_mark_node;
    5631              :     }
    5632              : 
    5633    144528660 :   switch (code)
    5634              :     {
    5635              :     case PLUS_EXPR:
    5636              :     case MINUS_EXPR:
    5637              :     case MULT_EXPR:
    5638              :     case TRUNC_DIV_EXPR:
    5639              :     case CEIL_DIV_EXPR:
    5640              :     case FLOOR_DIV_EXPR:
    5641              :     case ROUND_DIV_EXPR:
    5642              :     case EXACT_DIV_EXPR:
    5643              :       may_need_excess_precision = true;
    5644              :       break;
    5645     50910043 :     case EQ_EXPR:
    5646     50910043 :     case NE_EXPR:
    5647     50910043 :     case LE_EXPR:
    5648     50910043 :     case GE_EXPR:
    5649     50910043 :     case LT_EXPR:
    5650     50910043 :     case GT_EXPR:
    5651     50910043 :     case SPACESHIP_EXPR:
    5652              :       /* Excess precision for implicit conversions of integers to
    5653              :          floating point.  */
    5654     11047135 :       may_need_excess_precision = (ANY_INTEGRAL_TYPE_P (type0)
    5655     61950077 :                                    || ANY_INTEGRAL_TYPE_P (type1));
    5656              :       break;
    5657              :     default:
    5658    144528660 :       may_need_excess_precision = false;
    5659              :       break;
    5660              :     }
    5661    144528660 :   if (TREE_CODE (op0) == EXCESS_PRECISION_EXPR)
    5662              :     {
    5663        11415 :       op0 = TREE_OPERAND (op0, 0);
    5664        11415 :       type0 = TREE_TYPE (op0);
    5665              :     }
    5666    144517245 :   else if (may_need_excess_precision
    5667    108249837 :            && (code0 == REAL_TYPE || code0 == COMPLEX_TYPE))
    5668     26740848 :     if (tree eptype = excess_precision_type (type0))
    5669              :       {
    5670        30242 :         type0 = eptype;
    5671        30242 :         op0 = convert (eptype, op0);
    5672              :       }
    5673    144528660 :   if (TREE_CODE (op1) == EXCESS_PRECISION_EXPR)
    5674              :     {
    5675        14289 :       op1 = TREE_OPERAND (op1, 0);
    5676        14289 :       type1 = TREE_TYPE (op1);
    5677              :     }
    5678    144514371 :   else if (may_need_excess_precision
    5679    108248639 :            && (code1 == REAL_TYPE || code1 == COMPLEX_TYPE))
    5680     26599726 :     if (tree eptype = excess_precision_type (type1))
    5681              :       {
    5682        20445 :         type1 = eptype;
    5683        20445 :         op1 = convert (eptype, op1);
    5684              :       }
    5685              : 
    5686              :   /* Issue warnings about peculiar, but valid, uses of NULL.  */
    5687    289057235 :   if ((null_node_p (orig_op0) || null_node_p (orig_op1))
    5688              :       /* It's reasonable to use pointer values as operands of &&
    5689              :          and ||, so NULL is no exception.  */
    5690        11728 :       && code != TRUTH_ANDIF_EXPR && code != TRUTH_ORIF_EXPR
    5691        11713 :       && ( /* Both are NULL (or 0) and the operation was not a
    5692              :               comparison or a pointer subtraction.  */
    5693        11786 :           (null_ptr_cst_p (orig_op0) && null_ptr_cst_p (orig_op1)
    5694           27 :            && code != EQ_EXPR && code != NE_EXPR && code != MINUS_EXPR)
    5695              :           /* Or if one of OP0 or OP1 is neither a pointer nor NULL.  */
    5696        11701 :           || (!null_ptr_cst_p (orig_op0)
    5697        11640 :               && !TYPE_PTR_OR_PTRMEM_P (type0))
    5698        11689 :           || (!null_ptr_cst_p (orig_op1)
    5699           46 :               && !TYPE_PTR_OR_PTRMEM_P (type1)))
    5700    144528699 :       && (complain & tf_warning))
    5701              :     {
    5702           39 :       location_t loc =
    5703           39 :         expansion_point_location_if_in_system_header (input_location);
    5704              : 
    5705           39 :       warning_at (loc, OPT_Wpointer_arith, "NULL used in arithmetic");
    5706              :     }
    5707              : 
    5708              :   /* In case when one of the operands of the binary operation is
    5709              :      a vector and another is a scalar -- convert scalar to vector.  */
    5710    144596782 :   if ((gnu_vector_type_p (type0) && code1 != VECTOR_TYPE)
    5711    144595805 :       || (gnu_vector_type_p (type1) && code0 != VECTOR_TYPE))
    5712              :     {
    5713         1062 :       enum stv_conv convert_flag
    5714         1062 :         = scalar_to_vector (location, code, non_ep_op0, non_ep_op1,
    5715              :                             complain & tf_error);
    5716              : 
    5717         1062 :       switch (convert_flag)
    5718              :         {
    5719           21 :           case stv_error:
    5720           21 :             return error_mark_node;
    5721           55 :           case stv_firstarg:
    5722           55 :             {
    5723           55 :               op0 = convert (TREE_TYPE (type1), op0);
    5724           55 :               op0 = cp_save_expr (op0);
    5725           55 :               op0 = build_vector_from_val (type1, op0);
    5726           55 :               orig_type0 = type0 = TREE_TYPE (op0);
    5727           55 :               code0 = TREE_CODE (type0);
    5728           55 :               converted = 1;
    5729           55 :               break;
    5730              :             }
    5731          865 :           case stv_secondarg:
    5732          865 :             {
    5733          865 :               op1 = convert (TREE_TYPE (type0), op1);
    5734          865 :               op1 = cp_save_expr (op1);
    5735          865 :               op1 = build_vector_from_val (type0, op1);
    5736          865 :               orig_type1 = type1 = TREE_TYPE (op1);
    5737          865 :               code1 = TREE_CODE (type1);
    5738          865 :               converted = 1;
    5739          865 :               break;
    5740              :             }
    5741              :           default:
    5742              :             break;
    5743              :         }
    5744              :     }
    5745              : 
    5746    144528639 :   switch (code)
    5747              :     {
    5748     15898901 :     case MINUS_EXPR:
    5749              :       /* Subtraction of two similar pointers.
    5750              :          We must subtract them as integers, then divide by object size.  */
    5751     15898901 :       if (code0 == POINTER_TYPE && code1 == POINTER_TYPE
    5752     17360184 :           && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (type0),
    5753      1461283 :                                                         TREE_TYPE (type1)))
    5754              :         {
    5755      1461280 :           result = pointer_diff (location, op0, op1,
    5756              :                                  common_pointer_type (type0, type1), complain,
    5757              :                                  &instrument_expr);
    5758      1461280 :           if (instrument_expr != NULL)
    5759           84 :             result = build2 (COMPOUND_EXPR, TREE_TYPE (result),
    5760              :                              instrument_expr, result);
    5761              : 
    5762      1461280 :           return result;
    5763              :         }
    5764              :       /* In all other cases except pointer - int, the usual arithmetic
    5765              :          rules apply.  */
    5766     14437621 :       else if (!(code0 == POINTER_TYPE && code1 == INTEGER_TYPE))
    5767              :         {
    5768              :           common = 1;
    5769              :           break;
    5770              :         }
    5771              :       /* The pointer - int case is just like pointer + int; fall
    5772              :          through.  */
    5773     20879856 :       gcc_fallthrough ();
    5774     20879856 :     case PLUS_EXPR:
    5775     20879856 :       if ((code0 == POINTER_TYPE || code1 == POINTER_TYPE)
    5776      7606439 :           && (code0 == INTEGER_TYPE || code1 == INTEGER_TYPE))
    5777              :         {
    5778      7606430 :           tree ptr_operand;
    5779      7606430 :           tree int_operand;
    5780      7606430 :           ptr_operand = ((code0 == POINTER_TYPE) ? op0 : op1);
    5781       122935 :           int_operand = ((code0 == INTEGER_TYPE) ? op0 : op1);
    5782      7606430 :           if (processing_template_decl)
    5783              :             {
    5784      2158180 :               result_type = TREE_TYPE (ptr_operand);
    5785      2158180 :               break;
    5786              :             }
    5787      5448250 :           return cp_pointer_int_sum (location, code,
    5788              :                                      ptr_operand,
    5789              :                                      int_operand,
    5790      5448250 :                                      complain);
    5791              :         }
    5792              :       common = 1;
    5793              :       break;
    5794              : 
    5795              :     case MULT_EXPR:
    5796    137575532 :       common = 1;
    5797              :       break;
    5798              : 
    5799     11918523 :     case TRUNC_DIV_EXPR:
    5800     11918523 :     case CEIL_DIV_EXPR:
    5801     11918523 :     case FLOOR_DIV_EXPR:
    5802     11918523 :     case ROUND_DIV_EXPR:
    5803     11918523 :     case EXACT_DIV_EXPR:
    5804     11918523 :       if (TREE_CODE (op0) == SIZEOF_EXPR && TREE_CODE (op1) == SIZEOF_EXPR)
    5805              :         {
    5806       120087 :           tree type0 = TREE_OPERAND (op0, 0);
    5807       120087 :           tree type1 = TREE_OPERAND (op1, 0);
    5808       120087 :           tree first_arg = tree_strip_any_location_wrapper (type0);
    5809       120087 :           if (!TYPE_P (type0))
    5810        79415 :             type0 = TREE_TYPE (type0);
    5811       120087 :           if (!TYPE_P (type1))
    5812        44707 :             type1 = TREE_TYPE (type1);
    5813       120087 :           if (type0
    5814       120087 :               && type1
    5815       101134 :               && INDIRECT_TYPE_P (type0)
    5816       120162 :               && same_type_p (TREE_TYPE (type0), type1))
    5817              :             {
    5818           27 :               if (!(TREE_CODE (first_arg) == PARM_DECL
    5819           21 :                     && DECL_ARRAY_PARAMETER_P (first_arg)
    5820            3 :                     && warn_sizeof_array_argument)
    5821           42 :                   && (complain & tf_warning))
    5822              :                 {
    5823           21 :                   auto_diagnostic_group d;
    5824           21 :                   if (warning_at (location, OPT_Wsizeof_pointer_div,
    5825              :                                   "division %<sizeof (%T) / sizeof (%T)%> does "
    5826              :                                   "not compute the number of array elements",
    5827              :                                   type0, type1))
    5828           18 :                     if (DECL_P (first_arg))
    5829           18 :                       inform (DECL_SOURCE_LOCATION (first_arg),
    5830              :                               "first %<sizeof%> operand was declared here");
    5831           21 :                 }
    5832              :             }
    5833       120063 :           else if (!dependent_type_p (type0)
    5834        25857 :                    && !dependent_type_p (type1)
    5835        25757 :                    && TREE_CODE (type0) == ARRAY_TYPE
    5836        20930 :                    && !char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type0)))
    5837              :                    /* Set by finish_parenthesized_expr.  */
    5838        20279 :                    && !warning_suppressed_p (op1, OPT_Wsizeof_array_div)
    5839       140324 :                    && (complain & tf_warning))
    5840        20261 :             maybe_warn_sizeof_array_div (location, first_arg, type0,
    5841              :                                          op1, non_reference (type1));
    5842              :         }
    5843              : 
    5844     11918523 :       if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
    5845              :            || code0 == COMPLEX_TYPE || code0 == VECTOR_TYPE)
    5846     11918505 :           && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
    5847              :               || code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE))
    5848              :         {
    5849     11918496 :           enum tree_code tcode0 = code0, tcode1 = code1;
    5850     11918496 :           doing_div_or_mod = true;
    5851     11918496 :           warn_for_div_by_zero (location, fold_for_warn (op1));
    5852              : 
    5853     11918496 :           if (tcode0 == COMPLEX_TYPE || tcode0 == VECTOR_TYPE)
    5854        56869 :             tcode0 = TREE_CODE (TREE_TYPE (TREE_TYPE (op0)));
    5855     11918496 :           if (tcode1 == COMPLEX_TYPE || tcode1 == VECTOR_TYPE)
    5856        29298 :             tcode1 = TREE_CODE (TREE_TYPE (TREE_TYPE (op1)));
    5857              : 
    5858     11918499 :           if (!((tcode0 == INTEGER_TYPE
    5859      5240048 :                  || (tcode0 == ENUMERAL_TYPE && code0 == VECTOR_TYPE))
    5860              :                 && (tcode1 == INTEGER_TYPE
    5861        93605 :                     || (tcode1 == ENUMERAL_TYPE && code1 == VECTOR_TYPE))))
    5862              :             resultcode = RDIV_EXPR;
    5863              :           else
    5864              :             {
    5865              :               /* When dividing two signed integers, we have to promote to int.
    5866              :                  unless we divide by a constant != -1.  Note that default
    5867              :                  conversion will have been performed on the operands at this
    5868              :                  point, so we have to dig out the original type to find out if
    5869              :                  it was unsigned.  */
    5870      6584849 :               tree stripped_op1 = tree_strip_any_location_wrapper (op1);
    5871      6584849 :               shorten = may_shorten_divmod (op0, stripped_op1);
    5872              :             }
    5873              : 
    5874              :           common = 1;
    5875              :         }
    5876              :       break;
    5877              : 
    5878      2812062 :     case BIT_AND_EXPR:
    5879      2812062 :     case BIT_IOR_EXPR:
    5880      2812062 :     case BIT_XOR_EXPR:
    5881      2812062 :       if ((code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
    5882      2812062 :           || (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE
    5883        21080 :               && !VECTOR_FLOAT_TYPE_P (type0)
    5884        21062 :               && !VECTOR_FLOAT_TYPE_P (type1)))
    5885              :         shorten = -1;
    5886              :       break;
    5887              : 
    5888      1511277 :     case TRUNC_MOD_EXPR:
    5889      1511277 :     case FLOOR_MOD_EXPR:
    5890      1511277 :       doing_div_or_mod = true;
    5891      1511277 :       warn_for_div_by_zero (location, fold_for_warn (op1));
    5892              : 
    5893      1511277 :       if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE
    5894           28 :           && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE
    5895      1511305 :           && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE)
    5896              :         common = 1;
    5897      1511249 :       else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
    5898              :         {
    5899              :           /* Although it would be tempting to shorten always here, that loses
    5900              :              on some targets, since the modulo instruction is undefined if the
    5901              :              quotient can't be represented in the computation mode.  We shorten
    5902              :              only if unsigned or if dividing by something we know != -1.  */
    5903      1511225 :           tree stripped_op1 = tree_strip_any_location_wrapper (op1);
    5904      1511225 :           shorten = may_shorten_divmod (op0, stripped_op1);
    5905      1511225 :           common = 1;
    5906              :         }
    5907              :       break;
    5908              : 
    5909     17213714 :     case TRUTH_ANDIF_EXPR:
    5910     17213714 :     case TRUTH_ORIF_EXPR:
    5911     17213714 :     case TRUTH_AND_EXPR:
    5912     17213714 :     case TRUTH_OR_EXPR:
    5913     17213714 :       if (!VECTOR_TYPE_P (type0) && gnu_vector_type_p (type1))
    5914              :         {
    5915            3 :           if (!COMPARISON_CLASS_P (op1))
    5916            3 :             op1 = cp_build_binary_op (EXPR_LOCATION (op1), NE_EXPR, op1,
    5917              :                                       build_zero_cst (type1), complain);
    5918            3 :           if (code == TRUTH_ANDIF_EXPR)
    5919              :             {
    5920            0 :               tree z = build_zero_cst (TREE_TYPE (op1));
    5921            0 :               return build_conditional_expr (location, op0, op1, z, complain);
    5922              :             }
    5923            3 :           else if (code == TRUTH_ORIF_EXPR)
    5924              :             {
    5925            3 :               tree m1 = build_all_ones_cst (TREE_TYPE (op1));
    5926            3 :               return build_conditional_expr (location, op0, m1, op1, complain);
    5927              :             }
    5928              :           else
    5929            0 :             gcc_unreachable ();
    5930              :         }
    5931     17213711 :       if (gnu_vector_type_p (type0)
    5932     17213711 :           && (!VECTOR_TYPE_P (type1) || gnu_vector_type_p (type1)))
    5933              :         {
    5934           24 :           if (!COMPARISON_CLASS_P (op0))
    5935           24 :             op0 = cp_build_binary_op (EXPR_LOCATION (op0), NE_EXPR, op0,
    5936              :                                       build_zero_cst (type0), complain);
    5937           24 :           if (!VECTOR_TYPE_P (type1))
    5938              :             {
    5939            9 :               tree m1 = build_all_ones_cst (TREE_TYPE (op0));
    5940            9 :               tree z = build_zero_cst (TREE_TYPE (op0));
    5941            9 :               op1 = build_conditional_expr (location, op1, m1, z, complain);
    5942              :             }
    5943           15 :           else if (!COMPARISON_CLASS_P (op1))
    5944           15 :             op1 = cp_build_binary_op (EXPR_LOCATION (op1), NE_EXPR, op1,
    5945              :                                       build_zero_cst (type1), complain);
    5946              : 
    5947           24 :           if (code == TRUTH_ANDIF_EXPR)
    5948              :             code = BIT_AND_EXPR;
    5949            9 :           else if (code == TRUTH_ORIF_EXPR)
    5950              :             code = BIT_IOR_EXPR;
    5951              :           else
    5952            0 :             gcc_unreachable ();
    5953              : 
    5954           24 :           return cp_build_binary_op (location, code, op0, op1, complain);
    5955              :         }
    5956              : 
    5957     17213687 :       if (warn_constant_logical_operand
    5958       131239 :           && (complain & tf_warning)
    5959       128828 :           && (code0 == INTEGER_TYPE || code0 == ENUMERAL_TYPE)
    5960        11190 :           && (code1 == INTEGER_TYPE || code1 == ENUMERAL_TYPE))
    5961              :         {
    5962         4861 :           tree cop0 = fold_for_warn (op0), cop1 = fold_for_warn (op1);
    5963         4861 :           const char *name
    5964              :             = ((code == TRUTH_ANDIF_EXPR || code == TRUTH_AND_EXPR)
    5965              :                ? "&&" : "||");
    5966         4946 :           auto enum_other_than_0_1 = [] (tree type) {
    5967           85 :             if (TREE_CODE (type) != ENUMERAL_TYPE)
    5968              :               return false;
    5969          154 :             for (tree l = TYPE_VALUES (type); l; l = TREE_CHAIN (l))
    5970              :               {
    5971          125 :                 tree v = DECL_INITIAL (TREE_VALUE (l));
    5972          125 :                 if (!integer_zerop (v) && !integer_onep (v))
    5973              :                   return true;
    5974              :               }
    5975              :             return false;
    5976              :           };
    5977        14535 :           auto diagnose_constant_logical_operand = [=] (tree val, tree type) {
    5978         9674 :             if (TREE_CODE (val) != INTEGER_CST || integer_zerop (val))
    5979         9517 :               return false;
    5980          157 :             if (integer_onep (val) && !enum_other_than_0_1 (type))
    5981              :               return false;
    5982           96 :             gcc_rich_location richloc (location);
    5983           96 :             richloc.add_fixit_replace (name + 1);
    5984           96 :             auto_diagnostic_group d;
    5985           96 :             if (warning_at (location, OPT_Wconstant_logical_operand,
    5986              :                             "use of logical %qs with constant operand %qE",
    5987              :                             name, val))
    5988           96 :               inform (&richloc, "use %qs for bitwise operation", name + 1);
    5989           96 :             return true;
    5990           96 :           };
    5991         4861 :           if (!diagnose_constant_logical_operand (cop1, orig_type1))
    5992         4813 :             diagnose_constant_logical_operand (cop0, orig_type0);
    5993              :         }
    5994              : 
    5995     17213687 :       result_type = boolean_type_node;
    5996     17213687 :       break;
    5997              : 
    5998              :       /* Shift operations: result has same type as first operand;
    5999              :          always convert second operand to int.
    6000              :          Also set SHORT_SHIFT if shifting rightward.  */
    6001              : 
    6002      1090469 :     case RSHIFT_EXPR:
    6003      1090469 :       if (gnu_vector_type_p (type0)
    6004          186 :           && code1 == INTEGER_TYPE
    6005      1090525 :           && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE)
    6006              :         {
    6007              :           result_type = type0;
    6008              :           converted = 1;
    6009              :         }
    6010      1090413 :       else if (gnu_vector_type_p (type0)
    6011          130 :                && gnu_vector_type_p (type1)
    6012          130 :                && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE
    6013          127 :                && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE
    6014      1090540 :                && known_eq (TYPE_VECTOR_SUBPARTS (type0),
    6015              :                             TYPE_VECTOR_SUBPARTS (type1)))
    6016              :         {
    6017              :           result_type = type0;
    6018              :           converted = 1;
    6019              :         }
    6020      1090286 :       else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
    6021              :         {
    6022      1090259 :           tree const_op1 = fold_for_warn (op1);
    6023      1090259 :           if (TREE_CODE (const_op1) != INTEGER_CST)
    6024       100770 :             const_op1 = op1;
    6025      1090259 :           result_type = type0;
    6026      1090259 :           doing_shift = true;
    6027      1090259 :           if (TREE_CODE (const_op1) == INTEGER_CST)
    6028              :             {
    6029       989489 :               if (tree_int_cst_lt (const_op1, integer_zero_node))
    6030              :                 {
    6031           48 :                   if ((complain & tf_warning)
    6032           48 :                       && c_inhibit_evaluation_warnings == 0)
    6033           36 :                     warning_at (location, OPT_Wshift_count_negative,
    6034              :                                 "right shift count is negative");
    6035              :                 }
    6036              :               else
    6037              :                 {
    6038       989441 :                   if (!integer_zerop (const_op1))
    6039       989220 :                     short_shift = 1;
    6040              : 
    6041       989441 :                   if (compare_tree_int (const_op1, TYPE_PRECISION (type0)) >= 0
    6042           46 :                       && (complain & tf_warning)
    6043       989487 :                       && c_inhibit_evaluation_warnings == 0)
    6044           34 :                     warning_at (location, OPT_Wshift_count_overflow,
    6045              :                                 "right shift count >= width of type");
    6046              :                 }
    6047              :             }
    6048              :           /* Avoid converting op1 to result_type later.  */
    6049              :           converted = 1;
    6050              :         }
    6051              :       break;
    6052              : 
    6053      3077210 :     case LSHIFT_EXPR:
    6054      3077210 :       if (gnu_vector_type_p (type0)
    6055          229 :           && code1 == INTEGER_TYPE
    6056      3077254 :           && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE)
    6057              :         {
    6058              :           result_type = type0;
    6059              :           converted = 1;
    6060              :         }
    6061      3077166 :       else if (gnu_vector_type_p (type0)
    6062          185 :                && gnu_vector_type_p (type1)
    6063          185 :                && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE
    6064          182 :                && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE
    6065      3077345 :                && known_eq (TYPE_VECTOR_SUBPARTS (type0),
    6066              :                             TYPE_VECTOR_SUBPARTS (type1)))
    6067              :         {
    6068              :           result_type = type0;
    6069              :           converted = 1;
    6070              :         }
    6071      3076987 :       else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
    6072              :         {
    6073      3076932 :           tree const_op0 = fold_for_warn (op0);
    6074      3076932 :           if (TREE_CODE (const_op0) != INTEGER_CST)
    6075       263728 :             const_op0 = op0;
    6076      3076932 :           tree const_op1 = fold_for_warn (op1);
    6077      3076932 :           if (TREE_CODE (const_op1) != INTEGER_CST)
    6078       218843 :             const_op1 = op1;
    6079      3076932 :           result_type = type0;
    6080      3076932 :           doing_shift = true;
    6081      3076932 :           if (TREE_CODE (const_op0) == INTEGER_CST
    6082      2813204 :               && tree_int_cst_sgn (const_op0) < 0
    6083          280 :               && !TYPE_OVERFLOW_WRAPS (type0)
    6084          196 :               && (complain & tf_warning)
    6085      3077128 :               && c_inhibit_evaluation_warnings == 0)
    6086          196 :             warning_at (location, OPT_Wshift_negative_value,
    6087              :                         "left shift of negative value");
    6088      3076932 :           if (TREE_CODE (const_op1) == INTEGER_CST)
    6089              :             {
    6090      2858089 :               if (tree_int_cst_lt (const_op1, integer_zero_node))
    6091              :                 {
    6092           57 :                   if ((complain & tf_warning)
    6093           57 :                       && c_inhibit_evaluation_warnings == 0)
    6094           39 :                     warning_at (location, OPT_Wshift_count_negative,
    6095              :                                 "left shift count is negative");
    6096              :                 }
    6097      2858032 :               else if (compare_tree_int (const_op1,
    6098      2858032 :                                          TYPE_PRECISION (type0)) >= 0)
    6099              :                 {
    6100           83 :                   if ((complain & tf_warning)
    6101           61 :                       && c_inhibit_evaluation_warnings == 0)
    6102           45 :                     warning_at (location, OPT_Wshift_count_overflow,
    6103              :                                 "left shift count >= width of type");
    6104              :                 }
    6105      2857949 :               else if (TREE_CODE (const_op0) == INTEGER_CST
    6106      2632154 :                        && (complain & tf_warning))
    6107      2526242 :                 maybe_warn_shift_overflow (location, const_op0, const_op1);
    6108              :             }
    6109              :           /* Avoid converting op1 to result_type later.  */
    6110              :           converted = 1;
    6111              :         }
    6112              :       break;
    6113              : 
    6114     25531652 :     case EQ_EXPR:
    6115     25531652 :     case NE_EXPR:
    6116     25531652 :       if (gnu_vector_type_p (type0) && gnu_vector_type_p (type1))
    6117         2992 :         goto vector_compare;
    6118     25528660 :       if ((complain & tf_warning)
    6119     22688532 :           && c_inhibit_evaluation_warnings == 0
    6120     47132199 :           && (FLOAT_TYPE_P (type0) || FLOAT_TYPE_P (type1)))
    6121       780650 :         warning_at (location, OPT_Wfloat_equal,
    6122              :                     "comparing floating-point with %<==%> "
    6123              :                     "or %<!=%> is unsafe");
    6124     25528660 :       {
    6125     25528660 :         tree stripped_orig_op0 = tree_strip_any_location_wrapper (orig_op0);
    6126     25528660 :         tree stripped_orig_op1 = tree_strip_any_location_wrapper (orig_op1);
    6127     25528660 :         if ((complain & tf_warning_or_error)
    6128     25528660 :             && ((TREE_CODE (stripped_orig_op0) == STRING_CST
    6129           39 :                  && !integer_zerop (cp_fully_fold (op1)))
    6130     23148868 :                 || (TREE_CODE (stripped_orig_op1) == STRING_CST
    6131           68 :                     && !integer_zerop (cp_fully_fold (op0)))))
    6132           47 :           warning_at (location, OPT_Waddress,
    6133              :                       "comparison with string literal results in "
    6134              :                       "unspecified behavior");
    6135     25528613 :         else if (TREE_CODE (TREE_TYPE (orig_op0)) == ARRAY_TYPE
    6136     25528613 :                  && TREE_CODE (TREE_TYPE (orig_op1)) == ARRAY_TYPE)
    6137              :           {
    6138              :             /* P2865R5 made array comparisons ill-formed in C++26.  */
    6139           68 :             if (complain & tf_warning_or_error)
    6140           45 :               do_warn_array_compare (location, code, stripped_orig_op0,
    6141              :                                      stripped_orig_op1);
    6142           23 :             else if (cxx_dialect >= cxx26)
    6143            1 :               return error_mark_node;
    6144              :           }
    6145              :       }
    6146              : 
    6147     25528659 :       build_type = boolean_type_node;
    6148     25528659 :       if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
    6149              :            || code0 == COMPLEX_TYPE || code0 == ENUMERAL_TYPE)
    6150     21486203 :           && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
    6151              :               || code1 == COMPLEX_TYPE || code1 == ENUMERAL_TYPE))
    6152              :         short_compare = 1;
    6153        42288 :       else if (((code0 == POINTER_TYPE || TYPE_PTRDATAMEM_P (type0))
    6154      4037436 :                 && null_ptr_cst_p (orig_op1))
    6155              :                /* Handle, eg, (void*)0 (c++/43906), and more.  */
    6156      6423412 :                || (code0 == POINTER_TYPE
    6157      2302722 :                    && TYPE_PTR_P (type1) && integer_zerop (op1)))
    6158              :         {
    6159      1752879 :           if (TYPE_PTR_P (type1))
    6160        18563 :             result_type = composite_pointer_type (location,
    6161              :                                                   type0, type1, op0, op1,
    6162              :                                                   CPO_COMPARISON, complain);
    6163              :           else
    6164              :             result_type = type0;
    6165              : 
    6166      1752879 :           if (char_type_p (TREE_TYPE (orig_op1)))
    6167              :             {
    6168           10 :               auto_diagnostic_group d;
    6169           10 :               if (warning_at (location, OPT_Wpointer_compare,
    6170              :                               "comparison between pointer and zero character "
    6171              :                               "constant"))
    6172           10 :                 inform (location,
    6173              :                         "did you mean to dereference the pointer?");
    6174           10 :             }
    6175      1752879 :           warn_for_null_address (location, op0, complain);
    6176              :         }
    6177         5488 :       else if (((code1 == POINTER_TYPE || TYPE_PTRDATAMEM_P (type1))
    6178      2320919 :                 && null_ptr_cst_p (orig_op0))
    6179              :                /* Handle, eg, (void*)0 (c++/43906), and more.  */
    6180      4651077 :                || (code1 == POINTER_TYPE
    6181      2319628 :                    && TYPE_PTR_P (type0) && integer_zerop (op0)))
    6182              :         {
    6183          961 :           if (TYPE_PTR_P (type0))
    6184           68 :             result_type = composite_pointer_type (location,
    6185              :                                                   type0, type1, op0, op1,
    6186              :                                                   CPO_COMPARISON, complain);
    6187              :           else
    6188              :             result_type = type1;
    6189              : 
    6190          961 :           if (char_type_p (TREE_TYPE (orig_op0)))
    6191              :             {
    6192           10 :               auto_diagnostic_group d;
    6193           10 :               if (warning_at (location, OPT_Wpointer_compare,
    6194              :                              "comparison between pointer and zero character "
    6195              :                              "constant"))
    6196           10 :                 inform (location,
    6197              :                         "did you mean to dereference the pointer?");
    6198           10 :             }
    6199          961 :           warn_for_null_address (location, op1, complain);
    6200              :         }
    6201      2325024 :       else if ((code0 == POINTER_TYPE && code1 == POINTER_TYPE)
    6202        40991 :                || (TYPE_PTRDATAMEM_P (type0) && TYPE_PTRDATAMEM_P (type1)))
    6203      2284431 :         result_type = composite_pointer_type (location,
    6204              :                                               type0, type1, op0, op1,
    6205              :                                               CPO_COMPARISON, complain);
    6206        40593 :       else if (null_ptr_cst_p (orig_op0) && null_ptr_cst_p (orig_op1))
    6207              :         /* One of the operands must be of nullptr_t type.  */
    6208           69 :         result_type = TREE_TYPE (nullptr_node);
    6209        40524 :       else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
    6210              :         {
    6211           58 :           result_type = type0;
    6212           58 :           if (complain & tf_error)
    6213           56 :             permerror (location, "ISO C++ forbids comparison between "
    6214              :                        "pointer and integer");
    6215              :           else
    6216            2 :             return error_mark_node;
    6217              :         }
    6218        40466 :       else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
    6219              :         {
    6220        35527 :           result_type = type1;
    6221        35527 :           if (complain & tf_error)
    6222           69 :             permerror (location, "ISO C++ forbids comparison between "
    6223              :                        "pointer and integer");
    6224              :           else
    6225        35458 :             return error_mark_node;
    6226              :         }
    6227         4939 :       else if (TYPE_PTRMEMFUNC_P (type0) && null_ptr_cst_p (orig_op1))
    6228              :         {
    6229          212 :           if (TARGET_PTRMEMFUNC_VBIT_LOCATION
    6230              :               == ptrmemfunc_vbit_in_delta)
    6231              :             {
    6232              :               tree pfn0, delta0, e1, e2;
    6233              : 
    6234              :               if (TREE_SIDE_EFFECTS (op0))
    6235              :                 op0 = cp_save_expr (op0);
    6236              : 
    6237              :               pfn0 = pfn_from_ptrmemfunc (op0);
    6238              :               delta0 = delta_from_ptrmemfunc (op0);
    6239              :               {
    6240              :                 /* If we will warn below about a null-address compare
    6241              :                    involving the orig_op0 ptrmemfunc, we'd likely also
    6242              :                    warn about the pfn0's null-address compare, and
    6243              :                    that would be redundant, so suppress it.  */
    6244              :                 warning_sentinel ws (warn_address);
    6245              :                 e1 = cp_build_binary_op (location,
    6246              :                                          EQ_EXPR,
    6247              :                                          pfn0,
    6248              :                                          build_zero_cst (TREE_TYPE (pfn0)),
    6249              :                                          complain);
    6250              :               }
    6251              :               e2 = cp_build_binary_op (location,
    6252              :                                        BIT_AND_EXPR,
    6253              :                                        delta0,
    6254              :                                        integer_one_node,
    6255              :                                        complain);
    6256              : 
    6257              :               if (complain & tf_warning)
    6258              :                 maybe_warn_zero_as_null_pointer_constant (op1, input_location);
    6259              : 
    6260              :               e2 = cp_build_binary_op (location,
    6261              :                                        EQ_EXPR, e2, integer_zero_node,
    6262              :                                        complain);
    6263              :               op0 = cp_build_binary_op (location,
    6264              :                                         TRUTH_ANDIF_EXPR, e1, e2,
    6265              :                                         complain);
    6266              :               op1 = cp_convert (TREE_TYPE (op0), integer_one_node, complain);
    6267              :             }
    6268              :           else
    6269              :             {
    6270          212 :               op0 = build_ptrmemfunc_access_expr (op0, pfn_identifier);
    6271          212 :               op1 = cp_convert (TREE_TYPE (op0), op1, complain);
    6272              :             }
    6273          212 :           result_type = TREE_TYPE (op0);
    6274              : 
    6275          212 :           warn_for_null_address (location, orig_op0, complain);
    6276              :         }
    6277         4727 :       else if (TYPE_PTRMEMFUNC_P (type1) && null_ptr_cst_p (orig_op0))
    6278           36 :         return cp_build_binary_op (location, code, op1, op0, complain);
    6279         4691 :       else if (TYPE_PTRMEMFUNC_P (type0) && TYPE_PTRMEMFUNC_P (type1))
    6280              :         {
    6281          135 :           tree type;
    6282              :           /* E will be the final comparison.  */
    6283          135 :           tree e;
    6284              :           /* E1 and E2 are for scratch.  */
    6285          135 :           tree e1;
    6286          135 :           tree e2;
    6287          135 :           tree pfn0;
    6288          135 :           tree pfn1;
    6289          135 :           tree delta0;
    6290          135 :           tree delta1;
    6291              : 
    6292          135 :           type = composite_pointer_type (location, type0, type1, op0, op1,
    6293              :                                          CPO_COMPARISON, complain);
    6294              : 
    6295          135 :           if (!same_type_p (TREE_TYPE (op0), type))
    6296            6 :             op0 = cp_convert_and_check (type, op0, complain);
    6297          135 :           if (!same_type_p (TREE_TYPE (op1), type))
    6298            9 :             op1 = cp_convert_and_check (type, op1, complain);
    6299              : 
    6300          135 :           if (op0 == error_mark_node || op1 == error_mark_node)
    6301              :             return error_mark_node;
    6302              : 
    6303          132 :           if (TREE_SIDE_EFFECTS (op0))
    6304           69 :             op0 = cp_save_expr (op0);
    6305          132 :           if (TREE_SIDE_EFFECTS (op1))
    6306            3 :             op1 = cp_save_expr (op1);
    6307              : 
    6308          132 :           pfn0 = pfn_from_ptrmemfunc (op0);
    6309          132 :           pfn0 = cp_fully_fold (pfn0);
    6310              :           /* Avoid -Waddress warnings (c++/64877).  */
    6311          132 :           if (TREE_CODE (pfn0) == ADDR_EXPR)
    6312           20 :             suppress_warning (pfn0, OPT_Waddress);
    6313          132 :           pfn1 = pfn_from_ptrmemfunc (op1);
    6314          132 :           pfn1 = cp_fully_fold (pfn1);
    6315          132 :           delta0 = delta_from_ptrmemfunc (op0);
    6316          132 :           delta1 = delta_from_ptrmemfunc (op1);
    6317          132 :           if (TARGET_PTRMEMFUNC_VBIT_LOCATION
    6318              :               == ptrmemfunc_vbit_in_delta)
    6319              :             {
    6320              :               /* We generate:
    6321              : 
    6322              :                  (op0.pfn == op1.pfn
    6323              :                   && ((op0.delta == op1.delta)
    6324              :                        || (!op0.pfn && op0.delta & 1 == 0
    6325              :                            && op1.delta & 1 == 0))
    6326              : 
    6327              :                  The reason for the `!op0.pfn' bit is that a NULL
    6328              :                  pointer-to-member is any member with a zero PFN and
    6329              :                  LSB of the DELTA field is 0.  */
    6330              : 
    6331              :               e1 = cp_build_binary_op (location, BIT_AND_EXPR,
    6332              :                                        delta0,
    6333              :                                        integer_one_node,
    6334              :                                        complain);
    6335              :               e1 = cp_build_binary_op (location,
    6336              :                                        EQ_EXPR, e1, integer_zero_node,
    6337              :                                        complain);
    6338              :               e2 = cp_build_binary_op (location, BIT_AND_EXPR,
    6339              :                                        delta1,
    6340              :                                        integer_one_node,
    6341              :                                        complain);
    6342              :               e2 = cp_build_binary_op (location,
    6343              :                                        EQ_EXPR, e2, integer_zero_node,
    6344              :                                        complain);
    6345              :               e1 = cp_build_binary_op (location,
    6346              :                                        TRUTH_ANDIF_EXPR, e2, e1,
    6347              :                                        complain);
    6348              :               e2 = cp_build_binary_op (location, EQ_EXPR,
    6349              :                                        pfn0,
    6350              :                                        build_zero_cst (TREE_TYPE (pfn0)),
    6351              :                                        complain);
    6352              :               e2 = cp_build_binary_op (location,
    6353              :                                        TRUTH_ANDIF_EXPR, e2, e1, complain);
    6354              :               e1 = cp_build_binary_op (location,
    6355              :                                        EQ_EXPR, delta0, delta1, complain);
    6356              :               e1 = cp_build_binary_op (location,
    6357              :                                        TRUTH_ORIF_EXPR, e1, e2, complain);
    6358              :             }
    6359              :           else
    6360              :             {
    6361              :               /* We generate:
    6362              : 
    6363              :                  (op0.pfn == op1.pfn
    6364              :                  && (!op0.pfn || op0.delta == op1.delta))
    6365              : 
    6366              :                  The reason for the `!op0.pfn' bit is that a NULL
    6367              :                  pointer-to-member is any member with a zero PFN; the
    6368              :                  DELTA field is unspecified.  */
    6369              : 
    6370          132 :               e1 = cp_build_binary_op (location,
    6371              :                                        EQ_EXPR, delta0, delta1, complain);
    6372          132 :               e2 = cp_build_binary_op (location,
    6373              :                                        EQ_EXPR,
    6374              :                                        pfn0,
    6375          132 :                                        build_zero_cst (TREE_TYPE (pfn0)),
    6376              :                                        complain);
    6377          132 :               e1 = cp_build_binary_op (location,
    6378              :                                        TRUTH_ORIF_EXPR, e1, e2, complain);
    6379              :             }
    6380          132 :           e2 = build2 (EQ_EXPR, boolean_type_node, pfn0, pfn1);
    6381          132 :           e = cp_build_binary_op (location,
    6382              :                                   TRUTH_ANDIF_EXPR, e2, e1, complain);
    6383          132 :           if (code == EQ_EXPR)
    6384              :             return e;
    6385           30 :           return cp_build_binary_op (location,
    6386           30 :                                      EQ_EXPR, e, integer_zero_node, complain);
    6387              :         }
    6388              :       /* [expr.eq]: "If both operands are of type std::meta::info,
    6389              :          comparison is defined as follows..."  */
    6390         4556 :       else if (code0 == META_TYPE && code1 == META_TYPE)
    6391              :         result_type = type0;
    6392              :       else
    6393              :         {
    6394           28 :           gcc_assert (!TYPE_PTRMEMFUNC_P (type0)
    6395              :                       || !same_type_p (TYPE_PTRMEMFUNC_FN_TYPE (type0),
    6396              :                                        type1));
    6397           28 :           gcc_assert (!TYPE_PTRMEMFUNC_P (type1)
    6398              :                       || !same_type_p (TYPE_PTRMEMFUNC_FN_TYPE (type1),
    6399              :                                        type0));
    6400              :         }
    6401              : 
    6402              :       break;
    6403              : 
    6404          241 :     case MAX_EXPR:
    6405          241 :     case MIN_EXPR:
    6406          241 :       if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
    6407          241 :            && (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
    6408              :         shorten = 1;
    6409            0 :       else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
    6410            0 :         result_type = composite_pointer_type (location,
    6411              :                                               type0, type1, op0, op1,
    6412              :                                               CPO_COMPARISON, complain);
    6413              :       break;
    6414              : 
    6415     25378391 :     case LE_EXPR:
    6416     25378391 :     case GE_EXPR:
    6417     25378391 :     case LT_EXPR:
    6418     25378391 :     case GT_EXPR:
    6419     25378391 :     case SPACESHIP_EXPR:
    6420     25378391 :       if (TREE_CODE (orig_op0) == STRING_CST
    6421     25378391 :           || TREE_CODE (orig_op1) == STRING_CST)
    6422              :         {
    6423            0 :           if (complain & tf_warning)
    6424            0 :             warning_at (location, OPT_Waddress,
    6425              :                         "comparison with string literal results "
    6426              :                         "in unspecified behavior");
    6427              :         }
    6428     25378391 :       else if (TREE_CODE (TREE_TYPE (orig_op0)) == ARRAY_TYPE
    6429          224 :                && TREE_CODE (TREE_TYPE (orig_op1)) == ARRAY_TYPE
    6430     25378506 :                && code != SPACESHIP_EXPR)
    6431              :         {
    6432           96 :           if (complain & tf_warning_or_error)
    6433           51 :             do_warn_array_compare (location, code,
    6434              :                                    tree_strip_any_location_wrapper (orig_op0),
    6435              :                                    tree_strip_any_location_wrapper (orig_op1));
    6436           45 :           else if (cxx_dialect >= cxx26)
    6437            1 :             return error_mark_node;
    6438              :         }
    6439              : 
    6440     25378390 :       if (gnu_vector_type_p (type0) && gnu_vector_type_p (type1))
    6441              :         {
    6442         7727 :         vector_compare:
    6443         7727 :           tree intt;
    6444         7727 :           if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (type0),
    6445         7727 :                                                           TREE_TYPE (type1))
    6446         7727 :               && !vector_types_compatible_elements_p (type0, type1))
    6447              :             {
    6448            3 :               if (complain & tf_error)
    6449              :                 {
    6450            3 :                   auto_diagnostic_group d;
    6451            3 :                   error_at (location, "comparing vectors with different "
    6452              :                                       "element types");
    6453            3 :                   inform (location, "operand types are %qT and %qT",
    6454              :                           type0, type1);
    6455            3 :                 }
    6456            3 :               return error_mark_node;
    6457              :             }
    6458              : 
    6459         7724 :           if (maybe_ne (TYPE_VECTOR_SUBPARTS (type0),
    6460        15448 :                         TYPE_VECTOR_SUBPARTS (type1)))
    6461              :             {
    6462            3 :               if (complain & tf_error)
    6463              :                 {
    6464            3 :                   auto_diagnostic_group d;
    6465            3 :                   error_at (location, "comparing vectors with different "
    6466              :                                       "number of elements");
    6467            3 :                   inform (location, "operand types are %qT and %qT",
    6468              :                           type0, type1);
    6469            3 :                 }
    6470            3 :               return error_mark_node;
    6471              :             }
    6472              : 
    6473              :           /* It's not precisely specified how the usual arithmetic
    6474              :              conversions apply to the vector types.  Here, we use
    6475              :              the unsigned type if one of the operands is signed and
    6476              :              the other one is unsigned.  */
    6477         7721 :           if (TYPE_UNSIGNED (type0) != TYPE_UNSIGNED (type1))
    6478              :             {
    6479           36 :               if (!TYPE_UNSIGNED (type0))
    6480           36 :                 op0 = build1 (VIEW_CONVERT_EXPR, type1, op0);
    6481              :               else
    6482            0 :                 op1 = build1 (VIEW_CONVERT_EXPR, type0, op1);
    6483           36 :               warning_at (location, OPT_Wsign_compare, "comparison between "
    6484              :                           "types %qT and %qT", type0, type1);
    6485              :             }
    6486              : 
    6487         7721 :           if (resultcode == SPACESHIP_EXPR)
    6488              :             {
    6489            3 :               if (complain & tf_error)
    6490            3 :                 sorry_at (location, "three-way comparison of vectors");
    6491            3 :               return error_mark_node;
    6492              :             }
    6493              : 
    6494         7718 :           if (VECTOR_BOOLEAN_TYPE_P (type0) && VECTOR_BOOLEAN_TYPE_P (type1))
    6495              :             result_type = type0;
    6496              :           else
    6497              :             {
    6498              :               /* Always construct signed integer vector type.  */
    6499         7718 :               auto intmode = SCALAR_TYPE_MODE (TREE_TYPE (type0));
    6500         7718 :               auto nelts = TYPE_VECTOR_SUBPARTS (type0);
    6501              : 
    6502        15436 :               intt = c_common_type_for_size (GET_MODE_BITSIZE (intmode), 0);
    6503         7718 :               if (!intt)
    6504              :                 {
    6505            0 :                   if (complain & tf_error)
    6506            0 :                     error_at (location, "could not find an integer type "
    6507            0 :                                 "of the same size as %qT", TREE_TYPE (type0));
    6508            0 :                   return error_mark_node;
    6509              :                 }
    6510         7718 :               result_type = build_opaque_vector_type (intt, nelts);
    6511              :             }
    6512         7718 :           return build_vec_cmp (resultcode, result_type, op0, op1);
    6513              :         }
    6514     25373655 :       build_type = boolean_type_node;
    6515     25373655 :       if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
    6516              :            || code0 == ENUMERAL_TYPE)
    6517     22815669 :            && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
    6518              :                || code1 == ENUMERAL_TYPE))
    6519              :         short_compare = 1;
    6520      2558089 :       else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
    6521      2557809 :         result_type = composite_pointer_type (location,
    6522              :                                               type0, type1, op0, op1,
    6523              :                                               CPO_COMPARISON, complain);
    6524           73 :       else if ((code0 == POINTER_TYPE && null_ptr_cst_p (orig_op1))
    6525          208 :                || (code1 == POINTER_TYPE && null_ptr_cst_p (orig_op0))
    6526          434 :                || (null_ptr_cst_p (orig_op0) && null_ptr_cst_p (orig_op1)))
    6527              :         {
    6528              :           /* Core Issue 1512 made this ill-formed.  */
    6529          190 :           if (complain & tf_error)
    6530          186 :             error_at (location, "ordered comparison of pointer with "
    6531              :                       "integer zero (%qT and %qT)", type0, type1);
    6532          190 :           return error_mark_node;
    6533              :         }
    6534           90 :       else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
    6535              :         {
    6536            0 :           result_type = type0;
    6537            0 :           if (complain & tf_error)
    6538            0 :             permerror (location, "ISO C++ forbids comparison between "
    6539              :                        "pointer and integer");
    6540              :           else
    6541            0 :             return error_mark_node;
    6542              :         }
    6543           90 :       else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
    6544              :         {
    6545           24 :           result_type = type1;
    6546           24 :           if (complain & tf_error)
    6547           24 :             permerror (location, "ISO C++ forbids comparison between "
    6548              :                        "pointer and integer");
    6549              :           else
    6550            0 :             return error_mark_node;
    6551              :         }
    6552              : 
    6553     25373465 :       if ((code0 == POINTER_TYPE || code1 == POINTER_TYPE)
    6554      2557834 :           && !processing_template_decl
    6555     27718651 :           && sanitize_flags_p (SANITIZE_POINTER_COMPARE))
    6556              :         {
    6557           49 :           op0 = cp_save_expr (op0);
    6558           49 :           op1 = cp_save_expr (op1);
    6559              : 
    6560           49 :           tree tt = builtin_decl_explicit (BUILT_IN_ASAN_POINTER_COMPARE);
    6561           49 :           instrument_expr = build_call_expr_loc (location, tt, 2, op0, op1);
    6562              :         }
    6563              : 
    6564              :       break;
    6565              : 
    6566            0 :     case UNORDERED_EXPR:
    6567            0 :     case ORDERED_EXPR:
    6568            0 :     case UNLT_EXPR:
    6569            0 :     case UNLE_EXPR:
    6570            0 :     case UNGT_EXPR:
    6571            0 :     case UNGE_EXPR:
    6572            0 :     case UNEQ_EXPR:
    6573            0 :       build_type = integer_type_node;
    6574            0 :       if (code0 != REAL_TYPE || code1 != REAL_TYPE)
    6575              :         {
    6576            0 :           if (complain & tf_error)
    6577            0 :             error ("unordered comparison on non-floating-point argument");
    6578            0 :           return error_mark_node;
    6579              :         }
    6580              :       common = 1;
    6581              :       break;
    6582              : 
    6583              :     default:
    6584              :       break;
    6585              :     }
    6586              : 
    6587    137575532 :   if (((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE
    6588              :         || code0 == ENUMERAL_TYPE)
    6589    112057940 :        && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
    6590              :            || code1 == COMPLEX_TYPE || code1 == ENUMERAL_TYPE)))
    6591              :     arithmetic_types_p = 1;
    6592              :   else
    6593              :     {
    6594     25898899 :       arithmetic_types_p = 0;
    6595              :       /* Vector arithmetic is only allowed when both sides are vectors.  */
    6596     25898899 :       if (gnu_vector_type_p (type0) && gnu_vector_type_p (type1))
    6597              :         {
    6598        60323 :           if (!tree_int_cst_equal (TYPE_SIZE (type0), TYPE_SIZE (type1))
    6599        60323 :               || !vector_types_compatible_elements_p (type0, type1))
    6600              :             {
    6601           18 :               if (complain & tf_error)
    6602              :                 {
    6603              :                   /* "location" already embeds the locations of the
    6604              :                      operands, so we don't need to add them separately
    6605              :                      to richloc.  */
    6606           18 :                   rich_location richloc (line_table, location);
    6607           18 :                   binary_op_error (&richloc, code, type0, type1);
    6608           18 :                 }
    6609           18 :               return error_mark_node;
    6610              :             }
    6611              :           arithmetic_types_p = 1;
    6612              :         }
    6613              :     }
    6614              :   /* Determine the RESULT_TYPE, if it is not already known.  */
    6615    137575514 :   if (!result_type
    6616    137575514 :       && arithmetic_types_p
    6617    107434620 :       && (shorten || common || short_compare))
    6618              :     {
    6619    107434519 :       result_type = cp_common_type (type0, type1);
    6620    107434519 :       if (result_type == error_mark_node)
    6621              :         {
    6622            6 :           tree t1 = type0;
    6623            6 :           tree t2 = type1;
    6624            6 :           if (TREE_CODE (t1) == COMPLEX_TYPE)
    6625            0 :             t1 = TREE_TYPE (t1);
    6626            6 :           if (TREE_CODE (t2) == COMPLEX_TYPE)
    6627            0 :             t2 = TREE_TYPE (t2);
    6628            6 :           gcc_checking_assert (TREE_CODE (t1) == REAL_TYPE
    6629              :                                && TREE_CODE (t2) == REAL_TYPE
    6630              :                                && (extended_float_type_p (t1)
    6631              :                                    || extended_float_type_p (t2))
    6632              :                                && cp_compare_floating_point_conversion_ranks
    6633              :                                     (t1, t2) == 3);
    6634            6 :           if (complain & tf_error)
    6635              :             {
    6636            6 :               rich_location richloc (line_table, location);
    6637            6 :               binary_op_error (&richloc, code, type0, type1);
    6638            6 :             }
    6639            6 :           return error_mark_node;
    6640              :         }
    6641    107434513 :       if (complain & tf_warning)
    6642     97783256 :         do_warn_double_promotion (result_type, type0, type1,
    6643              :                                   "implicit conversion from %qH to %qI "
    6644              :                                   "to match other operand of binary "
    6645              :                                   "expression", location);
    6646    107434513 :       if (do_warn_enum_conversions (location, code, TREE_TYPE (orig_op0),
    6647    107434513 :                                     TREE_TYPE (orig_op1), complain))
    6648           12 :         return error_mark_node;
    6649              :     }
    6650    137575496 :   if (may_need_excess_precision
    6651    101308764 :       && (orig_type0 != type0 || orig_type1 != type1)
    6652        43139 :       && build_type == NULL_TREE
    6653        43139 :       && result_type)
    6654              :     {
    6655        33003 :       gcc_assert (common);
    6656        33003 :       semantic_result_type = cp_common_type (orig_type0, orig_type1);
    6657        33003 :       if (semantic_result_type == error_mark_node)
    6658              :         {
    6659            0 :           tree t1 = orig_type0;
    6660            0 :           tree t2 = orig_type1;
    6661            0 :           if (TREE_CODE (t1) == COMPLEX_TYPE)
    6662            0 :             t1 = TREE_TYPE (t1);
    6663            0 :           if (TREE_CODE (t2) == COMPLEX_TYPE)
    6664            0 :             t2 = TREE_TYPE (t2);
    6665            0 :           gcc_checking_assert (TREE_CODE (t1) == REAL_TYPE
    6666              :                                && TREE_CODE (t2) == REAL_TYPE
    6667              :                                && (extended_float_type_p (t1)
    6668              :                                    || extended_float_type_p (t2))
    6669              :                                && cp_compare_floating_point_conversion_ranks
    6670              :                                     (t1, t2) == 3);
    6671            0 :           if (complain & tf_error)
    6672              :             {
    6673            0 :               rich_location richloc (line_table, location);
    6674            0 :               binary_op_error (&richloc, code, type0, type1);
    6675            0 :             }
    6676            0 :           return error_mark_node;
    6677              :         }
    6678              :     }
    6679              : 
    6680    137575496 :   if (code == SPACESHIP_EXPR)
    6681              :     {
    6682       586293 :       iloc_sentinel s (location);
    6683              : 
    6684       586293 :       tree orig_type0 = TREE_TYPE (orig_op0);
    6685       586293 :       tree_code orig_code0 = TREE_CODE (orig_type0);
    6686       586293 :       tree orig_type1 = TREE_TYPE (orig_op1);
    6687       586293 :       tree_code orig_code1 = TREE_CODE (orig_type1);
    6688       586293 :       if (!result_type || result_type == error_mark_node)
    6689              :         /* Nope.  */
    6690              :         result_type = NULL_TREE;
    6691       586272 :       else if ((orig_code0 == BOOLEAN_TYPE) != (orig_code1 == BOOLEAN_TYPE))
    6692              :         /* "If one of the operands is of type bool and the other is not, the
    6693              :            program is ill-formed."  */
    6694              :         result_type = NULL_TREE;
    6695       586269 :       else if (code0 == POINTER_TYPE && orig_code0 != POINTER_TYPE
    6696           19 :                && code1 == POINTER_TYPE && orig_code1 != POINTER_TYPE)
    6697              :         /* We only do array/function-to-pointer conversion if "at least one of
    6698              :            the operands is of pointer type".  */
    6699              :         result_type = NULL_TREE;
    6700       586250 :       else if (TYPE_PTRFN_P (result_type) || NULLPTR_TYPE_P (result_type))
    6701              :         /* <=> no longer supports equality relations.  */
    6702              :         result_type = NULL_TREE;
    6703       586247 :       else if (orig_code0 == ENUMERAL_TYPE && orig_code1 == ENUMERAL_TYPE
    6704       586277 :                && !(same_type_ignoring_top_level_qualifiers_p
    6705           30 :                     (orig_type0, orig_type1)))
    6706              :         /* "If both operands have arithmetic types, or one operand has integral
    6707              :            type and the other operand has unscoped enumeration type, the usual
    6708              :            arithmetic conversions are applied to the operands."  So we don't do
    6709              :            arithmetic conversions if the operands both have enumeral type.  */
    6710              :         result_type = NULL_TREE;
    6711       586232 :       else if ((orig_code0 == ENUMERAL_TYPE && orig_code1 == REAL_TYPE)
    6712       586226 :                || (orig_code0 == REAL_TYPE && orig_code1 == ENUMERAL_TYPE))
    6713              :         /* [depr.arith.conv.enum]: Three-way comparisons between such operands
    6714              :            [where one is of enumeration type and the other is of a different
    6715              :            enumeration type or a floating-point type] are ill-formed.  */
    6716              :         result_type = NULL_TREE;
    6717              : 
    6718       586220 :       if (result_type)
    6719              :         {
    6720       586220 :           build_type = spaceship_type (result_type, complain);
    6721       586220 :           if (build_type == error_mark_node)
    6722              :             return error_mark_node;
    6723              :         }
    6724              : 
    6725       586278 :       if (result_type && arithmetic_types_p)
    6726              :         {
    6727              :           /* If a narrowing conversion is required, other than from an integral
    6728              :              type to a floating point type, the program is ill-formed.  */
    6729       276425 :           bool ok = true;
    6730       276425 :           if (TREE_CODE (result_type) == REAL_TYPE
    6731          555 :               && CP_INTEGRAL_TYPE_P (orig_type0))
    6732              :             /* OK */;
    6733       276418 :           else if (!check_narrowing (result_type, orig_op0, complain))
    6734       276425 :             ok = false;
    6735       276425 :           if (TREE_CODE (result_type) == REAL_TYPE
    6736          555 :               && CP_INTEGRAL_TYPE_P (orig_type1))
    6737              :             /* OK */;
    6738       276418 :           else if (!check_narrowing (result_type, orig_op1, complain))
    6739              :             ok = false;
    6740       276425 :           if (!ok && !(complain & tf_error))
    6741            2 :             return error_mark_node;
    6742              :         }
    6743       586293 :     }
    6744              : 
    6745    137575479 :   if (!result_type)
    6746              :     {
    6747          560 :       if (complain & tf_error)
    6748              :         {
    6749          219 :           binary_op_rich_location richloc (location,
    6750          219 :                                            orig_op0, orig_op1, true);
    6751          219 :           error_at (&richloc,
    6752              :                     "invalid operands of types %qT and %qT to binary %qO",
    6753          219 :                     TREE_TYPE (orig_op0), TREE_TYPE (orig_op1), code);
    6754          219 :         }
    6755          560 :       return error_mark_node;
    6756              :     }
    6757              : 
    6758              :   /* If we're in a template, the only thing we need to know is the
    6759              :      RESULT_TYPE.  */
    6760    137574919 :   if (processing_template_decl)
    6761              :     {
    6762              :       /* Since the middle-end checks the type when doing a build2, we
    6763              :          need to build the tree in pieces.  This built tree will never
    6764              :          get out of the front-end as we replace it when instantiating
    6765              :          the template.  */
    6766     63795773 :       tree tmp = build2 (resultcode,
    6767              :                          build_type ? build_type : result_type,
    6768              :                          NULL_TREE, op1);
    6769     39876412 :       TREE_OPERAND (tmp, 0) = op0;
    6770     39876412 :       if (semantic_result_type)
    6771            0 :         tmp = build1 (EXCESS_PRECISION_EXPR, semantic_result_type, tmp);
    6772     39876412 :       return tmp;
    6773              :     }
    6774              : 
    6775              :   /* Remember the original type; RESULT_TYPE might be changed later on
    6776              :      by shorten_binary_op.  */
    6777     97698507 :   tree orig_type = result_type;
    6778              : 
    6779     97698507 :   if (arithmetic_types_p)
    6780              :     {
    6781     83879181 :       bool first_complex = (code0 == COMPLEX_TYPE);
    6782     83879181 :       bool second_complex = (code1 == COMPLEX_TYPE);
    6783     83879181 :       int none_complex = (!first_complex && !second_complex);
    6784              : 
    6785              :       /* Adapted from patch for c/24581.  */
    6786     83879181 :       if (first_complex != second_complex
    6787       157057 :           && (code == PLUS_EXPR
    6788              :               || code == MINUS_EXPR
    6789       157057 :               || code == MULT_EXPR
    6790        41084 :               || (code == TRUNC_DIV_EXPR && first_complex))
    6791       143550 :           && TREE_CODE (TREE_TYPE (result_type)) == REAL_TYPE
    6792     84022570 :           && flag_signed_zeros)
    6793              :         {
    6794              :           /* An operation on mixed real/complex operands must be
    6795              :              handled specially, but the language-independent code can
    6796              :              more easily optimize the plain complex arithmetic if
    6797              :              -fno-signed-zeros.  */
    6798       143389 :           tree real_type = TREE_TYPE (result_type);
    6799       143389 :           tree real, imag;
    6800       143389 :           if (first_complex)
    6801              :             {
    6802       110341 :               if (TREE_TYPE (op0) != result_type)
    6803            6 :                 op0 = cp_convert_and_check (result_type, op0, complain);
    6804       110341 :               if (TREE_TYPE (op1) != real_type)
    6805           26 :                 op1 = cp_convert_and_check (real_type, op1, complain);
    6806              :             }
    6807              :           else
    6808              :             {
    6809        33048 :               if (TREE_TYPE (op0) != real_type)
    6810           31 :                 op0 = cp_convert_and_check (real_type, op0, complain);
    6811        33048 :               if (TREE_TYPE (op1) != result_type)
    6812           32 :                 op1 = cp_convert_and_check (result_type, op1, complain);
    6813              :             }
    6814       143389 :           if (TREE_CODE (op0) == ERROR_MARK || TREE_CODE (op1) == ERROR_MARK)
    6815            0 :             return error_mark_node;
    6816       143389 :           if (first_complex)
    6817              :             {
    6818       110341 :               op0 = cp_save_expr (op0);
    6819       110341 :               real = cp_build_unary_op (REALPART_EXPR, op0, true, complain);
    6820       110341 :               imag = cp_build_unary_op (IMAGPART_EXPR, op0, true, complain);
    6821       110341 :               switch (code)
    6822              :                 {
    6823        55147 :                 case MULT_EXPR:
    6824        55147 :                 case TRUNC_DIV_EXPR:
    6825        55147 :                   op1 = cp_save_expr (op1);
    6826        55147 :                   imag = build2 (resultcode, real_type, imag, op1);
    6827              :                   /* Fall through.  */
    6828       110341 :                 case PLUS_EXPR:
    6829       110341 :                 case MINUS_EXPR:
    6830       110341 :                   real = build2 (resultcode, real_type, real, op1);
    6831       110341 :                   break;
    6832            0 :                 default:
    6833            0 :                   gcc_unreachable();
    6834              :                 }
    6835              :             }
    6836              :           else
    6837              :             {
    6838        33048 :               op1 = cp_save_expr (op1);
    6839        33048 :               real = cp_build_unary_op (REALPART_EXPR, op1, true, complain);
    6840        33048 :               imag = cp_build_unary_op (IMAGPART_EXPR, op1, true, complain);
    6841        33048 :               switch (code)
    6842              :                 {
    6843          638 :                 case MULT_EXPR:
    6844          638 :                   op0 = cp_save_expr (op0);
    6845          638 :                   imag = build2 (resultcode, real_type, op0, imag);
    6846              :                   /* Fall through.  */
    6847        17301 :                 case PLUS_EXPR:
    6848        17301 :                   real = build2 (resultcode, real_type, op0, real);
    6849        17301 :                   break;
    6850        15747 :                 case MINUS_EXPR:
    6851        15747 :                   real = build2 (resultcode, real_type, op0, real);
    6852        15747 :                   imag = build1 (NEGATE_EXPR, real_type, imag);
    6853        15747 :                   break;
    6854            0 :                 default:
    6855            0 :                   gcc_unreachable();
    6856              :                 }
    6857              :             }
    6858       143389 :           result = build2 (COMPLEX_EXPR, result_type, real, imag);
    6859       143389 :           if (semantic_result_type)
    6860           24 :             result = build1 (EXCESS_PRECISION_EXPR, semantic_result_type,
    6861              :                              result);
    6862       143389 :           return result;
    6863              :         }
    6864              : 
    6865              :       /* For certain operations (which identify themselves by shorten != 0)
    6866              :          if both args were extended from the same smaller type,
    6867              :          do the arithmetic in that type and then extend.
    6868              : 
    6869              :          shorten !=0 and !=1 indicates a bitwise operation.
    6870              :          For them, this optimization is safe only if
    6871              :          both args are zero-extended or both are sign-extended.
    6872              :          Otherwise, we might change the result.
    6873              :          E.g., (short)-1 | (unsigned short)-1 is (int)-1
    6874              :          but calculated in (unsigned short) it would be (unsigned short)-1.  */
    6875              : 
    6876     83735792 :       if (shorten && none_complex)
    6877              :         {
    6878      6680108 :           final_type = result_type;
    6879      6680108 :           result_type = shorten_binary_op (result_type, op0, op1,
    6880              :                                            shorten == -1);
    6881              :         }
    6882              : 
    6883              :       /* Shifts can be shortened if shifting right.  */
    6884              : 
    6885     83735792 :       if (short_shift)
    6886              :         {
    6887       820041 :           int unsigned_arg;
    6888       820041 :           tree arg0 = get_narrower (op0, &unsigned_arg);
    6889              :           /* We're not really warning here but when we set short_shift we
    6890              :              used fold_for_warn to fold the operand.  */
    6891       820041 :           tree const_op1 = fold_for_warn (op1);
    6892              : 
    6893       820041 :           final_type = result_type;
    6894              : 
    6895       820041 :           if (arg0 == op0 && final_type == TREE_TYPE (op0))
    6896       744979 :             unsigned_arg = TYPE_UNSIGNED (TREE_TYPE (op0));
    6897              : 
    6898       820041 :           if (TYPE_PRECISION (TREE_TYPE (arg0)) < TYPE_PRECISION (result_type)
    6899         2014 :               && tree_int_cst_sgn (const_op1) > 0
    6900              :               /* We can shorten only if the shift count is less than the
    6901              :                  number of bits in the smaller type size.  */
    6902         2014 :               && compare_tree_int (const_op1,
    6903         2014 :                                    TYPE_PRECISION (TREE_TYPE (arg0))) < 0
    6904              :               /* We cannot drop an unsigned shift after sign-extension.  */
    6905       822030 :               && (!TYPE_UNSIGNED (final_type) || unsigned_arg))
    6906              :             {
    6907              :               /* Do an unsigned shift if the operand was zero-extended.  */
    6908         1982 :               result_type
    6909         1982 :                 = c_common_signed_or_unsigned_type (unsigned_arg,
    6910         1982 :                                                     TREE_TYPE (arg0));
    6911              :               /* Convert value-to-be-shifted to that type.  */
    6912         1982 :               if (TREE_TYPE (op0) != result_type)
    6913         1982 :                 op0 = convert (result_type, op0);
    6914              :               converted = 1;
    6915              :             }
    6916              :         }
    6917              : 
    6918              :       /* Comparison operations are shortened too but differently.
    6919              :          They identify themselves by setting short_compare = 1.  */
    6920              : 
    6921     83735792 :       if (short_compare)
    6922              :         {
    6923              :           /* We call shorten_compare only for diagnostics.  */
    6924     28735749 :           tree xop0 = fold_simple (op0);
    6925     28735749 :           tree xop1 = fold_simple (op1);
    6926     28735749 :           tree xresult_type = result_type;
    6927     28735749 :           enum tree_code xresultcode = resultcode;
    6928     28735749 :           shorten_compare (location, &xop0, &xop1, &xresult_type,
    6929              :                            &xresultcode);
    6930              :         }
    6931              : 
    6932     54999956 :       if ((short_compare || code == MIN_EXPR || code == MAX_EXPR)
    6933     28735938 :           && warn_sign_compare
    6934              :           /* Do not warn until the template is instantiated; we cannot
    6935              :              bound the ranges of the arguments until that point.  */
    6936       343086 :           && !processing_template_decl
    6937       343086 :           && (complain & tf_warning)
    6938       335083 :           && c_inhibit_evaluation_warnings == 0
    6939              :           /* Even unsigned enum types promote to signed int.  We don't
    6940              :              want to issue -Wsign-compare warnings for this case.  */
    6941       318648 :           && !enum_cast_to_int (orig_op0)
    6942     84054440 :           && !enum_cast_to_int (orig_op1))
    6943              :         {
    6944       318641 :           warn_for_sign_compare (location, orig_op0, orig_op1, op0, op1,
    6945              :                                  result_type, resultcode);
    6946              :         }
    6947              :     }
    6948              : 
    6949              :   /* If CONVERTED is zero, both args will be converted to type RESULT_TYPE.
    6950              :      Then the expression will be built.
    6951              :      It will be given type FINAL_TYPE if that is nonzero;
    6952              :      otherwise, it will be given type RESULT_TYPE.  */
    6953     97555118 :   if (! converted)
    6954              :     {
    6955     93946698 :       warning_sentinel w (warn_sign_conversion, short_compare);
    6956     93946698 :       if (!same_type_p (TREE_TYPE (op0), result_type))
    6957      4102109 :         op0 = cp_convert_and_check (result_type, op0, complain);
    6958     93946698 :       if (!same_type_p (TREE_TYPE (op1), result_type))
    6959     18196221 :         op1 = cp_convert_and_check (result_type, op1, complain);
    6960              : 
    6961     93946698 :       if (op0 == error_mark_node || op1 == error_mark_node)
    6962           58 :         return error_mark_node;
    6963     93946698 :     }
    6964              : 
    6965     97555060 :   if (build_type == NULL_TREE)
    6966     62645834 :     build_type = result_type;
    6967              : 
    6968     97555060 :   if (doing_shift
    6969      3607771 :       && flag_strong_eval_order == 2
    6970      3517540 :       && TREE_SIDE_EFFECTS (op1)
    6971     97575915 :       && !processing_template_decl)
    6972              :     {
    6973              :       /* In C++17, in both op0 << op1 and op0 >> op1 op0 is sequenced before
    6974              :          op1, so if op1 has side-effects, use SAVE_EXPR around op0.  */
    6975        20855 :       op0 = cp_save_expr (op0);
    6976        20855 :       instrument_expr = op0;
    6977              :     }
    6978              : 
    6979     97555060 :   if (sanitize_flags_p ((SANITIZE_SHIFT
    6980              :                          | SANITIZE_DIVIDE
    6981              :                          | SANITIZE_FLOAT_DIVIDE
    6982              :                          | SANITIZE_SI_OVERFLOW))
    6983        13440 :       && current_function_decl != NULL_TREE
    6984        11046 :       && !processing_template_decl
    6985     97566106 :       && (doing_div_or_mod || doing_shift))
    6986              :     {
    6987              :       /* OP0 and/or OP1 might have side-effects.  */
    6988          939 :       op0 = cp_save_expr (op0);
    6989          939 :       op1 = cp_save_expr (op1);
    6990          939 :       op0 = fold_non_dependent_expr (op0, complain);
    6991          939 :       op1 = fold_non_dependent_expr (op1, complain);
    6992          939 :       tree instrument_expr1 = NULL_TREE;
    6993          939 :       if (doing_div_or_mod
    6994          939 :           && sanitize_flags_p (SANITIZE_DIVIDE
    6995              :                                | SANITIZE_FLOAT_DIVIDE
    6996              :                                | SANITIZE_SI_OVERFLOW))
    6997              :         {
    6998              :           /* For diagnostics we want to use the promoted types without
    6999              :              shorten_binary_op.  So convert the arguments to the
    7000              :              original result_type.  */
    7001          475 :           tree cop0 = op0;
    7002          475 :           tree cop1 = op1;
    7003          475 :           if (TREE_TYPE (cop0) != orig_type)
    7004            6 :             cop0 = cp_convert (orig_type, op0, complain);
    7005          475 :           if (TREE_TYPE (cop1) != orig_type)
    7006           39 :             cop1 = cp_convert (orig_type, op1, complain);
    7007          475 :           instrument_expr1 = ubsan_instrument_division (location, cop0, cop1);
    7008              :         }
    7009          464 :       else if (doing_shift && sanitize_flags_p (SANITIZE_SHIFT))
    7010          383 :         instrument_expr1 = ubsan_instrument_shift (location, code, op0, op1);
    7011          939 :       if (instrument_expr != NULL)
    7012           18 :         instrument_expr = add_stmt_to_compound (instrument_expr,
    7013              :                                                 instrument_expr1);
    7014              :       else
    7015          921 :         instrument_expr = instrument_expr1;
    7016              :     }
    7017              : 
    7018     97555060 :   result = build2_loc (location, resultcode, build_type, op0, op1);
    7019     97555060 :   if (final_type != 0)
    7020      7500149 :     result = cp_convert (final_type, result, complain);
    7021              : 
    7022     97555060 :   if (instrument_expr != NULL)
    7023        21353 :     result = build2 (COMPOUND_EXPR, TREE_TYPE (result),
    7024              :                      instrument_expr, result);
    7025              : 
    7026     97555060 :   if (resultcode == SPACESHIP_EXPR && !processing_template_decl)
    7027       491958 :     result = get_target_expr (result, complain);
    7028              : 
    7029     97555060 :   if (semantic_result_type)
    7030        32979 :     result = build1 (EXCESS_PRECISION_EXPR, semantic_result_type, result);
    7031              : 
    7032     97555060 :   if (!c_inhibit_evaluation_warnings)
    7033              :     {
    7034     82792459 :       if (!processing_template_decl)
    7035              :         {
    7036     82792459 :           op0 = cp_fully_fold (op0);
    7037              :           /* Only consider the second argument if the first isn't overflowed.  */
    7038     82792459 :           if (!CONSTANT_CLASS_P (op0) || TREE_OVERFLOW_P (op0))
    7039              :             return result;
    7040     23200731 :           op1 = cp_fully_fold (op1);
    7041     23200731 :           if (!CONSTANT_CLASS_P (op1) || TREE_OVERFLOW_P (op1))
    7042              :             return result;
    7043              :         }
    7044            0 :       else if (!CONSTANT_CLASS_P (op0) || !CONSTANT_CLASS_P (op1)
    7045            0 :                || TREE_OVERFLOW_P (op0) || TREE_OVERFLOW_P (op1))
    7046              :         return result;
    7047              : 
    7048     17883995 :       tree result_ovl = fold_build2 (resultcode, build_type, op0, op1);
    7049     17883995 :       if (TREE_OVERFLOW_P (result_ovl))
    7050          190 :         overflow_warning (location, result_ovl);
    7051              :     }
    7052              : 
    7053              :   return result;
    7054              : }
    7055              : 
    7056              : /* Build a VEC_PERM_EXPR.
    7057              :    This is a simple wrapper for c_build_vec_perm_expr.  */
    7058              : tree
    7059        17586 : build_x_vec_perm_expr (location_t loc,
    7060              :                         tree arg0, tree arg1, tree arg2,
    7061              :                         tsubst_flags_t complain)
    7062              : {
    7063        17586 :   tree orig_arg0 = arg0;
    7064        17586 :   tree orig_arg1 = arg1;
    7065        17586 :   tree orig_arg2 = arg2;
    7066        17586 :   if (processing_template_decl)
    7067              :     {
    7068           19 :       if (type_dependent_expression_p (arg0)
    7069           13 :           || type_dependent_expression_p (arg1)
    7070           32 :           || type_dependent_expression_p (arg2))
    7071            6 :         return build_min_nt_loc (loc, VEC_PERM_EXPR, arg0, arg1, arg2);
    7072              :     }
    7073        17580 :   tree exp = c_build_vec_perm_expr (loc, arg0, arg1, arg2, complain & tf_error);
    7074        17580 :   if (processing_template_decl && exp != error_mark_node)
    7075           13 :     return build_min_non_dep (VEC_PERM_EXPR, exp, orig_arg0,
    7076           13 :                               orig_arg1, orig_arg2);
    7077              :   return exp;
    7078              : }
    7079              : 
    7080              : /* Build a VEC_PERM_EXPR.
    7081              :    This is a simple wrapper for c_build_shufflevector.  */
    7082              : tree
    7083        41953 : build_x_shufflevector (location_t loc, vec<tree, va_gc> *args,
    7084              :                        tsubst_flags_t complain)
    7085              : {
    7086        41953 :   tree arg0 = (*args)[0];
    7087        41953 :   tree arg1 = (*args)[1];
    7088        41953 :   if (processing_template_decl)
    7089              :     {
    7090          355 :       for (unsigned i = 0; i < args->length (); ++i)
    7091          339 :         if (i <= 1
    7092          339 :             ? type_dependent_expression_p ((*args)[i])
    7093           61 :             : instantiation_dependent_expression_p ((*args)[i]))
    7094              :           {
    7095          243 :             tree exp = build_min_nt_call_vec (NULL, args);
    7096          243 :             CALL_EXPR_IFN (exp) = IFN_SHUFFLEVECTOR;
    7097          243 :             return exp;
    7098              :           }
    7099              :     }
    7100        41710 :   auto_vec<tree, 16> mask;
    7101       564442 :   for (unsigned i = 2; i < args->length (); ++i)
    7102              :     {
    7103       522732 :       tree idx = fold_non_dependent_expr ((*args)[i], complain);
    7104       522732 :       mask.safe_push (idx);
    7105              :     }
    7106        41710 :   tree exp = c_build_shufflevector (loc, arg0, arg1, mask, complain & tf_error);
    7107        41710 :   if (processing_template_decl && exp != error_mark_node)
    7108              :     {
    7109           16 :       exp = build_min_non_dep_call_vec (exp, NULL, args);
    7110           16 :       CALL_EXPR_IFN (exp) = IFN_SHUFFLEVECTOR;
    7111              :     }
    7112        41710 :   return exp;
    7113        41710 : }
    7114              : 
    7115              : /* Build __builtin_bswapg (ARG) or __builtin_bitreverseg (ARG).  */
    7116              : tree
    7117          162 : build_x_bswapg_bitreverseg (location_t loc, internal_fn ifn,
    7118              :                             vec<tree, va_gc> *args, tsubst_flags_t complain)
    7119              : {
    7120           81 :   const char *name
    7121          162 :     = ifn == IFN_BSWAP ? "__builtin_bswapg" : "__builtin_bitreverseg";
    7122          162 :   if (args->length () != 1)
    7123              :     {
    7124           18 :       if (complain & tf_error)
    7125           18 :         error_at (loc, "wrong number of arguments to %qs", name);
    7126           18 :       return error_mark_node;
    7127              :     }
    7128          144 :   tree arg = (*args)[0];
    7129          144 :   if (error_operand_p (arg))
    7130            6 :     return error_mark_node;
    7131          138 :   if (type_dependent_expression_p (arg))
    7132              :     {
    7133            0 :       tree exp = build_min_nt_call_vec (NULL, args);
    7134            0 :       CALL_EXPR_IFN (exp) = ifn;
    7135            0 :       return exp;
    7136              :     }
    7137          138 :   tree type = TYPE_MAIN_VARIANT (TREE_TYPE (arg));
    7138          138 :   if (!INTEGRAL_TYPE_P (type))
    7139              :     {
    7140           24 :       if (complain & tf_error)
    7141           24 :         error_at (loc, "%qs operand not an integral type", name);
    7142           24 :       return error_mark_node;
    7143              :     }
    7144          114 :   if (TREE_CODE (type) == ENUMERAL_TYPE)
    7145              :     {
    7146           30 :       if (complain & tf_error)
    7147           30 :         error_at (loc, "argument %u in call to function "
    7148              :                        "%qs has enumerated type", 1, name);
    7149           30 :       return error_mark_node;
    7150              :     }
    7151           84 :   if (TREE_CODE (type) == BOOLEAN_TYPE)
    7152              :     {
    7153            6 :       if (complain & tf_error)
    7154            6 :         error_at (loc, "argument %u in call to function "
    7155              :                        "%qs has boolean type", 1, name);
    7156            6 :       return error_mark_node;
    7157              :     }
    7158           78 :   if (!TYPE_UNSIGNED (type))
    7159              :     {
    7160           12 :       if (complain & tf_error)
    7161           12 :         error_at (loc, "argument 1 in call to function "
    7162              :                        "%qs has signed type", name);
    7163           12 :       return error_mark_node;
    7164              :     }
    7165           66 :   if (ifn == IFN_BSWAP && (TYPE_PRECISION (type) % 8) != 0)
    7166              :     {
    7167            0 :       if (complain & tf_error)
    7168            0 :         error_at (loc, "precision %d of argument 1 to function "
    7169              :                        "%qs is not a multiple of 8",
    7170            0 :                   TYPE_PRECISION (type), name);
    7171            0 :       return error_mark_node;
    7172              :     }
    7173           66 :   tree exp = build_call_expr_internal_loc (loc, ifn, type, 1, arg);
    7174           66 :   if (processing_template_decl)
    7175              :     {
    7176            0 :       exp = build_min_non_dep_call_vec (exp, NULL, args);
    7177            0 :       CALL_EXPR_IFN (exp) = ifn;
    7178              :     }
    7179              :   return exp;
    7180              : }
    7181              : 
    7182              : /* Return a tree for the sum or difference (RESULTCODE says which)
    7183              :    of pointer PTROP and integer INTOP.  */
    7184              : 
    7185              : static tree
    7186      5448250 : cp_pointer_int_sum (location_t loc, enum tree_code resultcode, tree ptrop,
    7187              :                     tree intop, tsubst_flags_t complain)
    7188              : {
    7189      5448250 :   tree res_type = TREE_TYPE (ptrop);
    7190              : 
    7191              :   /* pointer_int_sum() uses size_in_bytes() on the TREE_TYPE(res_type)
    7192              :      in certain circumstance (when it's valid to do so).  So we need
    7193              :      to make sure it's complete.  We don't need to check here, if we
    7194              :      can actually complete it at all, as those checks will be done in
    7195              :      pointer_int_sum() anyway.  */
    7196      5448250 :   complete_type (TREE_TYPE (res_type));
    7197              : 
    7198      5448250 :   return pointer_int_sum (loc, resultcode, ptrop,
    7199      5448250 :                           intop, complain & tf_warning_or_error);
    7200              : }
    7201              : 
    7202              : /* Return a tree for the difference of pointers OP0 and OP1.
    7203              :    The resulting tree has type int.  If POINTER_SUBTRACT sanitization is
    7204              :    enabled, assign to INSTRUMENT_EXPR call to libsanitizer.  */
    7205              : 
    7206              : static tree
    7207      1461280 : pointer_diff (location_t loc, tree op0, tree op1, tree ptrtype,
    7208              :               tsubst_flags_t complain, tree *instrument_expr)
    7209              : {
    7210      1461280 :   tree result, inttype;
    7211      1461280 :   tree restype = ptrdiff_type_node;
    7212      1461280 :   tree target_type = TREE_TYPE (ptrtype);
    7213              : 
    7214      1461280 :   if (!complete_type_or_maybe_complain (target_type, NULL_TREE, complain))
    7215            9 :     return error_mark_node;
    7216              : 
    7217      1461271 :   if (VOID_TYPE_P (target_type))
    7218              :     {
    7219            0 :       if (complain & tf_error)
    7220            0 :         permerror (loc, "ISO C++ forbids using pointer of "
    7221              :                    "type %<void *%> in subtraction");
    7222              :       else
    7223            0 :         return error_mark_node;
    7224              :     }
    7225      1461271 :   if (TREE_CODE (target_type) == FUNCTION_TYPE)
    7226              :     {
    7227            9 :       if (complain & tf_error)
    7228            3 :         permerror (loc, "ISO C++ forbids using pointer to "
    7229              :                    "a function in subtraction");
    7230              :       else
    7231            6 :         return error_mark_node;
    7232              :     }
    7233      1461265 :   if (TREE_CODE (target_type) == METHOD_TYPE)
    7234              :     {
    7235            0 :       if (complain & tf_error)
    7236            0 :         permerror (loc, "ISO C++ forbids using pointer to "
    7237              :                    "a method in subtraction");
    7238              :       else
    7239            0 :         return error_mark_node;
    7240              :     }
    7241      2922530 :   else if (!verify_type_context (loc, TCTX_POINTER_ARITH,
    7242      1461265 :                                  TREE_TYPE (TREE_TYPE (op0)),
    7243              :                                  !(complain & tf_error))
    7244      2922530 :            || !verify_type_context (loc, TCTX_POINTER_ARITH,
    7245      1461265 :                                     TREE_TYPE (TREE_TYPE (op1)),
    7246              :                                     !(complain & tf_error)))
    7247            0 :     return error_mark_node;
    7248              : 
    7249              :   /* Determine integer type result of the subtraction.  This will usually
    7250              :      be the same as the result type (ptrdiff_t), but may need to be a wider
    7251              :      type if pointers for the address space are wider than ptrdiff_t.  */
    7252      1461265 :   if (TYPE_PRECISION (restype) < TYPE_PRECISION (TREE_TYPE (op0)))
    7253            0 :     inttype = c_common_type_for_size (TYPE_PRECISION (TREE_TYPE (op0)), 0);
    7254              :   else
    7255              :     inttype = restype;
    7256              : 
    7257      1461265 :   if (!processing_template_decl
    7258      1461265 :       && sanitize_flags_p (SANITIZE_POINTER_SUBTRACT))
    7259              :     {
    7260           84 :       op0 = save_expr (op0);
    7261           84 :       op1 = save_expr (op1);
    7262              : 
    7263           84 :       tree tt = builtin_decl_explicit (BUILT_IN_ASAN_POINTER_SUBTRACT);
    7264           84 :       *instrument_expr = build_call_expr_loc (loc, tt, 2, op0, op1);
    7265              :     }
    7266              : 
    7267              :   /* First do the subtraction, then build the divide operator
    7268              :      and only convert at the very end.
    7269              :      Do not do default conversions in case restype is a short type.  */
    7270              : 
    7271              :   /* POINTER_DIFF_EXPR requires a signed integer type of the same size as
    7272              :      pointers.  If some platform cannot provide that, or has a larger
    7273              :      ptrdiff_type to support differences larger than half the address
    7274              :      space, cast the pointers to some larger integer type and do the
    7275              :      computations in that type.  */
    7276      1461265 :   if (TYPE_PRECISION (inttype) > TYPE_PRECISION (TREE_TYPE (op0)))
    7277            0 :     op0 = cp_build_binary_op (loc,
    7278              :                               MINUS_EXPR,
    7279              :                               cp_convert (inttype, op0, complain),
    7280              :                               cp_convert (inttype, op1, complain),
    7281              :                               complain);
    7282              :   else
    7283      1461265 :     op0 = build2_loc (loc, POINTER_DIFF_EXPR, inttype, op0, op1);
    7284              : 
    7285              :   /* This generates an error if op1 is a pointer to an incomplete type.  */
    7286      1461265 :   if (!COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (op1))))
    7287              :     {
    7288            0 :       if (complain & tf_error)
    7289            0 :         error_at (loc, "invalid use of a pointer to an incomplete type in "
    7290              :                   "pointer arithmetic");
    7291              :       else
    7292            0 :         return error_mark_node;
    7293              :     }
    7294              : 
    7295      1461265 :   if (pointer_to_zero_sized_aggr_p (TREE_TYPE (op1)))
    7296              :     {
    7297           15 :       if (complain & tf_error)
    7298           15 :         error_at (loc, "arithmetic on pointer to an empty aggregate");
    7299              :       else
    7300            0 :         return error_mark_node;
    7301              :     }
    7302              : 
    7303      2922527 :   op1 = (TYPE_PTROB_P (ptrtype)
    7304      2922527 :          ? size_in_bytes_loc (loc, target_type)
    7305              :          : integer_one_node);
    7306              : 
    7307              :   /* Do the division.  */
    7308              : 
    7309      1461265 :   result = build2_loc (loc, EXACT_DIV_EXPR, inttype, op0,
    7310              :                        cp_convert (inttype, op1, complain));
    7311      1461265 :   return cp_convert (restype, result, complain);
    7312              : }
    7313              : 
    7314              : /* Construct and perhaps optimize a tree representation
    7315              :    for a unary operation.  CODE, a tree_code, specifies the operation
    7316              :    and XARG is the operand.  */
    7317              : 
    7318              : tree
    7319     62674523 : build_x_unary_op (location_t loc, enum tree_code code, cp_expr xarg,
    7320              :                   tree lookups, tsubst_flags_t complain)
    7321              : {
    7322     62674523 :   tree orig_expr = xarg;
    7323     62674523 :   tree exp;
    7324     62674523 :   int ptrmem = 0;
    7325     62674523 :   tree overload = NULL_TREE;
    7326              : 
    7327     62674523 :   if (processing_template_decl)
    7328              :     {
    7329     42770802 :       if (type_dependent_expression_p (xarg))
    7330              :         {
    7331     27950653 :           tree e = build_min_nt_loc (loc, code, xarg.get_value (), NULL_TREE);
    7332     27950653 :           TREE_TYPE (e) = build_dependent_operator_type (lookups, code, false);
    7333     27950653 :           return e;
    7334              :         }
    7335              :     }
    7336              : 
    7337     34723870 :   exp = NULL_TREE;
    7338              : 
    7339              :   /* [expr.unary.op] says:
    7340              : 
    7341              :        The address of an object of incomplete type can be taken.
    7342              : 
    7343              :      (And is just the ordinary address operator, not an overloaded
    7344              :      "operator &".)  However, if the type is a template
    7345              :      specialization, we must complete the type at this point so that
    7346              :      an overloaded "operator &" will be available if required.  */
    7347     34723870 :   if (code == ADDR_EXPR
    7348      4058782 :       && TREE_CODE (xarg) != TEMPLATE_ID_EXPR
    7349     38782237 :       && ((CLASS_TYPE_P (TREE_TYPE (xarg))
    7350      1780847 :            && !COMPLETE_TYPE_P (complete_type (TREE_TYPE (xarg))))
    7351      4049316 :           || (TREE_CODE (xarg) == OFFSET_REF)))
    7352              :     /* Don't look for a function.  */;
    7353              :   else
    7354     34653137 :     exp = build_new_op (loc, code, LOOKUP_NORMAL, xarg, NULL_TREE,
    7355              :                         NULL_TREE, lookups, &overload, complain);
    7356              : 
    7357     34723870 :   if (!exp && code == ADDR_EXPR)
    7358              :     {
    7359      4058378 :       if (is_overloaded_fn (xarg))
    7360              :         {
    7361       373406 :           tree fn = get_first_fn (xarg);
    7362       746812 :           if (DECL_CONSTRUCTOR_P (fn) || DECL_DESTRUCTOR_P (fn))
    7363              :             {
    7364           12 :               if (complain & tf_error)
    7365           21 :                 error_at (loc, DECL_CONSTRUCTOR_P (fn)
    7366              :                           ? G_("taking address of constructor %qD")
    7367              :                           : G_("taking address of destructor %qD"),
    7368              :                           fn);
    7369           12 :               return error_mark_node;
    7370              :             }
    7371              :         }
    7372              : 
    7373              :       /* A pointer to member-function can be formed only by saying
    7374              :          &X::mf.  */
    7375      4058360 :       if (!flag_ms_extensions && TREE_CODE (TREE_TYPE (xarg)) == METHOD_TYPE
    7376      4116411 :           && (TREE_CODE (xarg) != OFFSET_REF || !PTRMEM_OK_P (xarg)))
    7377              :         {
    7378            9 :           if (TREE_CODE (xarg) != OFFSET_REF
    7379            9 :               || !TYPE_P (TREE_OPERAND (xarg, 0)))
    7380              :             {
    7381            9 :               if (complain & tf_error)
    7382              :                 {
    7383            9 :                   auto_diagnostic_group d;
    7384            9 :                   error_at (loc, "invalid use of %qE to form a "
    7385              :                             "pointer-to-member-function", xarg.get_value ());
    7386            9 :                   if (TREE_CODE (xarg) != OFFSET_REF)
    7387            6 :                     inform (loc, "  a qualified-id is required");
    7388            9 :                 }
    7389            9 :               return error_mark_node;
    7390              :             }
    7391              :           else
    7392              :             {
    7393            0 :               if (complain & tf_error)
    7394            0 :                 error_at (loc, "parentheses around %qE cannot be used to "
    7395              :                           "form a pointer-to-member-function",
    7396              :                           xarg.get_value ());
    7397              :               else
    7398            0 :                 return error_mark_node;
    7399            0 :               PTRMEM_OK_P (xarg) = 1;
    7400              :             }
    7401              :         }
    7402              : 
    7403      4058357 :       if (TREE_CODE (xarg) == OFFSET_REF)
    7404              :         {
    7405        61667 :           ptrmem = PTRMEM_OK_P (xarg);
    7406              : 
    7407            0 :           if (!ptrmem && !flag_ms_extensions
    7408        61667 :               && TREE_CODE (TREE_TYPE (TREE_OPERAND (xarg, 1))) == METHOD_TYPE)
    7409              :             {
    7410              :               /* A single non-static member, make sure we don't allow a
    7411              :                  pointer-to-member.  */
    7412            0 :               xarg = build2 (OFFSET_REF, TREE_TYPE (xarg),
    7413            0 :                              TREE_OPERAND (xarg, 0),
    7414            0 :                              ovl_make (TREE_OPERAND (xarg, 1)));
    7415            0 :               PTRMEM_OK_P (xarg) = ptrmem;
    7416              :             }
    7417              :         }
    7418              : 
    7419      8116714 :       exp = cp_build_addr_expr_strict (xarg, complain);
    7420              : 
    7421      4058357 :       if (TREE_CODE (exp) == PTRMEM_CST)
    7422        60641 :         PTRMEM_CST_LOCATION (exp) = loc;
    7423              :       else
    7424      3997716 :         protected_set_expr_location (exp, loc);
    7425              :     }
    7426              : 
    7427     34723849 :   if (processing_template_decl && exp != error_mark_node)
    7428              :     {
    7429     14819988 :       if (overload != NULL_TREE)
    7430       186066 :         return (build_min_non_dep_op_overload
    7431       186066 :                 (code, exp, overload, orig_expr, integer_zero_node));
    7432              : 
    7433     14633922 :       exp = build_min_non_dep (code, exp, orig_expr,
    7434              :                                /*For {PRE,POST}{INC,DEC}REMENT_EXPR*/NULL_TREE);
    7435              :     }
    7436     34537783 :   if (TREE_CODE (exp) == ADDR_EXPR)
    7437      3266907 :     PTRMEM_OK_P (exp) = ptrmem;
    7438              :   return exp;
    7439              : }
    7440              : 
    7441              : /* Construct and perhaps optimize a tree representation
    7442              :    for __builtin_addressof operation.  ARG specifies the operand.  */
    7443              : 
    7444              : tree
    7445       657847 : cp_build_addressof (location_t loc, tree arg, tsubst_flags_t complain)
    7446              : {
    7447       657847 :   tree orig_expr = arg;
    7448              : 
    7449       657847 :   if (processing_template_decl)
    7450              :     {
    7451       167320 :       if (type_dependent_expression_p (arg))
    7452       167320 :         return build_min_nt_loc (loc, ADDRESSOF_EXPR, arg, NULL_TREE);
    7453              :     }
    7454              : 
    7455       981054 :   tree exp = cp_build_addr_expr_strict (arg, complain);
    7456              : 
    7457       490527 :   if (processing_template_decl && exp != error_mark_node)
    7458            0 :     exp = build_min_non_dep (ADDRESSOF_EXPR, exp, orig_expr, NULL_TREE);
    7459              :   return exp;
    7460              : }
    7461              : 
    7462              : /* Like c_common_truthvalue_conversion, but handle pointer-to-member
    7463              :    constants, where a null value is represented by an INTEGER_CST of
    7464              :    -1.  */
    7465              : 
    7466              : tree
    7467      7861250 : cp_truthvalue_conversion (tree expr, tsubst_flags_t complain)
    7468              : {
    7469      7861250 :   tree type = TREE_TYPE (expr);
    7470      7861250 :   location_t loc = cp_expr_loc_or_input_loc (expr);
    7471      6623704 :   if (TYPE_PTR_OR_PTRMEM_P (type)
    7472              :       /* Avoid ICE on invalid use of non-static member function.  */
    7473     14484666 :       || TREE_CODE (expr) == FUNCTION_DECL)
    7474      1237834 :     return cp_build_binary_op (loc, NE_EXPR, expr, nullptr_node, complain);
    7475              :   else
    7476      6623416 :     return c_common_truthvalue_conversion (loc, expr);
    7477              : }
    7478              : 
    7479              : /* Returns EXPR contextually converted to bool.  */
    7480              : 
    7481              : tree
    7482     75195244 : contextual_conv_bool (tree expr, tsubst_flags_t complain)
    7483              : {
    7484     75195244 :   return perform_implicit_conversion_flags (boolean_type_node, expr,
    7485     75195244 :                                             complain, LOOKUP_NORMAL);
    7486              : }
    7487              : 
    7488              : /* Just like cp_truthvalue_conversion, but we want a CLEANUP_POINT_EXPR.  This
    7489              :    is a low-level function; most callers should use maybe_convert_cond.  */
    7490              : 
    7491              : tree
    7492     51197257 : condition_conversion (tree expr)
    7493              : {
    7494     51197257 :   tree t = contextual_conv_bool (expr, tf_warning_or_error);
    7495     51197257 :   if (!processing_template_decl)
    7496     25275163 :     t = fold_build_cleanup_point_expr (boolean_type_node, t);
    7497     51197257 :   return t;
    7498              : }
    7499              : 
    7500              : /* Returns the address of T.  This function will fold away
    7501              :    ADDR_EXPR of INDIRECT_REF.  This is only for low-level usage;
    7502              :    most places should use cp_build_addr_expr instead.  */
    7503              : 
    7504              : tree
    7505    333418567 : build_address (tree t)
    7506              : {
    7507    333418567 :   if (error_operand_p (t) || !cxx_mark_addressable (t))
    7508           24 :     return error_mark_node;
    7509    333418543 :   gcc_checking_assert (TREE_CODE (t) != CONSTRUCTOR
    7510              :                        || processing_template_decl);
    7511    333418543 :   t = build_fold_addr_expr_loc (EXPR_LOCATION (t), t);
    7512    333418543 :   if (TREE_CODE (t) != ADDR_EXPR)
    7513     59071303 :     t = rvalue (t);
    7514              :   return t;
    7515              : }
    7516              : 
    7517              : /* Return a NOP_EXPR converting EXPR to TYPE.  */
    7518              : 
    7519              : tree
    7520    559362360 : build_nop (tree type, tree expr MEM_STAT_DECL)
    7521              : {
    7522    559362360 :   if (type == error_mark_node || error_operand_p (expr))
    7523              :     return expr;
    7524    559362286 :   return build1_loc (EXPR_LOCATION (expr), NOP_EXPR, type, expr PASS_MEM_STAT);
    7525              : }
    7526              : 
    7527              : /* Take the address of ARG, whatever that means under C++ semantics.
    7528              :    If STRICT_LVALUE is true, require an lvalue; otherwise, allow xvalues
    7529              :    and class rvalues as well.
    7530              : 
    7531              :    Nothing should call this function directly; instead, callers should use
    7532              :    cp_build_addr_expr or cp_build_addr_expr_strict.  */
    7533              : 
    7534              : static tree
    7535    261959320 : cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain)
    7536              : {
    7537    261959320 :   tree argtype;
    7538    261959320 :   tree val;
    7539              : 
    7540    261959320 :   if (!arg || error_operand_p (arg))
    7541           12 :     return error_mark_node;
    7542              : 
    7543    261959308 :   arg = mark_lvalue_use (arg);
    7544    261959308 :   if (error_operand_p (arg))
    7545            3 :     return error_mark_node;
    7546              : 
    7547    261959305 :   argtype = lvalue_type (arg);
    7548    261959305 :   location_t loc = cp_expr_loc_or_input_loc (arg);
    7549              : 
    7550    261959305 :   gcc_assert (!(identifier_p (arg) && IDENTIFIER_ANY_OP_P (arg)));
    7551              : 
    7552     15386664 :   if (TREE_CODE (arg) == COMPONENT_REF && type_unknown_p (arg)
    7553    261959533 :       && !really_overloaded_fn (arg))
    7554              :     {
    7555              :       /* They're trying to take the address of a unique non-static
    7556              :          member function.  This is ill-formed (except in MS-land),
    7557              :          but let's try to DTRT.
    7558              :          Note: We only handle unique functions here because we don't
    7559              :          want to complain if there's a static overload; non-unique
    7560              :          cases will be handled by instantiate_type.  But we need to
    7561              :          handle this case here to allow casts on the resulting PMF.
    7562              :          We could defer this in non-MS mode, but it's easier to give
    7563              :          a useful error here.  */
    7564              : 
    7565              :       /* Inside constant member functions, the `this' pointer
    7566              :          contains an extra const qualifier.  TYPE_MAIN_VARIANT
    7567              :          is used here to remove this const from the diagnostics
    7568              :          and the created OFFSET_REF.  */
    7569           87 :       tree base = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (arg, 0)));
    7570           87 :       tree fn = get_first_fn (TREE_OPERAND (arg, 1));
    7571           87 :       if (!mark_used (fn, complain) && !(complain & tf_error))
    7572            0 :         return error_mark_node;
    7573              :       /* Until microsoft headers are known to incorrectly take the address of
    7574              :          unqualified xobj member functions we should not support this
    7575              :          extension.
    7576              :          See comment in class.cc:resolve_address_of_overloaded_function for
    7577              :          the extended reasoning.  */
    7578           87 :       if (!flag_ms_extensions || DECL_XOBJ_MEMBER_FUNCTION_P (fn))
    7579              :         {
    7580           81 :           auto_diagnostic_group d;
    7581           81 :           tree name = DECL_NAME (fn);
    7582           81 :           if (!(complain & tf_error))
    7583            0 :             return error_mark_node;
    7584           81 :           else if (current_class_type
    7585           81 :                    && TREE_OPERAND (arg, 0) == current_class_ref)
    7586              :             /* An expression like &memfn.  */
    7587           36 :             if (!DECL_XOBJ_MEMBER_FUNCTION_P (fn))
    7588           21 :               permerror (loc,
    7589              :                          "ISO C++ forbids taking the address of an unqualified"
    7590              :                          " or parenthesized non-static member function to form"
    7591              :                          " a pointer to member function.  Say %<&%T::%D%>",
    7592              :                          base, name);
    7593              :             else
    7594           15 :               error_at (loc,
    7595              :                         "ISO C++ forbids taking the address of an unqualified"
    7596              :                         " or parenthesized non-static member function to form"
    7597              :                         " a pointer to explicit object member function");
    7598              :           else
    7599           45 :             if (!DECL_XOBJ_MEMBER_FUNCTION_P (fn))
    7600            9 :               permerror (loc,
    7601              :                          "ISO C++ forbids taking the address of a bound member"
    7602              :                          " function to form a pointer to member function."
    7603              :                          "  Say %<&%T::%D%>",
    7604              :                          base, name);
    7605              :             else
    7606           36 :               error_at (loc,
    7607              :                         "ISO C++ forbids taking the address of a bound member"
    7608              :                         " function to form a pointer to explicit object member"
    7609              :                         " function");
    7610           81 :           if (DECL_XOBJ_MEMBER_FUNCTION_P (fn))
    7611           51 :             inform (loc,
    7612              :                     "a pointer to explicit object member function can only be "
    7613              :                     "formed with %<&%T::%D%>", base, name);
    7614           81 :         }
    7615           87 :       arg = build_offset_ref (base, fn, /*address_p=*/true, complain);
    7616              :     }
    7617              : 
    7618              :   /* Uninstantiated types are all functions.  Taking the
    7619              :      address of a function is a no-op, so just return the
    7620              :      argument.  */
    7621    261959305 :   if (type_unknown_p (arg))
    7622         3014 :     return build1 (ADDR_EXPR, unknown_type_node, arg);
    7623              : 
    7624    261956291 :   if (TREE_CODE (arg) == OFFSET_REF)
    7625              :     /* We want a pointer to member; bypass all the code for actually taking
    7626              :        the address of something.  */
    7627        60858 :     goto offset_ref;
    7628              : 
    7629              :   /* Anything not already handled and not a true memory reference
    7630              :      is an error.  */
    7631    261895433 :   if (!FUNC_OR_METHOD_TYPE_P (argtype))
    7632              :     {
    7633    138379418 :       cp_lvalue_kind kind = lvalue_kind (arg);
    7634    138379418 :       if (kind == clk_none)
    7635              :         {
    7636           25 :           if (complain & tf_error)
    7637           25 :             lvalue_error (loc, lv_addressof);
    7638           25 :           return error_mark_node;
    7639              :         }
    7640    138379393 :       if (strict_lvalue && (kind & (clk_rvalueref|clk_class)))
    7641              :         {
    7642           39 :           if (!(complain & tf_error))
    7643           12 :             return error_mark_node;
    7644              :           /* Make this a permerror because we used to accept it.  */
    7645           27 :           permerror (loc, "taking address of rvalue");
    7646              :         }
    7647              :     }
    7648              : 
    7649    261895396 :   if (TYPE_REF_P (argtype))
    7650              :     {
    7651          238 :       tree type = build_pointer_type (TREE_TYPE (argtype));
    7652          238 :       arg = build1 (CONVERT_EXPR, type, arg);
    7653          238 :       return arg;
    7654              :     }
    7655    261895158 :   else if (pedantic && DECL_MAIN_P (tree_strip_any_location_wrapper (arg)))
    7656              :     {
    7657              :       /* ARM $3.4 */
    7658              :       /* Apparently a lot of autoconf scripts for C++ packages do this,
    7659              :          so only complain if -Wpedantic.  */
    7660            9 :       if (complain & (flag_pedantic_errors ? tf_error : tf_warning))
    7661            9 :         pedwarn (loc, OPT_Wpedantic,
    7662              :                  "ISO C++ forbids taking address of function %<::main%>");
    7663            0 :       else if (flag_pedantic_errors)
    7664            0 :         return error_mark_node;
    7665              :     }
    7666              : 
    7667              :   /* Let &* cancel out to simplify resulting code.  */
    7668    261895158 :   if (INDIRECT_REF_P (arg))
    7669              :     {
    7670     94349244 :       arg = TREE_OPERAND (arg, 0);
    7671     94349244 :       if (TYPE_REF_P (TREE_TYPE (arg)))
    7672              :         {
    7673     57137572 :           tree type = build_pointer_type (TREE_TYPE (TREE_TYPE (arg)));
    7674     57137572 :           arg = build1 (CONVERT_EXPR, type, arg);
    7675              :         }
    7676              :       else
    7677              :         /* Don't let this be an lvalue.  */
    7678     37211672 :         arg = rvalue (arg);
    7679     94349244 :       return arg;
    7680              :     }
    7681              : 
    7682              :   /* Handle complex lvalues (when permitted)
    7683              :      by reduction to simpler cases.  */
    7684    167545914 :   val = unary_complex_lvalue (ADDR_EXPR, arg);
    7685    167545914 :   if (val != 0)
    7686              :     return val;
    7687              : 
    7688    167074235 :   switch (TREE_CODE (arg))
    7689              :     {
    7690            0 :     CASE_CONVERT:
    7691            0 :     case FLOAT_EXPR:
    7692            0 :     case FIX_TRUNC_EXPR:
    7693              :       /* We should have handled this above in the lvalue_kind check.  */
    7694            0 :       gcc_unreachable ();
    7695        77421 :       break;
    7696              : 
    7697        77421 :     case BASELINK:
    7698        77421 :       arg = BASELINK_FUNCTIONS (arg);
    7699              :       /* Fall through.  */
    7700              : 
    7701        77421 :     case OVERLOAD:
    7702        77421 :       arg = OVL_FIRST (arg);
    7703              :       break;
    7704              : 
    7705        60858 :     case OFFSET_REF:
    7706        60858 :     offset_ref:
    7707              :       /* Turn a reference to a non-static data member into a
    7708              :          pointer-to-member.  */
    7709        60858 :       {
    7710        60858 :         tree type;
    7711        60858 :         tree t;
    7712              : 
    7713        60858 :         gcc_assert (PTRMEM_OK_P (arg));
    7714              : 
    7715        60858 :         t = TREE_OPERAND (arg, 1);
    7716        60858 :         if (TYPE_REF_P (TREE_TYPE (t)))
    7717              :           {
    7718           15 :             if (complain & tf_error)
    7719           15 :               error_at (loc,
    7720              :                         "cannot create pointer to reference member %qD", t);
    7721           15 :             return error_mark_node;
    7722              :           }
    7723              : 
    7724              :         /* Forming a pointer-to-member is a use of non-pure-virtual fns.  */
    7725        60843 :         if (TREE_CODE (t) == FUNCTION_DECL
    7726        58253 :             && !DECL_PURE_VIRTUAL_P (t)
    7727       119073 :             && !mark_used (t, complain) && !(complain & tf_error))
    7728            3 :           return error_mark_node;
    7729              : 
    7730              :         /* Pull out the function_decl for a single xobj member function, and
    7731              :            let the rest of this function handle it.  This is similar to how
    7732              :            static member functions are handled in the BASELINK case above.  */
    7733        60840 :         if (DECL_XOBJ_MEMBER_FUNCTION_P (t))
    7734              :           {
    7735              :             arg = t;
    7736              :             break;
    7737              :           }
    7738              : 
    7739        60744 :         type = build_ptrmem_type (context_for_name_lookup (t),
    7740        60744 :                                   TREE_TYPE (t));
    7741        60744 :         t = make_ptrmem_cst (type, t);
    7742        60744 :         return t;
    7743              :       }
    7744              : 
    7745              :     default:
    7746              :       break;
    7747              :     }
    7748              : 
    7749    167074331 :   if (argtype != error_mark_node)
    7750    167074331 :     argtype = build_pointer_type (argtype);
    7751              : 
    7752    167074331 :   if (bitfield_p (arg))
    7753              :     {
    7754           33 :       if (complain & tf_error)
    7755           33 :         error_at (loc, "attempt to take address of bit-field");
    7756           33 :       return error_mark_node;
    7757              :     }
    7758              : 
    7759              :   /* In a template, we are processing a non-dependent expression
    7760              :      so we can just form an ADDR_EXPR with the correct type.  */
    7761    167074298 :   if (processing_template_decl || TREE_CODE (arg) != COMPONENT_REF)
    7762              :     {
    7763    152154229 :       if (!mark_single_function (arg, complain))
    7764            3 :         return error_mark_node;
    7765    152154226 :       val = build_address (arg);
    7766    152154226 :       if (TREE_CODE (arg) == OFFSET_REF)
    7767            0 :         PTRMEM_OK_P (val) = PTRMEM_OK_P (arg);
    7768              :     }
    7769     14920069 :   else if (BASELINK_P (TREE_OPERAND (arg, 1)))
    7770              :     {
    7771           27 :       tree fn = BASELINK_FUNCTIONS (TREE_OPERAND (arg, 1));
    7772              : 
    7773           27 :       if (TREE_CODE (fn) == OVERLOAD && OVL_SINGLE_P (fn))
    7774           27 :         fn = OVL_FIRST (fn);
    7775              : 
    7776              :       /* We can only get here with a single static member
    7777              :          function.  */
    7778           27 :       gcc_assert (TREE_CODE (fn) == FUNCTION_DECL
    7779              :                   && DECL_STATIC_FUNCTION_P (fn));
    7780           27 :       if (!mark_used (fn, complain) && !(complain & tf_error))
    7781            0 :         return error_mark_node;
    7782           27 :       val = build_address (fn);
    7783           27 :       if (TREE_SIDE_EFFECTS (TREE_OPERAND (arg, 0)))
    7784              :         /* Do not lose object's side effects.  */
    7785           12 :         val = build2 (COMPOUND_EXPR, TREE_TYPE (val),
    7786           12 :                       TREE_OPERAND (arg, 0), val);
    7787              :     }
    7788              :   else
    7789              :     {
    7790     14920042 :       tree object = TREE_OPERAND (arg, 0);
    7791     14920042 :       tree field = TREE_OPERAND (arg, 1);
    7792     14920042 :       gcc_assert (same_type_ignoring_top_level_qualifiers_p
    7793              :                   (TREE_TYPE (object), decl_type_context (field)));
    7794     14920042 :       val = build_address (arg);
    7795              :     }
    7796              : 
    7797    167074295 :   if (TYPE_PTR_P (argtype)
    7798    167074295 :       && TREE_CODE (TREE_TYPE (argtype)) == METHOD_TYPE)
    7799              :     {
    7800         1120 :       build_ptrmemfunc_type (argtype);
    7801         1120 :       val = build_ptrmemfunc (argtype, val, 0,
    7802              :                               /*c_cast_p=*/false,
    7803              :                               complain);
    7804              :     }
    7805              : 
    7806              :   /* Ensure we have EXPR_LOCATION set for possible later diagnostics.  */
    7807    167074295 :   if (TREE_CODE (val) == ADDR_EXPR
    7808    167074295 :       && TREE_CODE (TREE_OPERAND (val, 0)) == FUNCTION_DECL)
    7809    118218327 :     SET_EXPR_LOCATION (val, input_location);
    7810              : 
    7811              :   return val;
    7812              : }
    7813              : 
    7814              : /* Take the address of ARG if it has one, even if it's an rvalue.  */
    7815              : 
    7816              : tree
    7817    257410436 : cp_build_addr_expr (tree arg, tsubst_flags_t complain)
    7818              : {
    7819    257410436 :   return cp_build_addr_expr_1 (arg, 0, complain);
    7820              : }
    7821              : 
    7822              : /* Take the address of ARG, but only if it's an lvalue.  */
    7823              : 
    7824              : static tree
    7825      4548884 : cp_build_addr_expr_strict (tree arg, tsubst_flags_t complain)
    7826              : {
    7827      4548884 :   return cp_build_addr_expr_1 (arg, 1, complain);
    7828              : }
    7829              : 
    7830              : /* C++: Must handle pointers to members.
    7831              : 
    7832              :    Perhaps type instantiation should be extended to handle conversion
    7833              :    from aggregates to types we don't yet know we want?  (Or are those
    7834              :    cases typically errors which should be reported?)
    7835              : 
    7836              :    NOCONVERT suppresses the default promotions (such as from short to int).  */
    7837              : 
    7838              : tree
    7839     30333589 : cp_build_unary_op (enum tree_code code, tree xarg, bool noconvert,
    7840              :                    tsubst_flags_t complain)
    7841              : {
    7842              :   /* No default_conversion here.  It causes trouble for ADDR_EXPR.  */
    7843     30333589 :   tree arg = xarg;
    7844     30333589 :   location_t location = cp_expr_loc_or_input_loc (arg);
    7845     30333589 :   tree argtype = 0;
    7846     30333589 :   tree eptype = NULL_TREE;
    7847     30333589 :   const char *errstring = NULL;
    7848     30333589 :   tree val;
    7849     30333589 :   const char *invalid_op_diag;
    7850              : 
    7851     30333589 :   if (!arg || error_operand_p (arg))
    7852            0 :     return error_mark_node;
    7853              : 
    7854     30333589 :   arg = resolve_nondeduced_context (arg, complain);
    7855              : 
    7856     60667178 :   if ((invalid_op_diag
    7857     30333589 :        = targetm.invalid_unary_op ((code == UNARY_PLUS_EXPR
    7858              :                                     ? CONVERT_EXPR
    7859              :                                     : code),
    7860     30333589 :                                    TREE_TYPE (arg))))
    7861              :     {
    7862            0 :       if (complain & tf_error)
    7863            0 :         error (invalid_op_diag);
    7864            0 :       return error_mark_node;
    7865              :     }
    7866              : 
    7867     30333589 :   if (TREE_CODE (arg) == EXCESS_PRECISION_EXPR)
    7868              :     {
    7869         7778 :       eptype = TREE_TYPE (arg);
    7870         7778 :       arg = TREE_OPERAND (arg, 0);
    7871              :     }
    7872              : 
    7873     30333589 :   switch (code)
    7874              :     {
    7875      2351099 :     case UNARY_PLUS_EXPR:
    7876      2351099 :     case NEGATE_EXPR:
    7877      2351099 :       {
    7878      2351099 :         int flags = WANT_ARITH | WANT_ENUM;
    7879              :         /* Unary plus (but not unary minus) is allowed on pointers.  */
    7880      2351099 :         if (code == UNARY_PLUS_EXPR)
    7881       158810 :           flags |= WANT_POINTER;
    7882      2351099 :         arg = build_expr_type_conversion (flags, arg, true);
    7883      2351099 :         if (!arg)
    7884           35 :           errstring = (code == NEGATE_EXPR
    7885           27 :                        ? _("wrong type argument to unary minus")
    7886            8 :                        : _("wrong type argument to unary plus"));
    7887              :         else
    7888              :           {
    7889      2351064 :             if (!noconvert && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (arg)))
    7890       666884 :               arg = cp_perform_integral_promotions (arg, complain);
    7891              : 
    7892              :             /* Make sure the result is not an lvalue: a unary plus or minus
    7893              :                expression is always a rvalue.  */
    7894      2351064 :             arg = rvalue (arg);
    7895              :           }
    7896              :       }
    7897              :       break;
    7898              : 
    7899       922827 :     case BIT_NOT_EXPR:
    7900       922827 :       if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
    7901              :         {
    7902           15 :           code = CONJ_EXPR;
    7903           15 :           if (!noconvert)
    7904              :             {
    7905           15 :               arg = cp_default_conversion (arg, complain);
    7906           15 :               if (arg == error_mark_node)
    7907              :                 return error_mark_node;
    7908              :             }
    7909              :         }
    7910       922812 :       else if (!(arg = build_expr_type_conversion (WANT_INT | WANT_ENUM
    7911              :                                                    | WANT_VECTOR_OR_COMPLEX,
    7912              :                                                    arg, true)))
    7913           17 :         errstring = _("wrong type argument to bit-complement");
    7914       922795 :       else if (!noconvert && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (arg)))
    7915              :         {
    7916              :           /* Warn if the expression has boolean value.  */
    7917       922440 :           if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE
    7918       922440 :               && (complain & tf_warning))
    7919              :             {
    7920           61 :               auto_diagnostic_group d;
    7921           61 :               if (warning_at (location, OPT_Wbool_operation,
    7922              :                               "%<~%> on an expression of type %<bool%>"))
    7923           42 :                 inform (location, "did you mean to use logical not (%<!%>)?");
    7924           61 :             }
    7925       922440 :           arg = cp_perform_integral_promotions (arg, complain);
    7926              :         }
    7927          355 :       else if (!noconvert && VECTOR_TYPE_P (TREE_TYPE (arg)))
    7928          355 :         arg = mark_rvalue_use (arg);
    7929              :       break;
    7930              : 
    7931            0 :     case ABS_EXPR:
    7932            0 :       if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, arg, true)))
    7933            0 :         errstring = _("wrong type argument to abs");
    7934            0 :       else if (!noconvert)
    7935              :         {
    7936            0 :           arg = cp_default_conversion (arg, complain);
    7937            0 :           if (arg == error_mark_node)
    7938              :             return error_mark_node;
    7939              :         }
    7940              :       break;
    7941              : 
    7942            0 :     case CONJ_EXPR:
    7943              :       /* Conjugating a real value is a no-op, but allow it anyway.  */
    7944            0 :       if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, arg, true)))
    7945            0 :         errstring = _("wrong type argument to conjugation");
    7946            0 :       else if (!noconvert)
    7947              :         {
    7948            0 :           arg = cp_default_conversion (arg, complain);
    7949            0 :           if (arg == error_mark_node)
    7950              :             return error_mark_node;
    7951              :         }
    7952              :       break;
    7953              : 
    7954     17718611 :     case TRUTH_NOT_EXPR:
    7955     17718611 :       if (gnu_vector_type_p (TREE_TYPE (arg)))
    7956           60 :         return cp_build_binary_op (input_location, EQ_EXPR, arg,
    7957           60 :                                    build_zero_cst (TREE_TYPE (arg)), complain);
    7958     17718551 :       arg = contextual_conv_bool (arg, complain);
    7959     17718551 :       if (arg != error_mark_node)
    7960              :         {
    7961     17718541 :           if (processing_template_decl)
    7962      8324614 :             return build1_loc (location, TRUTH_NOT_EXPR, boolean_type_node, arg);
    7963      9393927 :           val = invert_truthvalue_loc (location, arg);
    7964      9393927 :           if (obvalue_p (val))
    7965        11960 :             val = non_lvalue_loc (location, val);
    7966      9393927 :           return val;
    7967              :         }
    7968           10 :       errstring = _("in argument to unary !");
    7969           10 :       break;
    7970              : 
    7971              :     case NOP_EXPR:
    7972              :       break;
    7973              : 
    7974       441730 :     case REALPART_EXPR:
    7975       441730 :     case IMAGPART_EXPR:
    7976       441730 :       val = build_real_imag_expr (input_location, code, arg);
    7977       441730 :       if (eptype && TREE_CODE (eptype) == COMPLEX_EXPR)
    7978            0 :         val = build1_loc (input_location, EXCESS_PRECISION_EXPR,
    7979            0 :                           TREE_TYPE (eptype), val);
    7980              :       return val;
    7981              : 
    7982      8347100 :     case PREINCREMENT_EXPR:
    7983      8347100 :     case POSTINCREMENT_EXPR:
    7984      8347100 :     case PREDECREMENT_EXPR:
    7985      8347100 :     case POSTDECREMENT_EXPR:
    7986              :       /* Handle complex lvalues (when permitted)
    7987              :          by reduction to simpler cases.  */
    7988              : 
    7989      8347100 :       val = unary_complex_lvalue (code, arg);
    7990      8347100 :       if (val != 0)
    7991           38 :         goto return_build_unary_op;
    7992              : 
    7993      8347062 :       tree stripped_arg;
    7994      8347062 :       stripped_arg = tree_strip_any_location_wrapper (arg);
    7995      2083187 :       if ((VAR_P (stripped_arg) || TREE_CODE (stripped_arg) == PARM_DECL)
    7996      7733208 :           && !DECL_READ_P (stripped_arg)
    7997      9453618 :           && (VAR_P (stripped_arg) ? warn_unused_but_set_variable
    7998              :                                    : warn_unused_but_set_parameter) > 1)
    7999              :         {
    8000         9811 :           arg = mark_lvalue_use (arg);
    8001         9811 :           DECL_READ_P (stripped_arg) = 0;
    8002              :         }
    8003              :       else
    8004      8337251 :         arg = mark_lvalue_use (arg);
    8005              : 
    8006              :       /* Increment or decrement the real part of the value,
    8007              :          and don't change the imaginary part.  */
    8008      8347062 :       if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
    8009              :         {
    8010           18 :           tree real, imag;
    8011              : 
    8012           18 :           arg = cp_stabilize_reference (arg);
    8013           18 :           real = cp_build_unary_op (REALPART_EXPR, arg, true, complain);
    8014           18 :           imag = cp_build_unary_op (IMAGPART_EXPR, arg, true, complain);
    8015           18 :           real = cp_build_unary_op (code, real, true, complain);
    8016           18 :           if (real == error_mark_node || imag == error_mark_node)
    8017              :             return error_mark_node;
    8018           15 :           val = build2 (COMPLEX_EXPR, TREE_TYPE (arg), real, imag);
    8019           15 :           goto return_build_unary_op;
    8020              :         }
    8021              : 
    8022              :       /* Report invalid types.  */
    8023              : 
    8024      8347044 :       if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_POINTER,
    8025              :                                               arg, true)))
    8026              :         {
    8027           36 :           if (code == PREINCREMENT_EXPR)
    8028            9 :             errstring = _("no pre-increment operator for type");
    8029           27 :           else if (code == POSTINCREMENT_EXPR)
    8030            9 :             errstring = _("no post-increment operator for type");
    8031           18 :           else if (code == PREDECREMENT_EXPR)
    8032            9 :             errstring = _("no pre-decrement operator for type");
    8033              :           else
    8034            9 :             errstring = _("no post-decrement operator for type");
    8035              :           break;
    8036              :         }
    8037      8347008 :       else if (arg == error_mark_node)
    8038              :         return error_mark_node;
    8039              : 
    8040              :       /* Report something read-only.  */
    8041              : 
    8042      8347005 :       if (CP_TYPE_CONST_P (TREE_TYPE (arg))
    8043      8347005 :           || TREE_READONLY (arg))
    8044              :         {
    8045          164 :           if (complain & tf_error)
    8046          164 :             cxx_readonly_error (location, arg,
    8047          164 :                                 ((code == PREINCREMENT_EXPR
    8048          164 :                                   || code == POSTINCREMENT_EXPR)
    8049              :                                  ? lv_increment : lv_decrement));
    8050              :           else
    8051            0 :             return error_mark_node;
    8052              :         }
    8053              : 
    8054      8347005 :       {
    8055      8347005 :         tree inc;
    8056      8347005 :         tree declared_type = unlowered_expr_type (arg);
    8057              : 
    8058      8347005 :         argtype = TREE_TYPE (arg);
    8059              : 
    8060              :         /* ARM $5.2.5 last annotation says this should be forbidden.  */
    8061      8347005 :         if (TREE_CODE (argtype) == ENUMERAL_TYPE)
    8062              :           {
    8063            0 :             if (complain & tf_error)
    8064            0 :               permerror (location, (code == PREINCREMENT_EXPR
    8065            0 :                                     || code == POSTINCREMENT_EXPR)
    8066              :                          ? G_("ISO C++ forbids incrementing an enum")
    8067              :                          : G_("ISO C++ forbids decrementing an enum"));
    8068              :             else
    8069            0 :               return error_mark_node;
    8070              :           }
    8071              : 
    8072              :         /* Compute the increment.  */
    8073              : 
    8074      8347005 :         if (TYPE_PTR_P (argtype))
    8075              :           {
    8076      2659554 :             tree type = complete_type (TREE_TYPE (argtype));
    8077              : 
    8078      2659554 :             if (!COMPLETE_OR_VOID_TYPE_P (type))
    8079              :               {
    8080           10 :                 if (complain & tf_error)
    8081            9 :                   error_at (location, ((code == PREINCREMENT_EXPR
    8082            9 :                                         || code == POSTINCREMENT_EXPR))
    8083              :                             ? G_("cannot increment a pointer to incomplete "
    8084              :                                  "type %qT")
    8085              :                             : G_("cannot decrement a pointer to incomplete "
    8086              :                                  "type %qT"),
    8087            9 :                             TREE_TYPE (argtype));
    8088              :                 else
    8089            1 :                   return error_mark_node;
    8090              :               }
    8091      2659544 :             else if (!TYPE_PTROB_P (argtype))
    8092              :               {
    8093           69 :                 if (complain & tf_error)
    8094           63 :                   pedwarn (location, OPT_Wpointer_arith,
    8095           63 :                            (code == PREINCREMENT_EXPR
    8096           63 :                               || code == POSTINCREMENT_EXPR)
    8097              :                            ? G_("ISO C++ forbids incrementing a pointer "
    8098              :                                 "of type %qT")
    8099              :                            : G_("ISO C++ forbids decrementing a pointer "
    8100              :                                 "of type %qT"),
    8101              :                            argtype);
    8102              :                 else
    8103            6 :                   return error_mark_node;
    8104              :               }
    8105      2659475 :             else if (!verify_type_context (location, TCTX_POINTER_ARITH,
    8106      2659475 :                                            TREE_TYPE (argtype),
    8107              :                                            !(complain & tf_error)))
    8108            0 :               return error_mark_node;
    8109              : 
    8110      2659547 :             inc = cxx_sizeof_nowarn (TREE_TYPE (argtype));
    8111              :           }
    8112              :         else
    8113      5687308 :           inc = VECTOR_TYPE_P (argtype)
    8114      5687451 :             ? build_one_cst (argtype)
    8115              :             : integer_one_node;
    8116              : 
    8117      8346998 :         inc = cp_convert (argtype, inc, complain);
    8118              : 
    8119              :         /* If 'arg' is an Objective-C PROPERTY_REF expression, then we
    8120              :            need to ask Objective-C to build the increment or decrement
    8121              :            expression for it.  */
    8122      8346998 :         if (objc_is_property_ref (arg))
    8123            0 :           return objc_build_incr_expr_for_property_ref (input_location, code,
    8124            0 :                                                         arg, inc);
    8125              : 
    8126              :         /* Complain about anything else that is not a true lvalue.  */
    8127      8346998 :         if (!lvalue_or_else (arg, ((code == PREINCREMENT_EXPR
    8128      8346998 :                                     || code == POSTINCREMENT_EXPR)
    8129              :                                    ? lv_increment : lv_decrement),
    8130              :                              complain))
    8131           38 :           return error_mark_node;
    8132              : 
    8133              :         /* [depr.volatile.type] "Postfix ++ and -- expressions and
    8134              :            prefix ++ and -- expressions of volatile-qualified arithmetic
    8135              :            and pointer types are deprecated."  */
    8136      8346675 :         if ((TREE_THIS_VOLATILE (arg) || CP_TYPE_VOLATILE_P (TREE_TYPE (arg)))
    8137      8346960 :             && (complain & tf_warning))
    8138          398 :           warning_at (location, OPT_Wvolatile,
    8139              :                       "%qs expression of %<volatile%>-qualified type is "
    8140              :                       "deprecated",
    8141              :                       ((code == PREINCREMENT_EXPR
    8142              :                         || code == POSTINCREMENT_EXPR)
    8143              :                        ? "++" : "--"));
    8144              : 
    8145              :         /* Forbid using -- or ++ in C++17 on `bool'.  */
    8146      8346960 :         if (TREE_CODE (declared_type) == BOOLEAN_TYPE)
    8147              :           {
    8148           95 :             if (code == POSTDECREMENT_EXPR || code == PREDECREMENT_EXPR)
    8149              :               {
    8150           33 :                 if (complain & tf_error)
    8151           33 :                   error_at (location,
    8152              :                             "use of an operand of type %qT in %<operator--%> "
    8153              :                             "is forbidden", boolean_type_node);
    8154           33 :                 return error_mark_node;
    8155              :               }
    8156              :             else
    8157              :               {
    8158           62 :                 if (cxx_dialect >= cxx17)
    8159              :                   {
    8160           33 :                     if (complain & tf_error)
    8161           32 :                       error_at (location,
    8162              :                                 "use of an operand of type %qT in "
    8163              :                                 "%<operator++%> is forbidden in C++17",
    8164              :                                 boolean_type_node);
    8165           33 :                     return error_mark_node;
    8166              :                   }
    8167              :                 /* Otherwise, [depr.incr.bool] says this is deprecated.  */
    8168           29 :                 else if (complain & tf_warning)
    8169           25 :                   warning_at (location, OPT_Wdeprecated,
    8170              :                               "use of an operand of type %qT "
    8171              :                               "in %<operator++%> is deprecated",
    8172              :                               boolean_type_node);
    8173              :               }
    8174           29 :             val = boolean_increment (code, arg);
    8175              :           }
    8176      8346865 :         else if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
    8177              :           /* An rvalue has no cv-qualifiers.  */
    8178      1349351 :           val = build2 (code, cv_unqualified (TREE_TYPE (arg)), arg, inc);
    8179              :         else
    8180      6997514 :           val = build2 (code, TREE_TYPE (arg), arg, inc);
    8181              : 
    8182      8346894 :         TREE_SIDE_EFFECTS (val) = 1;
    8183      8346894 :         goto return_build_unary_op;
    8184              :       }
    8185              : 
    8186       552222 :     case ADDR_EXPR:
    8187              :       /* Note that this operation never does default_conversion
    8188              :          regardless of NOCONVERT.  */
    8189       552222 :       return cp_build_addr_expr (arg, complain);
    8190              : 
    8191              :     default:
    8192              :       break;
    8193              :     }
    8194              : 
    8195      3273957 :   if (!errstring)
    8196              :     {
    8197      3273874 :       if (argtype == 0)
    8198      3273874 :         argtype = TREE_TYPE (arg);
    8199      3273874 :       val = build1 (code, argtype, arg);
    8200     11620821 :     return_build_unary_op:
    8201     11620821 :       if (eptype)
    8202         7769 :         val = build1 (EXCESS_PRECISION_EXPR, eptype, val);
    8203     11620821 :       return val;
    8204              :     }
    8205              : 
    8206           98 :   if (complain & tf_error)
    8207           53 :     error_at (location, "%s", errstring);
    8208           98 :   return error_mark_node;
    8209              : }
    8210              : 
    8211              : /* Hook for the c-common bits that build a unary op.  */
    8212              : tree
    8213         4136 : build_unary_op (location_t /*location*/,
    8214              :                 enum tree_code code, tree xarg, bool noconvert)
    8215              : {
    8216         4136 :   return cp_build_unary_op (code, xarg, noconvert, tf_warning_or_error);
    8217              : }
    8218              : 
    8219              : /* Adjust LVALUE, an MODIFY_EXPR, PREINCREMENT_EXPR or PREDECREMENT_EXPR,
    8220              :    so that it is a valid lvalue even for GENERIC by replacing
    8221              :    (lhs = rhs) with ((lhs = rhs), lhs)
    8222              :    (--lhs) with ((--lhs), lhs)
    8223              :    (++lhs) with ((++lhs), lhs)
    8224              :    and if lhs has side-effects, calling cp_stabilize_reference on it, so
    8225              :    that it can be evaluated multiple times.  */
    8226              : 
    8227              : tree
    8228       393850 : genericize_compound_lvalue (tree lvalue)
    8229              : {
    8230       393850 :   if (TREE_SIDE_EFFECTS (TREE_OPERAND (lvalue, 0)))
    8231          199 :     lvalue = build2 (TREE_CODE (lvalue), TREE_TYPE (lvalue),
    8232          199 :                      cp_stabilize_reference (TREE_OPERAND (lvalue, 0)),
    8233          199 :                      TREE_OPERAND (lvalue, 1));
    8234       393850 :   return build2 (COMPOUND_EXPR, TREE_TYPE (TREE_OPERAND (lvalue, 0)),
    8235       393850 :                  lvalue, TREE_OPERAND (lvalue, 0));
    8236              : }
    8237              : 
    8238              : /* Apply unary lvalue-demanding operator CODE to the expression ARG
    8239              :    for certain kinds of expressions which are not really lvalues
    8240              :    but which we can accept as lvalues.
    8241              : 
    8242              :    If ARG is not a kind of expression we can handle, return
    8243              :    NULL_TREE.  */
    8244              : 
    8245              : tree
    8246    301841444 : unary_complex_lvalue (enum tree_code code, tree arg)
    8247              : {
    8248              :   /* Inside a template, making these kinds of adjustments is
    8249              :      pointless; we are only concerned with the type of the
    8250              :      expression.  */
    8251    302235064 :   if (processing_template_decl)
    8252              :     return NULL_TREE;
    8253              : 
    8254              :   /* Handle (a, b) used as an "lvalue".  */
    8255    215252636 :   if (TREE_CODE (arg) == COMPOUND_EXPR)
    8256              :     {
    8257       395023 :       tree real_result = cp_build_unary_op (code, TREE_OPERAND (arg, 1), false,
    8258              :                                             tf_warning_or_error);
    8259       395023 :       return build2 (COMPOUND_EXPR, TREE_TYPE (real_result),
    8260       790046 :                      TREE_OPERAND (arg, 0), real_result);
    8261              :     }
    8262              : 
    8263              :   /* Handle (a ? b : c) used as an "lvalue".  */
    8264    214857613 :   if (TREE_CODE (arg) == COND_EXPR
    8265    214780901 :       || TREE_CODE (arg) == MIN_EXPR || TREE_CODE (arg) == MAX_EXPR)
    8266        76712 :     return rationalize_conditional_expr (code, arg, tf_warning_or_error);
    8267              : 
    8268              :   /* Handle (a = b), (++a), and (--a) used as an "lvalue".  */
    8269    214780901 :   if (TREE_CODE (arg) == MODIFY_EXPR
    8270    214387407 :       || TREE_CODE (arg) == PREINCREMENT_EXPR
    8271    214387344 :       || TREE_CODE (arg) == PREDECREMENT_EXPR)
    8272       393620 :     return unary_complex_lvalue (code, genericize_compound_lvalue (arg));
    8273              : 
    8274    214387281 :   if (code != ADDR_EXPR)
    8275              :     return NULL_TREE;
    8276              : 
    8277              :   /* Handle (a = b) used as an "lvalue" for `&'.  */
    8278    210624939 :   if (TREE_CODE (arg) == MODIFY_EXPR
    8279    210624939 :       || TREE_CODE (arg) == INIT_EXPR)
    8280              :     {
    8281            0 :       tree real_result = cp_build_unary_op (code, TREE_OPERAND (arg, 0), false,
    8282              :                                             tf_warning_or_error);
    8283            0 :       arg = build2 (COMPOUND_EXPR, TREE_TYPE (real_result),
    8284              :                     arg, real_result);
    8285            0 :       suppress_warning (arg /* What warning? */);
    8286            0 :       return arg;
    8287              :     }
    8288              : 
    8289    324367479 :   if (FUNC_OR_METHOD_TYPE_P (TREE_TYPE (arg))
    8290    324366380 :       || TREE_CODE (arg) == OFFSET_REF)
    8291              :     return NULL_TREE;
    8292              : 
    8293              :   /* We permit compiler to make function calls returning
    8294              :      objects of aggregate type look like lvalues.  */
    8295    113741441 :   {
    8296    113741441 :     tree targ = arg;
    8297              : 
    8298    113741441 :     if (TREE_CODE (targ) == SAVE_EXPR)
    8299            0 :       targ = TREE_OPERAND (targ, 0);
    8300              : 
    8301    113741441 :     if (TREE_CODE (targ) == CALL_EXPR && MAYBE_CLASS_TYPE_P (TREE_TYPE (targ)))
    8302              :       {
    8303           26 :         if (TREE_CODE (arg) == SAVE_EXPR)
    8304              :           targ = arg;
    8305              :         else
    8306           26 :           targ = build_cplus_new (TREE_TYPE (arg), arg, tf_warning_or_error);
    8307           26 :         return build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg)), targ);
    8308              :       }
    8309              : 
    8310    113741415 :     if (TREE_CODE (arg) == SAVE_EXPR && INDIRECT_REF_P (targ))
    8311            0 :       return build3 (SAVE_EXPR, build_pointer_type (TREE_TYPE (arg)),
    8312            0 :                      TREE_OPERAND (targ, 0), current_function_decl, NULL);
    8313              :   }
    8314              : 
    8315              :   /* Don't let anything else be handled specially.  */
    8316              :   return NULL_TREE;
    8317              : }
    8318              : 
    8319              : /* Mark EXP saying that we need to be able to take the
    8320              :    address of it; it should not be allocated in a register.
    8321              :    Value is true if successful.  ARRAY_REF_P is true if this
    8322              :    is for ARRAY_REF construction - in that case we don't want
    8323              :    to look through VIEW_CONVERT_EXPR from VECTOR_TYPE to ARRAY_TYPE,
    8324              :    it is fine to use ARRAY_REFs for vector subscripts on vector
    8325              :    register variables.
    8326              : 
    8327              :    C++: we do not allow `current_class_ptr' to be addressable.  */
    8328              : 
    8329              : bool
    8330    352513101 : cxx_mark_addressable (tree exp, bool array_ref_p)
    8331              : {
    8332    352513101 :   tree x = exp;
    8333              : 
    8334    412480488 :   while (1)
    8335    412480488 :     switch (TREE_CODE (x))
    8336              :       {
    8337     29647498 :       case VIEW_CONVERT_EXPR:
    8338     29647498 :         if (array_ref_p
    8339       784469 :             && TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE
    8340     30238535 :             && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (x, 0))))
    8341              :           return true;
    8342     29644440 :         x = TREE_OPERAND (x, 0);
    8343     29644440 :         break;
    8344              : 
    8345     29872565 :       case COMPONENT_REF:
    8346     29872565 :         if (bitfield_p (x))
    8347            9 :           error ("attempt to take address of bit-field");
    8348              :         /* FALLTHRU */
    8349     30322947 :       case ADDR_EXPR:
    8350     30322947 :       case ARRAY_REF:
    8351     30322947 :       case REALPART_EXPR:
    8352     30322947 :       case IMAGPART_EXPR:
    8353     30322947 :         x = TREE_OPERAND (x, 0);
    8354     30322947 :         break;
    8355              : 
    8356      7774438 :       case PARM_DECL:
    8357      7774438 :         if (x == current_class_ptr)
    8358              :           {
    8359           18 :             error ("cannot take the address of %<this%>, which is an rvalue expression");
    8360           18 :             TREE_ADDRESSABLE (x) = 1; /* so compiler doesn't die later.  */
    8361           18 :             return true;
    8362              :           }
    8363              :         /* Fall through.  */
    8364              : 
    8365     70436321 :       case VAR_DECL:
    8366              :         /* Caller should not be trying to mark initialized
    8367              :            constant fields addressable.  */
    8368     70436321 :         gcc_assert (DECL_LANG_SPECIFIC (x) == 0
    8369              :                     || DECL_IN_AGGR_P (x) == 0
    8370              :                     || TREE_STATIC (x)
    8371              :                     || DECL_EXTERNAL (x));
    8372     70436321 :         if (VAR_P (x)
    8373     62661901 :             && DECL_ANON_UNION_VAR_P (x)
    8374     70436404 :             && !TREE_ADDRESSABLE (x))
    8375           39 :           cxx_mark_addressable (DECL_VALUE_EXPR (x));
    8376              :         /* Fall through.  */
    8377              : 
    8378     70590956 :       case RESULT_DECL:
    8379     70591086 :         if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)
    8380     70591077 :             && !DECL_ARTIFICIAL (x))
    8381              :           {
    8382           31 :             if (VAR_P (x) && DECL_HARD_REGISTER (x))
    8383              :               {
    8384           15 :                 error
    8385           15 :                   ("address of explicit register variable %qD requested", x);
    8386           15 :                 return false;
    8387              :               }
    8388           16 :             else if (extra_warnings)
    8389            3 :               warning
    8390            3 :                 (OPT_Wextra, "address requested for %qD, which is declared %<register%>", x);
    8391              :           }
    8392     70590941 :         TREE_ADDRESSABLE (x) = 1;
    8393     70590941 :         return true;
    8394              : 
    8395    172183149 :       case CONST_DECL:
    8396    172183149 :       case FUNCTION_DECL:
    8397    172183149 :         TREE_ADDRESSABLE (x) = 1;
    8398    172183149 :         return true;
    8399              : 
    8400        54014 :       case CONSTRUCTOR:
    8401        54014 :         TREE_ADDRESSABLE (x) = 1;
    8402        54014 :         return true;
    8403              : 
    8404     16454208 :       case TARGET_EXPR:
    8405     16454208 :         TREE_ADDRESSABLE (x) = 1;
    8406     16454208 :         cxx_mark_addressable (TARGET_EXPR_SLOT (x));
    8407     16454208 :         return true;
    8408              : 
    8409              :       default:
    8410              :         return true;
    8411              :     }
    8412              : }
    8413              : 
    8414              : /* Build and return a conditional expression IFEXP ? OP1 : OP2.  */
    8415              : 
    8416              : tree
    8417      9361824 : build_x_conditional_expr (location_t loc, tree ifexp, tree op1, tree op2,
    8418              :                           tsubst_flags_t complain)
    8419              : {
    8420      9361824 :   tree orig_ifexp = ifexp;
    8421      9361824 :   tree orig_op1 = op1;
    8422      9361824 :   tree orig_op2 = op2;
    8423      9361824 :   tree expr;
    8424              : 
    8425      9361824 :   if (processing_template_decl)
    8426              :     {
    8427              :       /* The standard says that the expression is type-dependent if
    8428              :          IFEXP is type-dependent, even though the eventual type of the
    8429              :          expression doesn't dependent on IFEXP.  */
    8430      3370879 :       if (type_dependent_expression_p (ifexp)
    8431              :           /* As a GNU extension, the middle operand may be omitted.  */
    8432      1846930 :           || (op1 && type_dependent_expression_p (op1))
    8433      4721272 :           || type_dependent_expression_p (op2))
    8434      2048237 :         return build_min_nt_loc (loc, COND_EXPR, ifexp, op1, op2);
    8435              :     }
    8436              : 
    8437      7313587 :   expr = build_conditional_expr (loc, ifexp, op1, op2, complain);
    8438      7313587 :   if (processing_template_decl && expr != error_mark_node)
    8439              :     {
    8440      1322636 :       tree min = build_min_non_dep (COND_EXPR, expr,
    8441              :                                     orig_ifexp, orig_op1, orig_op2);
    8442      1322636 :       expr = convert_from_reference (min);
    8443              :     }
    8444              :   return expr;
    8445              : }
    8446              : 
    8447              : /* Given a list of expressions, return a compound expression
    8448              :    that performs them all and returns the value of the last of them.  */
    8449              : 
    8450              : tree
    8451     31082694 : build_x_compound_expr_from_list (tree list, expr_list_kind exp,
    8452              :                                  tsubst_flags_t complain)
    8453              : {
    8454     31082694 :   tree expr = TREE_VALUE (list);
    8455              : 
    8456       468642 :   if (BRACE_ENCLOSED_INITIALIZER_P (expr)
    8457     31551324 :       && !CONSTRUCTOR_IS_DIRECT_INIT (expr))
    8458              :     {
    8459           14 :       if (complain & tf_error)
    8460           28 :         pedwarn (cp_expr_loc_or_input_loc (expr), 0,
    8461              :                  "list-initializer for non-class type must not "
    8462              :                  "be parenthesized");
    8463              :       else
    8464            0 :         return error_mark_node;
    8465              :     }
    8466              : 
    8467     31082694 :   if (TREE_CHAIN (list))
    8468              :     {
    8469           23 :       if (complain & tf_error)
    8470           14 :         switch (exp)
    8471              :           {
    8472           12 :           case ELK_INIT:
    8473           12 :             permerror (input_location, "expression list treated as compound "
    8474              :                                        "expression in initializer");
    8475           12 :             break;
    8476            1 :           case ELK_MEM_INIT:
    8477            1 :             permerror (input_location, "expression list treated as compound "
    8478              :                                        "expression in mem-initializer");
    8479            1 :             break;
    8480            1 :           case ELK_FUNC_CAST:
    8481            1 :             permerror (input_location, "expression list treated as compound "
    8482              :                                        "expression in functional cast");
    8483            1 :             break;
    8484            0 :           default:
    8485            0 :             gcc_unreachable ();
    8486              :           }
    8487              :       else
    8488            9 :         return error_mark_node;
    8489              : 
    8490           28 :       for (list = TREE_CHAIN (list); list; list = TREE_CHAIN (list))
    8491           28 :         expr = build_x_compound_expr (EXPR_LOCATION (TREE_VALUE (list)),
    8492           14 :                                       expr, TREE_VALUE (list), NULL_TREE,
    8493              :                                       complain);
    8494              :     }
    8495              : 
    8496              :   return expr;
    8497              : }
    8498              : 
    8499              : /* Like build_x_compound_expr_from_list, but using a VEC.  */
    8500              : 
    8501              : tree
    8502       395679 : build_x_compound_expr_from_vec (vec<tree, va_gc> *vec, const char *msg,
    8503              :                                 tsubst_flags_t complain)
    8504              : {
    8505       395679 :   if (vec_safe_is_empty (vec))
    8506              :     return NULL_TREE;
    8507       395679 :   else if (vec->length () == 1)
    8508       395615 :     return (*vec)[0];
    8509              :   else
    8510              :     {
    8511           64 :       tree expr;
    8512           64 :       unsigned int ix;
    8513           64 :       tree t;
    8514              : 
    8515           64 :       if (msg != NULL)
    8516              :         {
    8517            4 :           if (complain & tf_error)
    8518            0 :             permerror (input_location,
    8519              :                        "%s expression list treated as compound expression",
    8520              :                        msg);
    8521              :           else
    8522            4 :             return error_mark_node;
    8523              :         }
    8524              : 
    8525           60 :       expr = (*vec)[0];
    8526          134 :       for (ix = 1; vec->iterate (ix, &t); ++ix)
    8527           74 :         expr = build_x_compound_expr (EXPR_LOCATION (t), expr,
    8528              :                                       t, NULL_TREE, complain);
    8529              : 
    8530              :       return expr;
    8531              :     }
    8532              : }
    8533              : 
    8534              : /* Handle overloading of the ',' operator when needed.  */
    8535              : 
    8536              : tree
    8537      3058498 : build_x_compound_expr (location_t loc, tree op1, tree op2,
    8538              :                        tree lookups, tsubst_flags_t complain)
    8539              : {
    8540      3058498 :   tree result;
    8541      3058498 :   tree orig_op1 = op1;
    8542      3058498 :   tree orig_op2 = op2;
    8543      3058498 :   tree overload = NULL_TREE;
    8544              : 
    8545      3058498 :   if (processing_template_decl)
    8546              :     {
    8547      2816805 :       if (type_dependent_expression_p (op1)
    8548      2816805 :           || type_dependent_expression_p (op2))
    8549              :         {
    8550      2554914 :           result = build_min_nt_loc (loc, COMPOUND_EXPR, op1, op2);
    8551      2554914 :           TREE_TYPE (result)
    8552      2554914 :             = build_dependent_operator_type (lookups, COMPOUND_EXPR, false);
    8553      2554914 :           return result;
    8554              :         }
    8555              :     }
    8556              : 
    8557       503584 :   result = build_new_op (loc, COMPOUND_EXPR, LOOKUP_NORMAL, op1, op2,
    8558              :                          NULL_TREE, lookups, &overload, complain);
    8559       503584 :   if (!result)
    8560       495261 :     result = cp_build_compound_expr (op1, op2, complain);
    8561              : 
    8562       503584 :   if (processing_template_decl && result != error_mark_node)
    8563              :     {
    8564       260070 :       if (overload != NULL_TREE)
    8565           72 :         return (build_min_non_dep_op_overload
    8566           72 :                 (COMPOUND_EXPR, result, overload, orig_op1, orig_op2));
    8567              : 
    8568       259998 :       return build_min_non_dep (COMPOUND_EXPR, result, orig_op1, orig_op2);
    8569              :     }
    8570              : 
    8571              :   return result;
    8572              : }
    8573              : 
    8574              : /* Like cp_build_compound_expr, but for the c-common bits.  */
    8575              : 
    8576              : tree
    8577        20168 : build_compound_expr (location_t /*loc*/, tree lhs, tree rhs)
    8578              : {
    8579        20168 :   return cp_build_compound_expr (lhs, rhs, tf_warning_or_error);
    8580              : }
    8581              : 
    8582              : /* Build a compound expression.  */
    8583              : 
    8584              : tree
    8585       650029 : cp_build_compound_expr (tree lhs, tree rhs, tsubst_flags_t complain)
    8586              : {
    8587       650029 :   lhs = convert_to_void (lhs, ICV_LEFT_OF_COMMA, complain);
    8588              : 
    8589       650029 :   if (lhs == error_mark_node || rhs == error_mark_node)
    8590              :     return error_mark_node;
    8591              : 
    8592       650026 :   if (TREE_CODE (lhs) == EXCESS_PRECISION_EXPR)
    8593            0 :     lhs = TREE_OPERAND (lhs, 0);
    8594       650026 :   tree eptype = NULL_TREE;
    8595       650026 :   if (TREE_CODE (rhs) == EXCESS_PRECISION_EXPR)
    8596              :     {
    8597            3 :       eptype = TREE_TYPE (rhs);
    8598            3 :       rhs = TREE_OPERAND (rhs, 0);
    8599              :     }
    8600              : 
    8601       650026 :   if (TREE_CODE (rhs) == TARGET_EXPR)
    8602              :     {
    8603              :       /* If the rhs is a TARGET_EXPR, then build the compound
    8604              :          expression inside the target_expr's initializer. This
    8605              :          helps the compiler to eliminate unnecessary temporaries.  */
    8606        30322 :       tree init = TARGET_EXPR_INITIAL (rhs);
    8607              : 
    8608        30322 :       init = build2 (COMPOUND_EXPR, TREE_TYPE (init), lhs, init);
    8609        30322 :       TARGET_EXPR_INITIAL (rhs) = init;
    8610              : 
    8611        30322 :       if (eptype)
    8612            0 :         rhs = build1 (EXCESS_PRECISION_EXPR, eptype, rhs);
    8613        30322 :       return rhs;
    8614              :     }
    8615              : 
    8616       619704 :   rhs = resolve_nondeduced_context (rhs, complain);
    8617              : 
    8618       619704 :   if (type_unknown_p (rhs))
    8619              :     {
    8620           33 :       if (complain & tf_error)
    8621           51 :         error_at (cp_expr_loc_or_input_loc (rhs),
    8622              :                   "no context to resolve type of %qE", rhs);
    8623           33 :       return error_mark_node;
    8624              :     }
    8625              : 
    8626       619671 :   tree ret = build2 (COMPOUND_EXPR, TREE_TYPE (rhs), lhs, rhs);
    8627       619671 :   if (eptype)
    8628            3 :     ret = build1 (EXCESS_PRECISION_EXPR, eptype, ret);
    8629              :   return ret;
    8630              : }
    8631              : 
    8632              : /* Issue a diagnostic message if casting from SRC_TYPE to DEST_TYPE
    8633              :    casts away constness.  CAST gives the type of cast.  Returns true
    8634              :    if the cast is ill-formed, false if it is well-formed.
    8635              : 
    8636              :    ??? This function warns for casting away any qualifier not just
    8637              :    const.  We would like to specify exactly what qualifiers are casted
    8638              :    away.
    8639              : */
    8640              : 
    8641              : static bool
    8642       827718 : check_for_casting_away_constness (location_t loc, tree src_type,
    8643              :                                   tree dest_type, enum tree_code cast,
    8644              :                                   tsubst_flags_t complain)
    8645              : {
    8646              :   /* C-style casts are allowed to cast away constness.  With
    8647              :      WARN_CAST_QUAL, we still want to issue a warning.  */
    8648       827718 :   if (cast == CAST_EXPR && !warn_cast_qual)
    8649              :     return false;
    8650              : 
    8651       628668 :   if (!casts_away_constness (src_type, dest_type, complain))
    8652              :     return false;
    8653              : 
    8654          400 :   switch (cast)
    8655              :     {
    8656          343 :     case CAST_EXPR:
    8657          343 :       if (complain & tf_warning)
    8658          343 :         warning_at (loc, OPT_Wcast_qual,
    8659              :                     "cast from type %qT to type %qT casts away qualifiers",
    8660              :                     src_type, dest_type);
    8661              :       return false;
    8662              : 
    8663           36 :     case STATIC_CAST_EXPR:
    8664           36 :       if (complain & tf_error)
    8665           24 :         error_at (loc, "%<static_cast%> from type %qT to type %qT casts "
    8666              :                   "away qualifiers",
    8667              :                   src_type, dest_type);
    8668              :       return true;
    8669              : 
    8670           21 :     case REINTERPRET_CAST_EXPR:
    8671           21 :       if (complain & tf_error)
    8672           15 :         error_at (loc, "%<reinterpret_cast%> from type %qT to type %qT "
    8673              :                   "casts away qualifiers",
    8674              :                   src_type, dest_type);
    8675              :       return true;
    8676              : 
    8677            0 :     default:
    8678            0 :       gcc_unreachable();
    8679              :     }
    8680              : }
    8681              : 
    8682              : /* Warns if the cast from expression EXPR to type TYPE is useless.  */
    8683              : void
    8684     49712942 : maybe_warn_about_useless_cast (location_t loc, tree type, tree expr,
    8685              :                                tsubst_flags_t complain)
    8686              : {
    8687     49712942 :   if (warn_useless_cast
    8688          152 :       && complain & tf_warning)
    8689              :     {
    8690          152 :       if (TYPE_REF_P (type)
    8691          152 :           ? ((TYPE_REF_IS_RVALUE (type)
    8692           86 :               ? xvalue_p (expr) : lvalue_p (expr))
    8693          172 :              && same_type_p (TREE_TYPE (expr), TREE_TYPE (type)))
    8694              :           /* Don't warn when converting a class object to a non-reference type,
    8695              :              because that's a common way to create a temporary.  */
    8696           66 :           : (!glvalue_p (expr) && same_type_p (TREE_TYPE (expr), type)))
    8697           96 :         warning_at (loc, OPT_Wuseless_cast,
    8698              :                     "useless cast to type %q#T", type);
    8699              :     }
    8700     49712942 : }
    8701              : 
    8702              : /* Warns if the cast ignores cv-qualifiers on TYPE.  */
    8703              : static void
    8704     49706546 : maybe_warn_about_cast_ignoring_quals (location_t loc, tree type,
    8705              :                                       tsubst_flags_t complain)
    8706              : {
    8707     49706546 :   if (warn_ignored_qualifiers
    8708       274165 :       && complain & tf_warning
    8709       273672 :       && !CLASS_TYPE_P (type)
    8710     49974885 :       && (cp_type_quals (type) & (TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE)))
    8711           36 :     warning_at (loc, OPT_Wignored_qualifiers,
    8712              :                 "type qualifiers ignored on cast result type");
    8713     49706546 : }
    8714              : 
    8715              : /* Convert EXPR (an expression with pointer-to-member type) to TYPE
    8716              :    (another pointer-to-member type in the same hierarchy) and return
    8717              :    the converted expression.  If ALLOW_INVERSE_P is permitted, a
    8718              :    pointer-to-derived may be converted to pointer-to-base; otherwise,
    8719              :    only the other direction is permitted.  If C_CAST_P is true, this
    8720              :    conversion is taking place as part of a C-style cast.  */
    8721              : 
    8722              : tree
    8723        27954 : convert_ptrmem (tree type, tree expr, bool allow_inverse_p,
    8724              :                 bool c_cast_p, tsubst_flags_t complain)
    8725              : {
    8726        27954 :   if (same_type_p (type, TREE_TYPE (expr)))
    8727              :     return expr;
    8728              : 
    8729        27954 :   if (TYPE_PTRDATAMEM_P (type))
    8730              :     {
    8731          398 :       tree obase = TYPE_PTRMEM_CLASS_TYPE (TREE_TYPE (expr));
    8732          398 :       tree nbase = TYPE_PTRMEM_CLASS_TYPE (type);
    8733          398 :       tree delta = (get_delta_difference
    8734          398 :                     (obase, nbase,
    8735              :                      allow_inverse_p, c_cast_p, complain));
    8736              : 
    8737          398 :       if (delta == error_mark_node)
    8738              :         return error_mark_node;
    8739              : 
    8740          392 :       if (!same_type_p (obase, nbase))
    8741              :         {
    8742          299 :           if (TREE_CODE (expr) == PTRMEM_CST)
    8743          157 :             expr = cplus_expand_constant (expr);
    8744              : 
    8745          299 :           tree cond = cp_build_binary_op (input_location, EQ_EXPR, expr,
    8746          299 :                                           build_int_cst (TREE_TYPE (expr), -1),
    8747              :                                           complain);
    8748          299 :           tree op1 = build_nop (ptrdiff_type_node, expr);
    8749          299 :           tree op2 = cp_build_binary_op (input_location, PLUS_EXPR, op1, delta,
    8750              :                                          complain);
    8751              : 
    8752          299 :           expr = fold_build3_loc (input_location,
    8753              :                                   COND_EXPR, ptrdiff_type_node, cond, op1, op2);
    8754              :         }
    8755              : 
    8756          392 :       return build_nop (type, expr);
    8757              :     }
    8758              :   else
    8759        27556 :     return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr,
    8760        27556 :                              allow_inverse_p, c_cast_p, complain);
    8761              : }
    8762              : 
    8763              : /* Perform a static_cast from EXPR to TYPE.  When C_CAST_P is true,
    8764              :    this static_cast is being attempted as one of the possible casts
    8765              :    allowed by a C-style cast.  (In that case, accessibility of base
    8766              :    classes is not considered, and it is OK to cast away
    8767              :    constness.)  Return the result of the cast.  *VALID_P is set to
    8768              :    indicate whether or not the cast was valid.  */
    8769              : 
    8770              : static tree
    8771     49167599 : build_static_cast_1 (location_t loc, tree type, tree expr, bool c_cast_p,
    8772              :                      bool *valid_p, tsubst_flags_t complain)
    8773              : {
    8774     49167599 :   tree intype;
    8775     49167599 :   tree result;
    8776     49167599 :   cp_lvalue_kind clk;
    8777              : 
    8778              :   /* Assume the cast is valid.  */
    8779     49167599 :   *valid_p = true;
    8780              : 
    8781     49167599 :   intype = unlowered_expr_type (expr);
    8782              : 
    8783              :   /* Save casted types in the function's used types hash table.  */
    8784     49167599 :   used_types_insert (type);
    8785              : 
    8786              :   /* A prvalue of non-class type is cv-unqualified.  */
    8787     49167599 :   if (!CLASS_TYPE_P (type))
    8788     46151611 :     type = cv_unqualified (type);
    8789              : 
    8790              :   /* [expr.static.cast]
    8791              : 
    8792              :      An lvalue of type "cv1 B", where B is a class type, can be cast
    8793              :      to type "reference to cv2 D", where D is a class derived (clause
    8794              :      _class.derived_) from B, if a valid standard conversion from
    8795              :      "pointer to D" to "pointer to B" exists (_conv.ptr_), cv2 is the
    8796              :      same cv-qualification as, or greater cv-qualification than, cv1,
    8797              :      and B is not a virtual base class of D.  */
    8798              :   /* We check this case before checking the validity of "TYPE t =
    8799              :      EXPR;" below because for this case:
    8800              : 
    8801              :        struct B {};
    8802              :        struct D : public B { D(const B&); };
    8803              :        extern B& b;
    8804              :        void f() { static_cast<const D&>(b); }
    8805              : 
    8806              :      we want to avoid constructing a new D.  The standard is not
    8807              :      completely clear about this issue, but our interpretation is
    8808              :      consistent with other compilers.  */
    8809     49167599 :   if (TYPE_REF_P (type)
    8810      5503923 :       && CLASS_TYPE_P (TREE_TYPE (type))
    8811      3611045 :       && CLASS_TYPE_P (intype)
    8812      3611028 :       && (TYPE_REF_IS_RVALUE (type) || lvalue_p (expr))
    8813      3598749 :       && DERIVED_FROM_P (intype, TREE_TYPE (type))
    8814      3577611 :       && can_convert (build_pointer_type (TYPE_MAIN_VARIANT (intype)),
    8815      3577611 :                       build_pointer_type (TYPE_MAIN_VARIANT
    8816              :                                           (TREE_TYPE (type))),
    8817              :                       complain)
    8818     52745210 :       && (c_cast_p
    8819      3577587 :           || at_least_as_qualified_p (TREE_TYPE (type), intype)))
    8820              :     {
    8821      3577611 :       tree base;
    8822              : 
    8823      3577611 :       if (processing_template_decl)
    8824              :         return expr;
    8825              : 
    8826              :       /* There is a standard conversion from "D*" to "B*" even if "B"
    8827              :          is ambiguous or inaccessible.  If this is really a
    8828              :          static_cast, then we check both for inaccessibility and
    8829              :          ambiguity.  However, if this is a static_cast being performed
    8830              :          because the user wrote a C-style cast, then accessibility is
    8831              :          not considered.  */
    8832      6697300 :       base = lookup_base (TREE_TYPE (type), intype,
    8833              :                           c_cast_p ? ba_unique : ba_check,
    8834              :                           NULL, complain);
    8835      3348662 :       expr = cp_build_addr_expr (expr, complain);
    8836              : 
    8837      3348662 :       if (sanitize_flags_p (SANITIZE_VPTR))
    8838              :         {
    8839          492 :           tree ubsan_check
    8840          492 :             = cp_ubsan_maybe_instrument_downcast (loc, type,
    8841              :                                                   intype, expr);
    8842          492 :           if (ubsan_check)
    8843      3348662 :             expr = ubsan_check;
    8844              :         }
    8845              : 
    8846              :       /* Convert from "B*" to "D*".  This function will check that "B"
    8847              :          is not a virtual base of "D".  Even if we don't have a guarantee
    8848              :          that expr is NULL, if the static_cast is to a reference type,
    8849              :          it is UB if it would be NULL, so omit the non-NULL check.  */
    8850      3348662 :       expr = build_base_path (MINUS_EXPR, expr, base,
    8851              :                               /*nonnull=*/flag_delete_null_pointer_checks,
    8852              :                               complain);
    8853              : 
    8854              :       /* Convert the pointer to a reference -- but then remember that
    8855              :          there are no expressions with reference type in C++.
    8856              : 
    8857              :          We call rvalue so that there's an actual tree code
    8858              :          (NON_LVALUE_EXPR) for the static_cast; otherwise, if the operand
    8859              :          is a variable with the same type, the conversion would get folded
    8860              :          away, leaving just the variable and causing lvalue_kind to give
    8861              :          the wrong answer.  */
    8862      3348662 :       expr = cp_fold_convert (type, expr);
    8863              : 
    8864              :       /* When -fsanitize=null, make sure to diagnose reference binding to
    8865              :          NULL even when the reference is converted to pointer later on.  */
    8866      3348662 :       if (sanitize_flags_p (SANITIZE_NULL)
    8867          498 :           && TREE_CODE (expr) == COND_EXPR
    8868            6 :           && TREE_OPERAND (expr, 2)
    8869            6 :           && TREE_CODE (TREE_OPERAND (expr, 2)) == INTEGER_CST
    8870      3348668 :           && TREE_TYPE (TREE_OPERAND (expr, 2)) == type)
    8871            6 :         ubsan_maybe_instrument_reference (&TREE_OPERAND (expr, 2));
    8872              : 
    8873      3348662 :       return convert_from_reference (rvalue (expr));
    8874              :     }
    8875              : 
    8876              :   /* "A glvalue of type cv1 T1 can be cast to type rvalue reference to
    8877              :      cv2 T2 if cv2 T2 is reference-compatible with cv1 T1 (8.5.3)."  */
    8878     45589988 :   if (TYPE_REF_P (type)
    8879      1926312 :       && TYPE_REF_IS_RVALUE (type)
    8880       813879 :       && (clk = real_lvalue_p (expr))
    8881       802518 :       && reference_compatible_p (TREE_TYPE (type), intype)
    8882     46392499 :       && (c_cast_p || at_least_as_qualified_p (TREE_TYPE (type), intype)))
    8883              :     {
    8884       802511 :       if (processing_template_decl)
    8885              :         return expr;
    8886       802015 :       if (clk == clk_ordinary)
    8887              :         {
    8888              :           /* Handle the (non-bit-field) lvalue case here by casting to
    8889              :              lvalue reference and then changing it to an rvalue reference.
    8890              :              Casting an xvalue to rvalue reference will be handled by the
    8891              :              main code path.  */
    8892       802012 :           tree lref = cp_build_reference_type (TREE_TYPE (type), false);
    8893       802012 :           result = (perform_direct_initialization_if_possible
    8894       802012 :                     (lref, expr, c_cast_p, complain));
    8895       802012 :           result = build1 (NON_LVALUE_EXPR, type, result);
    8896       802012 :           return convert_from_reference (result);
    8897              :         }
    8898              :       else
    8899              :         /* For a bit-field or packed field, bind to a temporary.  */
    8900            3 :         expr = rvalue (expr);
    8901              :     }
    8902              : 
    8903              :   /* Resolve overloaded address here rather than once in
    8904              :      implicit_conversion and again in the inverse code below.  */
    8905     44787480 :   if (TYPE_PTRMEMFUNC_P (type) && type_unknown_p (expr))
    8906              :     {
    8907           21 :       expr = instantiate_type (type, expr, complain);
    8908           21 :       intype = TREE_TYPE (expr);
    8909              :     }
    8910              : 
    8911              :   /* [expr.static.cast]
    8912              : 
    8913              :      Any expression can be explicitly converted to type cv void.  */
    8914     44787480 :   if (VOID_TYPE_P (type))
    8915              :     {
    8916       552742 :       if (TREE_CODE (expr) == EXCESS_PRECISION_EXPR)
    8917            0 :         expr = TREE_OPERAND (expr, 0);
    8918       552742 :       return convert_to_void (expr, ICV_CAST, complain);
    8919              :     }
    8920              : 
    8921              :   /* [class.abstract]
    8922              :      An abstract class shall not be used ... as the type of an explicit
    8923              :      conversion.  */
    8924     44234738 :   if (abstract_virtuals_error (ACU_CAST, type, complain))
    8925            6 :     return error_mark_node;
    8926              : 
    8927              :   /* [expr.static.cast]
    8928              : 
    8929              :      An expression e can be explicitly converted to a type T using a
    8930              :      static_cast of the form static_cast<T>(e) if the declaration T
    8931              :      t(e);" is well-formed, for some invented temporary variable
    8932              :      t.  */
    8933     44234732 :   result = perform_direct_initialization_if_possible (type, expr,
    8934              :                                                       c_cast_p, complain);
    8935              :   /* P1975 allows static_cast<Aggr>(42), as well as static_cast<T[5]>(42),
    8936              :      which initialize the first element of the aggregate.  We need to handle
    8937              :      the array case specifically.  */
    8938     44234732 :   if (result == NULL_TREE
    8939      4557799 :       && cxx_dialect >= cxx20
    8940      3230619 :       && TREE_CODE (type) == ARRAY_TYPE)
    8941              :     {
    8942              :       /* Create { EXPR } and perform direct-initialization from it.  */
    8943           15 :       tree e = build_constructor_single (init_list_type_node, NULL_TREE, expr);
    8944           15 :       CONSTRUCTOR_IS_DIRECT_INIT (e) = true;
    8945           15 :       CONSTRUCTOR_IS_PAREN_INIT (e) = true;
    8946           15 :       result = perform_direct_initialization_if_possible (type, e, c_cast_p,
    8947              :                                                           complain);
    8948              :     }
    8949      4557799 :   if (result)
    8950              :     {
    8951     39676948 :       if (processing_template_decl)
    8952              :         return expr;
    8953              : 
    8954     38995697 :       result = convert_from_reference (result);
    8955              : 
    8956              :       /* [expr.static.cast]
    8957              : 
    8958              :          If T is a reference type, the result is an lvalue; otherwise,
    8959              :          the result is an rvalue.  */
    8960     38995697 :       if (!TYPE_REF_P (type))
    8961              :         {
    8962     37871990 :           result = rvalue (result);
    8963              : 
    8964     37871990 :           if (result == expr && SCALAR_TYPE_P (type))
    8965              :             /* Leave some record of the cast.  */
    8966      2314948 :             result = build_nop (type, expr);
    8967              :         }
    8968     38995697 :       return result;
    8969              :     }
    8970              : 
    8971              :   /* [expr.static.cast]
    8972              : 
    8973              :      The inverse of any standard conversion sequence (clause _conv_),
    8974              :      other than the lvalue-to-rvalue (_conv.lval_), array-to-pointer
    8975              :      (_conv.array_), function-to-pointer (_conv.func_), and boolean
    8976              :      (_conv.bool_) conversions, can be performed explicitly using
    8977              :      static_cast subject to the restriction that the explicit
    8978              :      conversion does not cast away constness (_expr.const.cast_), and
    8979              :      the following additional rules for specific cases:  */
    8980              :   /* For reference, the conversions not excluded are: integral
    8981              :      promotions, floating-point promotion, integral conversions,
    8982              :      floating-point conversions, floating-integral conversions,
    8983              :      pointer conversions, and pointer to member conversions.  */
    8984              :   /* DR 128
    8985              : 
    8986              :      A value of integral _or enumeration_ type can be explicitly
    8987              :      converted to an enumeration type.  */
    8988              :   /* The effect of all that is that any conversion between any two
    8989              :      types which are integral, floating, or enumeration types can be
    8990              :      performed.  */
    8991      4557784 :   if ((INTEGRAL_OR_ENUMERATION_TYPE_P (type)
    8992      2513214 :        || SCALAR_FLOAT_TYPE_P (type))
    8993      2134565 :       && (INTEGRAL_OR_ENUMERATION_TYPE_P (intype)
    8994       188913 :           || SCALAR_FLOAT_TYPE_P (intype)))
    8995              :     {
    8996      2035635 :       if (processing_template_decl)
    8997              :         return expr;
    8998      1947246 :       if (TREE_CODE (expr) == EXCESS_PRECISION_EXPR)
    8999            0 :         expr = TREE_OPERAND (expr, 0);
    9000              :       /* [expr.static.cast]: "If the value is not a bit-field, the result
    9001              :          refers to the object or the specified base class subobject thereof;
    9002              :          otherwise, the lvalue-to-rvalue conversion is applied to the
    9003              :          bit-field and the resulting prvalue is used as the operand of the
    9004              :          static_cast."  There are no prvalue bit-fields; the l-to-r conversion
    9005              :          will give us an object of the underlying type of the bit-field.  */
    9006      1947246 :       expr = decay_conversion (expr, complain);
    9007      1947246 :       return ocp_convert (type, expr, CONV_C_CAST, LOOKUP_NORMAL, complain);
    9008              :     }
    9009              : 
    9010       781360 :   if (TYPE_PTR_P (type) && TYPE_PTR_P (intype)
    9011       776872 :       && CLASS_TYPE_P (TREE_TYPE (type))
    9012       181194 :       && CLASS_TYPE_P (TREE_TYPE (intype))
    9013      2554616 :       && can_convert (build_pointer_type (TYPE_MAIN_VARIANT
    9014              :                                           (TREE_TYPE (intype))),
    9015        32467 :                       build_pointer_type (TYPE_MAIN_VARIANT
    9016              :                                           (TREE_TYPE (type))),
    9017              :                       complain))
    9018              :     {
    9019        32128 :       tree base;
    9020              : 
    9021        32128 :       if (processing_template_decl)
    9022              :         return expr;
    9023              : 
    9024        32110 :       if (!c_cast_p
    9025        32110 :           && check_for_casting_away_constness (loc, intype, type,
    9026              :                                                STATIC_CAST_EXPR,
    9027              :                                                complain))
    9028            6 :         return error_mark_node;
    9029        63669 :       base = lookup_base (TREE_TYPE (type), TREE_TYPE (intype),
    9030              :                           c_cast_p ? ba_unique : ba_check,
    9031              :                           NULL, complain);
    9032        32104 :       expr = build_base_path (MINUS_EXPR, expr, base, /*nonnull=*/false,
    9033              :                               complain);
    9034              : 
    9035        32104 :       if (sanitize_flags_p (SANITIZE_VPTR))
    9036              :         {
    9037           43 :           tree ubsan_check
    9038           43 :             = cp_ubsan_maybe_instrument_downcast (loc, type,
    9039              :                                                   intype, expr);
    9040           43 :           if (ubsan_check)
    9041        32104 :             expr = ubsan_check;
    9042              :         }
    9043              : 
    9044        32104 :       return cp_fold_convert (type, expr);
    9045              :     }
    9046              : 
    9047           89 :   if ((TYPE_PTRDATAMEM_P (type) && TYPE_PTRDATAMEM_P (intype))
    9048      2490021 :       || (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype)))
    9049              :     {
    9050          232 :       tree c1;
    9051          232 :       tree c2;
    9052          232 :       tree t1;
    9053          232 :       tree t2;
    9054              : 
    9055          232 :       c1 = TYPE_PTRMEM_CLASS_TYPE (intype);
    9056          232 :       c2 = TYPE_PTRMEM_CLASS_TYPE (type);
    9057              : 
    9058          232 :       if (TYPE_PTRDATAMEM_P (type))
    9059              :         {
    9060           89 :           t1 = (build_ptrmem_type
    9061           89 :                 (c1,
    9062           89 :                  TYPE_MAIN_VARIANT (TYPE_PTRMEM_POINTED_TO_TYPE (intype))));
    9063           89 :           t2 = (build_ptrmem_type
    9064           89 :                 (c2,
    9065           89 :                  TYPE_MAIN_VARIANT (TYPE_PTRMEM_POINTED_TO_TYPE (type))));
    9066              :         }
    9067              :       else
    9068              :         {
    9069              :           t1 = intype;
    9070              :           t2 = type;
    9071              :         }
    9072          232 :       if (can_convert (t1, t2, complain) || can_convert (t2, t1, complain))
    9073              :         {
    9074          154 :           if (!c_cast_p
    9075          154 :               && check_for_casting_away_constness (loc, intype, type,
    9076              :                                                    STATIC_CAST_EXPR,
    9077              :                                                    complain))
    9078            9 :             return error_mark_node;
    9079          145 :           if (processing_template_decl)
    9080              :             return expr;
    9081          145 :           return convert_ptrmem (type, expr, /*allow_inverse_p=*/1,
    9082          145 :                                  c_cast_p, complain);
    9083              :         }
    9084              :     }
    9085              : 
    9086              :   /* [expr.static.cast]
    9087              : 
    9088              :      An rvalue of type "pointer to cv void" can be explicitly
    9089              :      converted to a pointer to object type.  A value of type pointer
    9090              :      to object converted to "pointer to cv void" and back to the
    9091              :      original pointer type will have its original value.  */
    9092      2489867 :   if (TYPE_PTR_P (intype)
    9093       841505 :       && VOID_TYPE_P (TREE_TYPE (intype))
    9094      3199181 :       && TYPE_PTROB_P (type))
    9095              :     {
    9096       677068 :       if (!c_cast_p
    9097       677068 :           && check_for_casting_away_constness (loc, intype, type,
    9098              :                                                STATIC_CAST_EXPR,
    9099              :                                                complain))
    9100           21 :         return error_mark_node;
    9101       677047 :       if (processing_template_decl)
    9102              :         return expr;
    9103       595379 :       return build_nop (type, expr);
    9104              :     }
    9105              : 
    9106      1812799 :   *valid_p = false;
    9107      1812799 :   return error_mark_node;
    9108              : }
    9109              : 
    9110              : /* Return an expression representing static_cast<TYPE>(EXPR).  */
    9111              : 
    9112              : tree
    9113     16768442 : build_static_cast (location_t loc, tree type, tree oexpr,
    9114              :                    tsubst_flags_t complain)
    9115              : {
    9116     16768442 :   tree expr = oexpr;
    9117     16768442 :   tree result;
    9118     16768442 :   bool valid_p;
    9119              : 
    9120     16768442 :   if (type == error_mark_node || expr == error_mark_node)
    9121              :     return error_mark_node;
    9122              : 
    9123     16768267 :   bool dependent = (dependent_type_p (type)
    9124     16768267 :                     || type_dependent_expression_p (expr));
    9125     11691651 :   if (dependent)
    9126              :     {
    9127      6157424 :     tmpl:
    9128      6157424 :       expr = build_min (STATIC_CAST_EXPR, type, oexpr);
    9129              :       /* We don't know if it will or will not have side effects.  */
    9130      6157424 :       TREE_SIDE_EFFECTS (expr) = 1;
    9131      6157424 :       result = convert_from_reference (expr);
    9132      6157424 :       protected_set_expr_location (result, loc);
    9133      6157424 :       return result;
    9134              :     }
    9135              : 
    9136              :   /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
    9137              :      Strip such NOP_EXPRs if VALUE is being used in non-lvalue context.  */
    9138     11691651 :   if (!TYPE_REF_P (type)
    9139      6188824 :       && TREE_CODE (expr) == NOP_EXPR
    9140     11798495 :       && TREE_TYPE (expr) == TREE_TYPE (TREE_OPERAND (expr, 0)))
    9141           67 :     expr = TREE_OPERAND (expr, 0);
    9142              : 
    9143     11691651 :   result = build_static_cast_1 (loc, type, expr, /*c_cast_p=*/false,
    9144              :                                 &valid_p, complain);
    9145     11691651 :   if (valid_p)
    9146              :     {
    9147     11691455 :       if (result != error_mark_node)
    9148              :         {
    9149     11691350 :           maybe_warn_about_useless_cast (loc, type, expr, complain);
    9150     11691350 :           maybe_warn_about_cast_ignoring_quals (loc, type, complain);
    9151              :         }
    9152     11691455 :       if (processing_template_decl)
    9153      1080808 :         goto tmpl;
    9154     10610647 :       protected_set_expr_location (result, loc);
    9155     10610647 :       return result;
    9156              :     }
    9157              : 
    9158          196 :   if (complain & tf_error)
    9159              :     {
    9160          163 :       auto_diagnostic_group d;
    9161          163 :       error_at (loc, "invalid %<static_cast%> from type %qT to type %qT",
    9162          163 :                 TREE_TYPE (expr), type);
    9163          163 :       if ((TYPE_PTR_P (type) || TYPE_REF_P (type))
    9164          121 :           && CLASS_TYPE_P (TREE_TYPE (type))
    9165          192 :             && !COMPLETE_TYPE_P (TREE_TYPE (type)))
    9166           17 :         inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (TREE_TYPE (type))),
    9167           17 :                 "class type %qT is incomplete", TREE_TYPE (type));
    9168          163 :       tree expr_type = TREE_TYPE (expr);
    9169          163 :       if (TYPE_PTR_P (expr_type))
    9170           35 :         expr_type = TREE_TYPE (expr_type);
    9171          163 :       if (CLASS_TYPE_P (expr_type) && !COMPLETE_TYPE_P (expr_type))
    9172           12 :         inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (expr_type)),
    9173              :                 "class type %qT is incomplete", expr_type);
    9174          163 :     }
    9175          196 :   return error_mark_node;
    9176              : }
    9177              : 
    9178              : /* EXPR is an expression with member function or pointer-to-member
    9179              :    function type.  TYPE is a pointer type.  Converting EXPR to TYPE is
    9180              :    not permitted by ISO C++, but we accept it in some modes.  If we
    9181              :    are not in one of those modes, issue a diagnostic.  Return the
    9182              :    converted expression.  */
    9183              : 
    9184              : tree
    9185          165 : convert_member_func_to_ptr (tree type, tree expr, tsubst_flags_t complain)
    9186              : {
    9187          165 :   tree intype;
    9188          165 :   tree decl;
    9189              : 
    9190          165 :   intype = TREE_TYPE (expr);
    9191          165 :   gcc_assert (TYPE_PTRMEMFUNC_P (intype)
    9192              :               || TREE_CODE (intype) == METHOD_TYPE);
    9193              : 
    9194          165 :   if (!(complain & tf_warning_or_error))
    9195            0 :     return error_mark_node;
    9196              : 
    9197          165 :   location_t loc = cp_expr_loc_or_input_loc (expr);
    9198              : 
    9199          165 :   if (pedantic || warn_pmf2ptr)
    9200          207 :     pedwarn (loc, pedantic ? OPT_Wpedantic : OPT_Wpmf_conversions,
    9201              :              "converting from %qH to %qI", intype, type);
    9202              : 
    9203          165 :   STRIP_ANY_LOCATION_WRAPPER (expr);
    9204              : 
    9205          165 :   if (TREE_CODE (intype) == METHOD_TYPE)
    9206           72 :     expr = build_addr_func (expr, complain);
    9207           93 :   else if (TREE_CODE (expr) == PTRMEM_CST)
    9208           75 :     expr = build_address (PTRMEM_CST_MEMBER (expr));
    9209              :   else
    9210              :     {
    9211           18 :       decl = maybe_dummy_object (TYPE_PTRMEM_CLASS_TYPE (intype), 0);
    9212           18 :       decl = build_address (decl);
    9213           18 :       expr = get_member_function_from_ptrfunc (&decl, expr, complain);
    9214              :     }
    9215              : 
    9216          165 :   if (expr == error_mark_node)
    9217              :     return error_mark_node;
    9218              : 
    9219          165 :   expr = build_nop (type, expr);
    9220          165 :   SET_EXPR_LOCATION (expr, loc);
    9221          165 :   return expr;
    9222              : }
    9223              : 
    9224              : /* Build a NOP_EXPR to TYPE, but mark it as a reinterpret_cast so that
    9225              :    constexpr evaluation knows to reject it.  */
    9226              : 
    9227              : static tree
    9228       111215 : build_nop_reinterpret (tree type, tree expr)
    9229              : {
    9230       111215 :   tree ret = build_nop (type, expr);
    9231       111215 :   if (ret != expr)
    9232       111215 :     REINTERPRET_CAST_P (ret) = true;
    9233       111215 :   return ret;
    9234              : }
    9235              : 
    9236              : /* Return a representation for a reinterpret_cast from EXPR to TYPE.
    9237              :    If C_CAST_P is true, this reinterpret cast is being done as part of
    9238              :    a C-style cast.  If VALID_P is non-NULL, *VALID_P is set to
    9239              :    indicate whether or not reinterpret_cast was valid.  */
    9240              : 
    9241              : static tree
    9242      1960006 : build_reinterpret_cast_1 (location_t loc, tree type, tree expr,
    9243              :                           bool c_cast_p, bool *valid_p,
    9244              :                           tsubst_flags_t complain)
    9245              : {
    9246      1960006 :   tree intype;
    9247              : 
    9248              :   /* Assume the cast is invalid.  */
    9249      1960006 :   if (valid_p)
    9250      1812659 :     *valid_p = true;
    9251              : 
    9252      1960006 :   if (type == error_mark_node || error_operand_p (expr))
    9253              :     return error_mark_node;
    9254              : 
    9255      1960006 :   intype = TREE_TYPE (expr);
    9256              : 
    9257              :   /* Save casted types in the function's used types hash table.  */
    9258      1960006 :   used_types_insert (type);
    9259              : 
    9260              :   /* A prvalue of non-class type is cv-unqualified.  */
    9261      1960006 :   if (!CLASS_TYPE_P (type))
    9262      1959997 :     type = cv_unqualified (type);
    9263              : 
    9264              :   /* [expr.reinterpret.cast]
    9265              :      A glvalue of type T1, designating an object x, can be cast to the type
    9266              :      "reference to T2" if an expression of type "pointer to T1" can be
    9267              :      explicitly converted to the type "pointer to T2" using a reinterpret_cast.
    9268              :      The result is that of *reinterpret_cast<T2 *>(p) where p is a pointer to x
    9269              :      of type "pointer to T1". No temporary is created, no copy is made, and no
    9270              :      constructors (11.4.4) or conversion functions (11.4.7) are called.  */
    9271      1960006 :   if (TYPE_REF_P (type))
    9272              :     {
    9273         9485 :       if (!glvalue_p (expr))
    9274              :         {
    9275            9 :           if (complain & tf_error)
    9276            9 :             error_at (loc, "invalid cast of a prvalue expression of type "
    9277              :                       "%qT to type %qT",
    9278              :                       intype, type);
    9279            9 :           return error_mark_node;
    9280              :         }
    9281              : 
    9282              :       /* Warn about a reinterpret_cast from "A*" to "B&" if "A" and
    9283              :          "B" are related class types; the reinterpret_cast does not
    9284              :          adjust the pointer.  */
    9285         9476 :       if (TYPE_PTR_P (intype)
    9286            3 :           && (complain & tf_warning)
    9287         9479 :           && (comptypes (TREE_TYPE (intype), TREE_TYPE (type),
    9288              :                          COMPARE_BASE | COMPARE_DERIVED)))
    9289            3 :         warning_at (loc, 0, "casting %qT to %qT does not dereference pointer",
    9290              :                     intype, type);
    9291              : 
    9292         9476 :       expr = cp_build_addr_expr (expr, complain);
    9293              : 
    9294         9476 :       if (warn_strict_aliasing > 2)
    9295           72 :         cp_strict_aliasing_warning (EXPR_LOCATION (expr), type, expr);
    9296              : 
    9297         9476 :       if (expr != error_mark_node)
    9298         9476 :         expr = build_reinterpret_cast_1
    9299         9476 :           (loc, build_pointer_type (TREE_TYPE (type)), expr, c_cast_p,
    9300              :            valid_p, complain);
    9301         9476 :       if (expr != error_mark_node)
    9302              :         /* cp_build_indirect_ref isn't right for rvalue refs.  */
    9303         9473 :         expr = convert_from_reference (fold_convert (type, expr));
    9304         9476 :       return expr;
    9305              :     }
    9306              : 
    9307              :   /* As a G++ extension, we consider conversions from member
    9308              :      functions, and pointers to member functions to
    9309              :      pointer-to-function and pointer-to-void types.  If
    9310              :      -Wno-pmf-conversions has not been specified,
    9311              :      convert_member_func_to_ptr will issue an error message.  */
    9312          250 :   if ((TYPE_PTRMEMFUNC_P (intype)
    9313      1950349 :        || TREE_CODE (intype) == METHOD_TYPE)
    9314          244 :       && TYPE_PTR_P (type)
    9315      1950686 :       && (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE
    9316          123 :           || VOID_TYPE_P (TREE_TYPE (type))))
    9317          156 :     return convert_member_func_to_ptr (type, expr, complain);
    9318              : 
    9319              :   /* If the cast is not to a reference type, the lvalue-to-rvalue,
    9320              :      array-to-pointer, and function-to-pointer conversions are
    9321              :      performed.  */
    9322      1950365 :   expr = decay_conversion (expr, complain);
    9323              : 
    9324              :   /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
    9325              :      Strip such NOP_EXPRs if VALUE is being used in non-lvalue context.  */
    9326      1950365 :   if (TREE_CODE (expr) == NOP_EXPR
    9327      1950365 :       && TREE_TYPE (expr) == TREE_TYPE (TREE_OPERAND (expr, 0)))
    9328          388 :     expr = TREE_OPERAND (expr, 0);
    9329              : 
    9330      1950365 :   if (error_operand_p (expr))
    9331           30 :     return error_mark_node;
    9332              : 
    9333      1950335 :   intype = TREE_TYPE (expr);
    9334              : 
    9335              :   /* [expr.reinterpret.cast]
    9336              :      A pointer can be converted to any integral type large enough to
    9337              :      hold it. ... A value of type std::nullptr_t can be converted to
    9338              :      an integral type; the conversion has the same meaning and
    9339              :      validity as a conversion of (void*)0 to the integral type.  */
    9340      1950335 :   if (CP_INTEGRAL_TYPE_P (type)
    9341       162718 :       && (TYPE_PTR_P (intype) || NULLPTR_TYPE_P (intype)))
    9342              :     {
    9343       160799 :       if (TYPE_PRECISION (type) < TYPE_PRECISION (intype))
    9344              :         {
    9345           21 :           if (complain & tf_error)
    9346           15 :             permerror (loc, "cast from %qH to %qI loses precision",
    9347              :                        intype, type);
    9348              :           else
    9349            6 :             return error_mark_node;
    9350              :         }
    9351       160793 :       if (NULLPTR_TYPE_P (intype))
    9352           98 :         return build_int_cst (type, 0);
    9353              :     }
    9354              :   /* [expr.reinterpret.cast]
    9355              :      A value of integral or enumeration type can be explicitly
    9356              :      converted to a pointer.  */
    9357      1789536 :   else if (TYPE_PTR_P (type) && INTEGRAL_OR_ENUMERATION_TYPE_P (intype))
    9358              :     /* OK */
    9359              :     ;
    9360      1755899 :   else if ((INTEGRAL_OR_ENUMERATION_TYPE_P (type)
    9361      1753965 :             || TYPE_PTR_OR_PTRMEM_P (type))
    9362      1867625 :            && same_type_p (type, intype))
    9363              :     /* DR 799 */
    9364          479 :     return rvalue (expr);
    9365      1755420 :   else if (TYPE_PTRFN_P (type) && TYPE_PTRFN_P (intype))
    9366              :     {
    9367          266 :       if ((complain & tf_warning)
    9368          532 :           && !cxx_safe_function_type_cast_p (TREE_TYPE (type),
    9369          266 :                                              TREE_TYPE (intype)))
    9370          145 :         warning_at (loc, OPT_Wcast_function_type,
    9371              :                     "cast between incompatible function types"
    9372              :                     " from %qH to %qI", intype, type);
    9373          266 :       return build_nop_reinterpret (type, expr);
    9374              :     }
    9375      1755154 :   else if (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype))
    9376              :     {
    9377           79 :       if ((complain & tf_warning)
    9378          158 :           && !cxx_safe_function_type_cast_p
    9379           79 :                 (TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE_RAW (type)),
    9380           79 :                  TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE_RAW (intype))))
    9381           52 :         warning_at (loc, OPT_Wcast_function_type,
    9382              :                     "cast between incompatible pointer to member types"
    9383              :                     " from %qH to %qI", intype, type);
    9384           79 :       return build_nop_reinterpret (type, expr);
    9385              :     }
    9386           21 :   else if ((TYPE_PTRDATAMEM_P (type) && TYPE_PTRDATAMEM_P (intype))
    9387      1755075 :            || (TYPE_PTROBV_P (type) && TYPE_PTROBV_P (intype)))
    9388              :     {
    9389       110615 :       if (!c_cast_p
    9390       110615 :           && check_for_casting_away_constness (loc, intype, type,
    9391              :                                                REINTERPRET_CAST_EXPR,
    9392              :                                                complain))
    9393           21 :         return error_mark_node;
    9394              :       /* Warn about possible alignment problems.  */
    9395       110594 :       if ((STRICT_ALIGNMENT || warn_cast_align == 2)
    9396           24 :           && (complain & tf_warning)
    9397           24 :           && !VOID_TYPE_P (type)
    9398           24 :           && TREE_CODE (TREE_TYPE (intype)) != FUNCTION_TYPE
    9399           24 :           && COMPLETE_TYPE_P (TREE_TYPE (type))
    9400           24 :           && COMPLETE_TYPE_P (TREE_TYPE (intype))
    9401       110642 :           && min_align_of_type (TREE_TYPE (type))
    9402           24 :              > min_align_of_type (TREE_TYPE (intype)))
    9403           18 :         warning_at (loc, OPT_Wcast_align, "cast from %qH to %qI "
    9404              :                     "increases required alignment of target type",
    9405              :                     intype, type);
    9406              : 
    9407       110594 :       if (warn_strict_aliasing <= 2)
    9408              :         /* strict_aliasing_warning STRIP_NOPs its expr.  */
    9409        98760 :         cp_strict_aliasing_warning (EXPR_LOCATION (expr), type, expr);
    9410              : 
    9411       110594 :       return build_nop_reinterpret (type, expr);
    9412              :     }
    9413          297 :   else if ((TYPE_PTRFN_P (type) && TYPE_PTROBV_P (intype))
    9414      1644620 :            || (TYPE_PTRFN_P (intype) && TYPE_PTROBV_P (type)))
    9415              :     {
    9416          276 :       if (complain & tf_warning)
    9417              :         /* C++11 5.2.10 p8 says that "Converting a function pointer to an
    9418              :            object pointer type or vice versa is conditionally-supported."  */
    9419          276 :         warning_at (loc, OPT_Wconditionally_supported,
    9420              :                     "casting between pointer-to-function and "
    9421              :                     "pointer-to-object is conditionally-supported");
    9422          276 :       return build_nop_reinterpret (type, expr);
    9423              :     }
    9424      1644184 :   else if (gnu_vector_type_p (type) && scalarish_type_p (intype))
    9425      1642215 :     return convert_to_vector (type, rvalue (expr));
    9426         1969 :   else if (gnu_vector_type_p (intype)
    9427         1969 :            && INTEGRAL_OR_ENUMERATION_TYPE_P (type))
    9428         1867 :     return convert_to_integer_nofold (type, expr);
    9429              :   else
    9430              :     {
    9431          102 :       if (valid_p)
    9432           84 :         *valid_p = false;
    9433          102 :       if (complain & tf_error)
    9434           93 :         error_at (loc, "invalid cast from type %qT to type %qT",
    9435              :                   intype, type);
    9436          102 :       return error_mark_node;
    9437              :     }
    9438              : 
    9439       194332 :   expr = cp_convert (type, expr, complain);
    9440       194332 :   if (TREE_CODE (expr) == NOP_EXPR)
    9441              :     /* Mark any nop_expr that created as a reintepret_cast.  */
    9442            0 :     REINTERPRET_CAST_P (expr) = true;
    9443              :   return expr;
    9444              : }
    9445              : 
    9446              : tree
    9447       731805 : build_reinterpret_cast (location_t loc, tree type, tree expr,
    9448              :                         tsubst_flags_t complain)
    9449              : {
    9450       731805 :   tree r;
    9451              : 
    9452       731805 :   if (type == error_mark_node || expr == error_mark_node)
    9453              :     return error_mark_node;
    9454              : 
    9455       731798 :   if (processing_template_decl)
    9456              :     {
    9457       593871 :       tree t = build_min (REINTERPRET_CAST_EXPR, type, expr);
    9458              : 
    9459       593871 :       if (!TREE_SIDE_EFFECTS (t)
    9460       593871 :           && type_dependent_expression_p (expr))
    9461              :         /* There might turn out to be side effects inside expr.  */
    9462       281151 :         TREE_SIDE_EFFECTS (t) = 1;
    9463       593871 :       r = convert_from_reference (t);
    9464       593871 :       protected_set_expr_location (r, loc);
    9465       593871 :       return r;
    9466              :     }
    9467              : 
    9468       137927 :   r = build_reinterpret_cast_1 (loc, type, expr, /*c_cast_p=*/false,
    9469              :                                 /*valid_p=*/NULL, complain);
    9470       137927 :   if (r != error_mark_node)
    9471              :     {
    9472       137864 :       maybe_warn_about_useless_cast (loc, type, expr, complain);
    9473       137864 :       maybe_warn_about_cast_ignoring_quals (loc, type, complain);
    9474              :     }
    9475       137927 :   protected_set_expr_location (r, loc);
    9476       137927 :   return r;
    9477              : }
    9478              : 
    9479              : /* Perform a const_cast from EXPR to TYPE.  If the cast is valid,
    9480              :    return an appropriate expression.  Otherwise, return
    9481              :    error_mark_node.  If the cast is not valid, and COMPLAIN is true,
    9482              :    then a diagnostic will be issued.  If VALID_P is non-NULL, we are
    9483              :    performing a C-style cast, its value upon return will indicate
    9484              :    whether or not the conversion succeeded.  */
    9485              : 
    9486              : static tree
    9487     37877835 : build_const_cast_1 (location_t loc, tree dst_type, tree expr,
    9488              :                     tsubst_flags_t complain, bool *valid_p)
    9489              : {
    9490     37877835 :   tree src_type;
    9491     37877835 :   tree reference_type;
    9492              : 
    9493              :   /* Callers are responsible for handling error_mark_node as a
    9494              :      destination type.  */
    9495     37877835 :   gcc_assert (dst_type != error_mark_node);
    9496              :   /* In a template, callers should be building syntactic
    9497              :      representations of casts, not using this machinery.  */
    9498     37877835 :   gcc_assert (!processing_template_decl);
    9499              : 
    9500              :   /* Assume the conversion is invalid.  */
    9501     37877835 :   if (valid_p)
    9502     37660875 :     *valid_p = false;
    9503              : 
    9504     37877835 :   if (!INDIRECT_TYPE_P (dst_type) && !TYPE_PTRDATAMEM_P (dst_type))
    9505              :     {
    9506     36817048 :       if (complain & tf_error)
    9507            9 :         error_at (loc, "invalid use of %<const_cast%> with type %qT, "
    9508              :                   "which is not a pointer, reference, "
    9509              :                   "nor a pointer-to-data-member type", dst_type);
    9510     36817048 :       return error_mark_node;
    9511              :     }
    9512              : 
    9513      1060787 :   if (TREE_CODE (TREE_TYPE (dst_type)) == FUNCTION_TYPE)
    9514              :     {
    9515         4173 :       if (complain & tf_error)
    9516            6 :         error_at (loc, "invalid use of %<const_cast%> with type %qT, "
    9517              :                   "which is a pointer or reference to a function type",
    9518              :                   dst_type);
    9519         4173 :        return error_mark_node;
    9520              :     }
    9521              : 
    9522              :   /* A prvalue of non-class type is cv-unqualified.  */
    9523      1056614 :   dst_type = cv_unqualified (dst_type);
    9524              : 
    9525              :   /* Save casted types in the function's used types hash table.  */
    9526      1056614 :   used_types_insert (dst_type);
    9527              : 
    9528      1056614 :   src_type = TREE_TYPE (expr);
    9529              :   /* Expressions do not really have reference types.  */
    9530      1056614 :   if (TYPE_REF_P (src_type))
    9531            0 :     src_type = TREE_TYPE (src_type);
    9532              : 
    9533              :   /* [expr.const.cast]
    9534              : 
    9535              :      For two object types T1 and T2, if a pointer to T1 can be explicitly
    9536              :      converted to the type "pointer to T2" using a const_cast, then the
    9537              :      following conversions can also be made:
    9538              : 
    9539              :      -- an lvalue of type T1 can be explicitly converted to an lvalue of
    9540              :      type T2 using the cast const_cast<T2&>;
    9541              : 
    9542              :      -- a glvalue of type T1 can be explicitly converted to an xvalue of
    9543              :      type T2 using the cast const_cast<T2&&>; and
    9544              : 
    9545              :      -- if T1 is a class type, a prvalue of type T1 can be explicitly
    9546              :      converted to an xvalue of type T2 using the cast const_cast<T2&&>.  */
    9547              : 
    9548      1056614 :   if (TYPE_REF_P (dst_type))
    9549              :     {
    9550       146482 :       reference_type = dst_type;
    9551       146482 :       if (!TYPE_REF_IS_RVALUE (dst_type)
    9552       146482 :           ? lvalue_p (expr)
    9553         1302 :           : obvalue_p (expr))
    9554              :         /* OK.  */;
    9555              :       else
    9556              :         {
    9557           35 :           if (complain & tf_error)
    9558            9 :             error_at (loc, "invalid %<const_cast%> of an rvalue of type %qT "
    9559              :                       "to type %qT",
    9560              :                       src_type, dst_type);
    9561           35 :           return error_mark_node;
    9562              :         }
    9563       146447 :       dst_type = build_pointer_type (TREE_TYPE (dst_type));
    9564       146447 :       src_type = build_pointer_type (src_type);
    9565              :     }
    9566              :   else
    9567              :     {
    9568       910132 :       reference_type = NULL_TREE;
    9569              :       /* If the destination type is not a reference type, the
    9570              :          lvalue-to-rvalue, array-to-pointer, and function-to-pointer
    9571              :          conversions are performed.  */
    9572       910132 :       src_type = type_decays_to (src_type);
    9573       910132 :       if (src_type == error_mark_node)
    9574              :         return error_mark_node;
    9575              :     }
    9576              : 
    9577      1056579 :   if (TYPE_PTR_P (src_type) || TYPE_PTRDATAMEM_P (src_type))
    9578              :     {
    9579       638379 :       if (comp_ptr_ttypes_const (dst_type, src_type, bounds_none))
    9580              :         {
    9581       401809 :           if (valid_p)
    9582              :             {
    9583       184927 :               *valid_p = true;
    9584              :               /* This cast is actually a C-style cast.  Issue a warning if
    9585              :                  the user is making a potentially unsafe cast.  */
    9586       184927 :               check_for_casting_away_constness (loc, src_type, dst_type,
    9587              :                                                 CAST_EXPR, complain);
    9588              :               /* ??? comp_ptr_ttypes_const ignores TYPE_ALIGN.  */
    9589       184927 :               if ((STRICT_ALIGNMENT || warn_cast_align == 2)
    9590            3 :                   && (complain & tf_warning)
    9591       184933 :                   && min_align_of_type (TREE_TYPE (dst_type))
    9592            3 :                      > min_align_of_type (TREE_TYPE (src_type)))
    9593            3 :                 warning_at (loc, OPT_Wcast_align, "cast from %qH to %qI "
    9594              :                             "increases required alignment of target type",
    9595              :                             src_type, dst_type);
    9596              :             }
    9597       401809 :           if (reference_type)
    9598              :             {
    9599       145379 :               expr = cp_build_addr_expr (expr, complain);
    9600       145379 :               if (expr == error_mark_node)
    9601              :                 return error_mark_node;
    9602       145361 :               expr = build_nop (reference_type, expr);
    9603       145361 :               return convert_from_reference (expr);
    9604              :             }
    9605              :           else
    9606              :             {
    9607       256430 :               expr = decay_conversion (expr, complain);
    9608       256430 :               if (expr == error_mark_node)
    9609              :                 return error_mark_node;
    9610              : 
    9611              :               /* build_c_cast puts on a NOP_EXPR to make the result not an
    9612              :                  lvalue.  Strip such NOP_EXPRs if VALUE is being used in
    9613              :                  non-lvalue context.  */
    9614       256430 :               if (TREE_CODE (expr) == NOP_EXPR
    9615       256430 :                   && TREE_TYPE (expr) == TREE_TYPE (TREE_OPERAND (expr, 0)))
    9616            3 :                 expr = TREE_OPERAND (expr, 0);
    9617       256430 :               return build_nop (dst_type, expr);
    9618              :             }
    9619              :         }
    9620       236570 :       else if (valid_p
    9621       473092 :                && !at_least_as_qualified_p (TREE_TYPE (dst_type),
    9622       236522 :                                             TREE_TYPE (src_type)))
    9623        15114 :         check_for_casting_away_constness (loc, src_type, dst_type,
    9624              :                                           CAST_EXPR, complain);
    9625              :     }
    9626              : 
    9627       654770 :   if (complain & tf_error)
    9628           30 :     error_at (loc, "invalid %<const_cast%> from type %qT to type %qT",
    9629              :               src_type, dst_type);
    9630       654770 :   return error_mark_node;
    9631              : }
    9632              : 
    9633              : tree
    9634       691288 : build_const_cast (location_t loc, tree type, tree expr,
    9635              :                   tsubst_flags_t complain)
    9636              : {
    9637       691288 :   tree r;
    9638              : 
    9639       691288 :   if (type == error_mark_node || error_operand_p (expr))
    9640              :     return error_mark_node;
    9641              : 
    9642       691280 :   if (processing_template_decl)
    9643              :     {
    9644       474320 :       tree t = build_min (CONST_CAST_EXPR, type, expr);
    9645              : 
    9646       474320 :       if (!TREE_SIDE_EFFECTS (t)
    9647       474320 :           && type_dependent_expression_p (expr))
    9648              :         /* There might turn out to be side effects inside expr.  */
    9649       364605 :         TREE_SIDE_EFFECTS (t) = 1;
    9650       474320 :       r = convert_from_reference (t);
    9651       474320 :       protected_set_expr_location (r, loc);
    9652       474320 :       return r;
    9653              :     }
    9654              : 
    9655       216960 :   r = build_const_cast_1 (loc, type, expr, complain, /*valid_p=*/NULL);
    9656       216960 :   if (r != error_mark_node)
    9657              :     {
    9658       216882 :       maybe_warn_about_useless_cast (loc, type, expr, complain);
    9659       216882 :       maybe_warn_about_cast_ignoring_quals (loc, type, complain);
    9660              :     }
    9661       216960 :   protected_set_expr_location (r, loc);
    9662       216960 :   return r;
    9663              : }
    9664              : 
    9665              : /* Like cp_build_c_cast, but for the c-common bits.  */
    9666              : 
    9667              : tree
    9668            0 : build_c_cast (location_t loc, tree type, tree expr)
    9669              : {
    9670            0 :   return cp_build_c_cast (loc, type, expr, tf_warning_or_error);
    9671              : }
    9672              : 
    9673              : /* Like the "build_c_cast" used for c-common, but using cp_expr to
    9674              :    preserve location information even for tree nodes that don't
    9675              :    support it.  */
    9676              : 
    9677              : cp_expr
    9678     10418403 : build_c_cast (location_t loc, tree type, cp_expr expr)
    9679              : {
    9680     10418403 :   cp_expr result = cp_build_c_cast (loc, type, expr, tf_warning_or_error);
    9681     10418403 :   result.set_location (loc);
    9682     10418403 :   return result;
    9683              : }
    9684              : 
    9685              : /* Build an expression representing an explicit C-style cast to type
    9686              :    TYPE of expression EXPR.  */
    9687              : 
    9688              : tree
    9689     40390975 : cp_build_c_cast (location_t loc, tree type, tree expr,
    9690              :                  tsubst_flags_t complain)
    9691              : {
    9692     40390975 :   tree value = expr;
    9693     40390975 :   tree result;
    9694     40390975 :   bool valid_p;
    9695              : 
    9696     40390975 :   if (type == error_mark_node || error_operand_p (expr))
    9697              :     return error_mark_node;
    9698              : 
    9699     40390792 :   if (processing_template_decl)
    9700              :     {
    9701      2729908 :       tree t = build_min (CAST_EXPR, type,
    9702              :                           tree_cons (NULL_TREE, value, NULL_TREE));
    9703              :       /* We don't know if it will or will not have side effects.  */
    9704      2729908 :       TREE_SIDE_EFFECTS (t) = 1;
    9705      2729908 :       return convert_from_reference (t);
    9706              :     }
    9707              : 
    9708              :   /* Casts to a (pointer to a) specific ObjC class (or 'id' or
    9709              :      'Class') should always be retained, because this information aids
    9710              :      in method lookup.  */
    9711     37660884 :   if (objc_is_object_ptr (type)
    9712     37660884 :       && objc_is_object_ptr (TREE_TYPE (expr)))
    9713            0 :     return build_nop (type, expr);
    9714              : 
    9715              :   /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
    9716              :      Strip such NOP_EXPRs if VALUE is being used in non-lvalue context.  */
    9717     37660884 :   if (!TYPE_REF_P (type)
    9718     37658563 :       && TREE_CODE (value) == NOP_EXPR
    9719     38111038 :       && TREE_TYPE (value) == TREE_TYPE (TREE_OPERAND (value, 0)))
    9720       224194 :     value = TREE_OPERAND (value, 0);
    9721              : 
    9722     37660884 :   if (TREE_CODE (type) == ARRAY_TYPE)
    9723              :     {
    9724              :       /* Allow casting from T1* to T2[] because Cfront allows it.
    9725              :          NIHCL uses it. It is not valid ISO C++ however.  */
    9726            3 :       if (TYPE_PTR_P (TREE_TYPE (expr)))
    9727              :         {
    9728            0 :           if (complain & tf_error)
    9729            0 :             permerror (loc, "ISO C++ forbids casting to an array type %qT",
    9730              :                        type);
    9731              :           else
    9732            0 :             return error_mark_node;
    9733            0 :           type = build_pointer_type (TREE_TYPE (type));
    9734              :         }
    9735              :       else
    9736              :         {
    9737            3 :           if (complain & tf_error)
    9738            3 :             error_at (loc, "ISO C++ forbids casting to an array type %qT",
    9739              :                       type);
    9740            3 :           return error_mark_node;
    9741              :         }
    9742              :     }
    9743              : 
    9744     37660881 :   if (FUNC_OR_METHOD_TYPE_P (type))
    9745              :     {
    9746           15 :       if (complain & tf_error)
    9747           15 :         error_at (loc, "invalid cast to function type %qT", type);
    9748           15 :       return error_mark_node;
    9749              :     }
    9750              : 
    9751     37660866 :   if (TYPE_PTR_P (type)
    9752       841369 :       && TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE
    9753              :       /* Casting to an integer of smaller size is an error detected elsewhere.  */
    9754       416795 :       && TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (value))
    9755              :       /* Don't warn about converting any constant.  */
    9756     38023573 :       && !TREE_CONSTANT (value))
    9757           47 :     warning_at (loc, OPT_Wint_to_pointer_cast,
    9758              :                 "cast to pointer from integer of different size");
    9759              : 
    9760              :   /* A C-style cast can be a const_cast.  */
    9761     37660866 :   result = build_const_cast_1 (loc, type, value, complain & tf_warning,
    9762              :                                &valid_p);
    9763     37660866 :   if (valid_p)
    9764              :     {
    9765       184918 :       if (result != error_mark_node)
    9766              :         {
    9767       184909 :           maybe_warn_about_useless_cast (loc, type, value, complain);
    9768       184909 :           maybe_warn_about_cast_ignoring_quals (loc, type, complain);
    9769              :         }
    9770            9 :       else if (complain & tf_error)
    9771            9 :         build_const_cast_1 (loc, type, value, tf_error, &valid_p);
    9772       184918 :       return result;
    9773              :     }
    9774              : 
    9775              :   /* Or a static cast.  */
    9776     37475948 :   result = build_static_cast_1 (loc, type, value, /*c_cast_p=*/true,
    9777              :                                 &valid_p, complain);
    9778              :   /* Or a reinterpret_cast.  */
    9779     37475948 :   if (!valid_p)
    9780      1812603 :     result = build_reinterpret_cast_1 (loc, type, value, /*c_cast_p=*/true,
    9781              :                                        &valid_p, complain);
    9782              :   /* The static_cast or reinterpret_cast may be followed by a
    9783              :      const_cast.  */
    9784     37475948 :   if (valid_p
    9785              :       /* A valid cast may result in errors if, for example, a
    9786              :          conversion to an ambiguous base class is required.  */
    9787     37475948 :       && !error_operand_p (result))
    9788              :     {
    9789     37475541 :       tree result_type;
    9790              : 
    9791     37475541 :       maybe_warn_about_useless_cast (loc, type, value, complain);
    9792     37475541 :       maybe_warn_about_cast_ignoring_quals (loc, type, complain);
    9793              : 
    9794              :       /* Non-class rvalues always have cv-unqualified type.  */
    9795     37475541 :       if (!CLASS_TYPE_P (type))
    9796     34826131 :         type = TYPE_MAIN_VARIANT (type);
    9797     37475541 :       result_type = TREE_TYPE (result);
    9798     37475541 :       if (!CLASS_TYPE_P (result_type) && !TYPE_REF_P (type))
    9799     34825041 :         result_type = TYPE_MAIN_VARIANT (result_type);
    9800              :       /* If the type of RESULT does not match TYPE, perform a
    9801              :          const_cast to make it match.  If the static_cast or
    9802              :          reinterpret_cast succeeded, we will differ by at most
    9803              :          cv-qualification, so the follow-on const_cast is guaranteed
    9804              :          to succeed.  */
    9805     37475541 :       if (!same_type_p (non_reference (type), non_reference (result_type)))
    9806              :         {
    9807            0 :           result = build_const_cast_1 (loc, type, result, tf_none, &valid_p);
    9808            0 :           gcc_assert (valid_p);
    9809              :         }
    9810     37475541 :       return result;
    9811              :     }
    9812              : 
    9813          407 :   return error_mark_node;
    9814              : }
    9815              : 
    9816              : /* Warn when a value is moved to itself with std::move.  LHS is the target,
    9817              :    RHS may be the std::move call, and LOC is the location of the whole
    9818              :    assignment.  Return true if we warned.  */
    9819              : 
    9820              : bool
    9821     27777914 : maybe_warn_self_move (location_t loc, tree lhs, tree rhs)
    9822              : {
    9823     27777914 :   if (!warn_self_move)
    9824              :     return false;
    9825              : 
    9826              :   /* C++98 doesn't know move.  */
    9827       365834 :   if (cxx_dialect < cxx11)
    9828              :     return false;
    9829              : 
    9830       345948 :   if (processing_template_decl)
    9831              :     return false;
    9832              : 
    9833        26524 :   if (!REFERENCE_REF_P (rhs)
    9834       301678 :       || TREE_CODE (TREE_OPERAND (rhs, 0)) != CALL_EXPR)
    9835              :     return false;
    9836         4816 :   tree fn = TREE_OPERAND (rhs, 0);
    9837         4816 :   if (!is_std_move_p (fn))
    9838              :     return false;
    9839              : 
    9840              :   /* Just a little helper to strip * and various NOPs.  */
    9841         6519 :   auto extract_op = [] (tree &op) {
    9842         4346 :     STRIP_NOPS (op);
    9843         5567 :     while (INDIRECT_REF_P (op))
    9844         1221 :       op = TREE_OPERAND (op, 0);
    9845         4346 :     op = maybe_undo_parenthesized_ref (op);
    9846         4346 :     STRIP_ANY_LOCATION_WRAPPER (op);
    9847         4346 :   };
    9848              : 
    9849         2173 :   tree arg = CALL_EXPR_ARG (fn, 0);
    9850         2173 :   extract_op (arg);
    9851         2173 :   if (TREE_CODE (arg) == ADDR_EXPR)
    9852         1495 :     arg = TREE_OPERAND (arg, 0);
    9853         2173 :   tree type = TREE_TYPE (lhs);
    9854         2173 :   tree orig_lhs = lhs;
    9855         2173 :   extract_op (lhs);
    9856         2173 :   if (cp_tree_equal (lhs, arg)
    9857              :       /* Also warn in a member-initializer-list, as in : i(std::move(i)).  */
    9858         2173 :       || (TREE_CODE (lhs) == FIELD_DECL
    9859          640 :           && TREE_CODE (arg) == COMPONENT_REF
    9860          305 :           && cp_tree_equal (TREE_OPERAND (arg, 0), current_class_ref)
    9861            6 :           && TREE_OPERAND (arg, 1) == lhs))
    9862          117 :     if (warning_at (loc, OPT_Wself_move,
    9863              :                     "moving %qE of type %qT to itself", orig_lhs, type))
    9864              :       return true;
    9865              : 
    9866              :   return false;
    9867              : }
    9868              : 
    9869              : /* For use from the C common bits.  */
    9870              : tree
    9871         4766 : build_modify_expr (location_t location,
    9872              :                    tree lhs, tree /*lhs_origtype*/,
    9873              :                    enum tree_code modifycode,
    9874              :                    location_t /*rhs_location*/, tree rhs,
    9875              :                    tree /*rhs_origtype*/)
    9876              : {
    9877         4766 :   return cp_build_modify_expr (location, lhs, modifycode, rhs,
    9878         4766 :                                tf_warning_or_error);
    9879              : }
    9880              : 
    9881              : /* Build an assignment expression of lvalue LHS from value RHS.
    9882              :    MODIFYCODE is the code for a binary operator that we use
    9883              :    to combine the old value of LHS with RHS to get the new value.
    9884              :    Or else MODIFYCODE is NOP_EXPR meaning do a simple assignment.
    9885              : 
    9886              :    C++: If MODIFYCODE is INIT_EXPR, then leave references unbashed.  */
    9887              : 
    9888              : tree
    9889     36187963 : cp_build_modify_expr (location_t loc, tree lhs, enum tree_code modifycode,
    9890              :                       tree rhs, tsubst_flags_t complain)
    9891              : {
    9892     36187963 :   lhs = mark_lvalue_use_nonread (lhs);
    9893              : 
    9894     36187963 :   tree result = NULL_TREE;
    9895     36187963 :   tree newrhs = rhs;
    9896     36187963 :   tree lhstype = TREE_TYPE (lhs);
    9897     36187963 :   tree olhs = lhs;
    9898     36187963 :   tree olhstype = lhstype;
    9899     36187963 :   bool plain_assign = (modifycode == NOP_EXPR);
    9900     36187963 :   bool compound_side_effects_p = false;
    9901     36187963 :   tree preeval = NULL_TREE;
    9902              : 
    9903              :   /* Avoid duplicate error messages from operands that had errors.  */
    9904     36187963 :   if (error_operand_p (lhs) || error_operand_p (rhs))
    9905           19 :     return error_mark_node;
    9906              : 
    9907     36188026 :   while (TREE_CODE (lhs) == COMPOUND_EXPR)
    9908              :     {
    9909           82 :       if (TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0)))
    9910           70 :         compound_side_effects_p = true;
    9911           82 :       lhs = TREE_OPERAND (lhs, 1);
    9912              :     }
    9913              : 
    9914              :   /* Handle control structure constructs used as "lvalues".  Note that we
    9915              :      leave COMPOUND_EXPR on the LHS because it is sequenced after the RHS.  */
    9916     36187944 :   switch (TREE_CODE (lhs))
    9917              :     {
    9918              :       /* Handle --foo = 5; as these are valid constructs in C++.  */
    9919           27 :     case PREDECREMENT_EXPR:
    9920           27 :     case PREINCREMENT_EXPR:
    9921           27 :       if (compound_side_effects_p)
    9922            9 :         newrhs = rhs = stabilize_expr (rhs, &preeval);
    9923           27 :       lhs = genericize_compound_lvalue (lhs);
    9924          173 :     maybe_add_compound:
    9925              :       /* If we had (bar, --foo) = 5; or (bar, (baz, --foo)) = 5;
    9926              :          and looked through the COMPOUND_EXPRs, readd them now around
    9927              :          the resulting lhs.  */
    9928          173 :       if (TREE_CODE (olhs) == COMPOUND_EXPR)
    9929              :         {
    9930            9 :           lhs = build2 (COMPOUND_EXPR, lhstype, TREE_OPERAND (olhs, 0), lhs);
    9931            9 :           tree *ptr = &TREE_OPERAND (lhs, 1);
    9932            9 :           for (olhs = TREE_OPERAND (olhs, 1);
    9933           12 :                TREE_CODE (olhs) == COMPOUND_EXPR;
    9934            3 :                olhs = TREE_OPERAND (olhs, 1))
    9935              :             {
    9936            3 :               *ptr = build2 (COMPOUND_EXPR, lhstype,
    9937            3 :                              TREE_OPERAND (olhs, 0), *ptr);
    9938            3 :               ptr = &TREE_OPERAND (*ptr, 1);
    9939              :             }
    9940              :         }
    9941              :       break;
    9942              : 
    9943          146 :     case MODIFY_EXPR:
    9944          146 :       if (compound_side_effects_p)
    9945            0 :         newrhs = rhs = stabilize_expr (rhs, &preeval);
    9946          146 :       lhs = genericize_compound_lvalue (lhs);
    9947          146 :       goto maybe_add_compound;
    9948              : 
    9949            0 :     case MIN_EXPR:
    9950            0 :     case MAX_EXPR:
    9951              :       /* MIN_EXPR and MAX_EXPR are currently only permitted as lvalues,
    9952              :          when neither operand has side-effects.  */
    9953            0 :       if (!lvalue_or_else (lhs, lv_assign, complain))
    9954            0 :         return error_mark_node;
    9955              : 
    9956            0 :       gcc_assert (!TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0))
    9957              :                   && !TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 1)));
    9958              : 
    9959            0 :       lhs = build3 (COND_EXPR, TREE_TYPE (lhs),
    9960            0 :                     build2 (TREE_CODE (lhs) == MIN_EXPR ? LE_EXPR : GE_EXPR,
    9961              :                             boolean_type_node,
    9962            0 :                             TREE_OPERAND (lhs, 0),
    9963            0 :                             TREE_OPERAND (lhs, 1)),
    9964            0 :                     TREE_OPERAND (lhs, 0),
    9965            0 :                     TREE_OPERAND (lhs, 1));
    9966          212 :       gcc_fallthrough ();
    9967              : 
    9968              :       /* Handle (a ? b : c) used as an "lvalue".  */
    9969          212 :     case COND_EXPR:
    9970          212 :       {
    9971              :         /* Produce (a ? (b = rhs) : (c = rhs))
    9972              :            except that the RHS goes through a save-expr
    9973              :            so the code to compute it is only emitted once.  */
    9974          212 :         if (VOID_TYPE_P (TREE_TYPE (rhs)))
    9975              :           {
    9976           18 :             if (complain & tf_error)
    9977           24 :               error_at (cp_expr_loc_or_loc (rhs, loc),
    9978              :                         "void value not ignored as it ought to be");
    9979           18 :             return error_mark_node;
    9980              :           }
    9981              : 
    9982          194 :         rhs = stabilize_expr (rhs, &preeval);
    9983              : 
    9984              :         /* Check this here to avoid odd errors when trying to convert
    9985              :            a throw to the type of the COND_EXPR.  */
    9986          194 :         if (!lvalue_or_else (lhs, lv_assign, complain))
    9987            6 :           return error_mark_node;
    9988              : 
    9989          188 :         tree op1 = TREE_OPERAND (lhs, 1);
    9990          188 :         if (TREE_CODE (op1) != THROW_EXPR)
    9991          182 :           op1 = cp_build_modify_expr (loc, op1, modifycode, rhs, complain);
    9992              :         /* When sanitizing undefined behavior, even when rhs doesn't need
    9993              :            stabilization at this point, the sanitization might add extra
    9994              :            SAVE_EXPRs in there and so make sure there is no tree sharing
    9995              :            in the rhs, otherwise those SAVE_EXPRs will have initialization
    9996              :            only in one of the two branches.  */
    9997          188 :         if (sanitize_flags_p (SANITIZE_UNDEFINED
    9998              :                               | SANITIZE_UNDEFINED_NONDEFAULT))
    9999            3 :           rhs = unshare_expr (rhs);
   10000          188 :         tree op2 = TREE_OPERAND (lhs, 2);
   10001          188 :         if (TREE_CODE (op2) != THROW_EXPR)
   10002          182 :           op2 = cp_build_modify_expr (loc, op2, modifycode, rhs, complain);
   10003          188 :         tree cond = build_conditional_expr (input_location,
   10004          188 :                                             TREE_OPERAND (lhs, 0), op1, op2,
   10005              :                                             complain);
   10006              : 
   10007          188 :         if (cond == error_mark_node)
   10008              :           return cond;
   10009              :         /* If we had (e, (a ? b : c)) = d; or (e, (f, (a ? b : c))) = d;
   10010              :            and looked through the COMPOUND_EXPRs, readd them now around
   10011              :            the resulting cond before adding the preevaluated rhs.  */
   10012          185 :         if (TREE_CODE (olhs) == COMPOUND_EXPR)
   10013              :           {
   10014           18 :             cond = build2 (COMPOUND_EXPR, TREE_TYPE (cond),
   10015           18 :                            TREE_OPERAND (olhs, 0), cond);
   10016           18 :             tree *ptr = &TREE_OPERAND (cond, 1);
   10017           18 :             for (olhs = TREE_OPERAND (olhs, 1);
   10018           21 :                  TREE_CODE (olhs) == COMPOUND_EXPR;
   10019            3 :                  olhs = TREE_OPERAND (olhs, 1))
   10020              :               {
   10021            3 :                 *ptr = build2 (COMPOUND_EXPR, TREE_TYPE (cond),
   10022            3 :                                TREE_OPERAND (olhs, 0), *ptr);
   10023            3 :                 ptr = &TREE_OPERAND (*ptr, 1);
   10024              :               }
   10025              :           }
   10026              :         /* Make sure the code to compute the rhs comes out
   10027              :            before the split.  */
   10028          185 :         result = cond;
   10029          185 :         goto ret;
   10030              :       }
   10031              : 
   10032              :     default:
   10033              :       lhs = olhs;
   10034              :       break;
   10035              :     }
   10036              : 
   10037     36187732 :   if (modifycode == INIT_EXPR)
   10038              :     {
   10039      4088020 :       if (BRACE_ENCLOSED_INITIALIZER_P (rhs))
   10040              :         /* Do the default thing.  */;
   10041      3891583 :       else if (TREE_CODE (rhs) == CONSTRUCTOR)
   10042              :         {
   10043              :           /* Compound literal.  */
   10044           98 :           if (! same_type_p (TREE_TYPE (rhs), lhstype))
   10045              :             /* Call convert to generate an error; see PR 11063.  */
   10046            0 :             rhs = convert (lhstype, rhs);
   10047           98 :           result = cp_build_init_expr (lhs, rhs);
   10048           98 :           TREE_SIDE_EFFECTS (result) = 1;
   10049           98 :           goto ret;
   10050              :         }
   10051      3891485 :       else if (! MAYBE_CLASS_TYPE_P (lhstype))
   10052              :         /* Do the default thing.  */;
   10053              :       else
   10054              :         {
   10055        39826 :           releasing_vec rhs_vec = make_tree_vector_single (rhs);
   10056        39826 :           result = build_special_member_call (lhs, complete_ctor_identifier,
   10057              :                                               &rhs_vec, lhstype, LOOKUP_NORMAL,
   10058              :                                               complain);
   10059        39826 :           if (result == NULL_TREE)
   10060            0 :             return error_mark_node;
   10061        39826 :           goto ret;
   10062        39826 :         }
   10063              :     }
   10064              :   else
   10065              :     {
   10066     32099712 :       lhs = require_complete_type (lhs, complain);
   10067     32099712 :       if (lhs == error_mark_node)
   10068              :         return error_mark_node;
   10069              : 
   10070     32099614 :       if (modifycode == NOP_EXPR)
   10071              :         {
   10072     27728768 :           maybe_warn_self_move (loc, lhs, rhs);
   10073              : 
   10074     27728768 :           if (c_dialect_objc ())
   10075              :             {
   10076            0 :               result = objc_maybe_build_modify_expr (lhs, rhs);
   10077            0 :               if (result)
   10078            0 :                 goto ret;
   10079              :             }
   10080              : 
   10081              :           /* `operator=' is not an inheritable operator.  */
   10082     27728768 :           if (! MAYBE_CLASS_TYPE_P (lhstype))
   10083              :             /* Do the default thing.  */;
   10084              :           else
   10085              :             {
   10086      3359840 :               result = build_new_op (input_location, MODIFY_EXPR,
   10087              :                                      LOOKUP_NORMAL, lhs, rhs,
   10088              :                                      make_node (NOP_EXPR), NULL_TREE,
   10089              :                                      /*overload=*/NULL, complain);
   10090      3359840 :               if (result == NULL_TREE)
   10091            0 :                 return error_mark_node;
   10092      3359840 :               goto ret;
   10093              :             }
   10094              :           lhstype = olhstype;
   10095              :         }
   10096              :       else
   10097              :         {
   10098      4370846 :           tree init = NULL_TREE;
   10099              : 
   10100              :           /* A binary op has been requested.  Combine the old LHS
   10101              :              value with the RHS producing the value we should actually
   10102              :              store into the LHS.  */
   10103      4370846 :           gcc_assert (!((TYPE_REF_P (lhstype)
   10104              :                          && MAYBE_CLASS_TYPE_P (TREE_TYPE (lhstype)))
   10105              :                         || MAYBE_CLASS_TYPE_P (lhstype)));
   10106              : 
   10107              :           /* Preevaluate the RHS to make sure its evaluation is complete
   10108              :              before the lvalue-to-rvalue conversion of the LHS:
   10109              : 
   10110              :              [expr.ass] With respect to an indeterminately-sequenced
   10111              :              function call, the operation of a compound assignment is a
   10112              :              single evaluation. [ Note: Therefore, a function call shall
   10113              :              not intervene between the lvalue-to-rvalue conversion and the
   10114              :              side effect associated with any single compound assignment
   10115              :              operator. -- end note ]  */
   10116      4370846 :           lhs = cp_stabilize_reference (lhs);
   10117      4370846 :           rhs = decay_conversion (rhs, complain);
   10118      4370846 :           if (rhs == error_mark_node)
   10119          123 :             return error_mark_node;
   10120              : 
   10121      4370843 :           {
   10122      4370843 :             auto_diagnostic_group d;
   10123      4370843 :             rhs = stabilize_expr (rhs, &init);
   10124      4370843 :             bool clear_decl_read = false;
   10125      4370843 :             tree stripped_lhs = tree_strip_any_location_wrapper (lhs);
   10126      1360022 :             if ((VAR_P (stripped_lhs) || TREE_CODE (stripped_lhs) == PARM_DECL)
   10127      3666775 :                 && !DECL_READ_P (stripped_lhs)
   10128       929576 :                 && (VAR_P (stripped_lhs) ? warn_unused_but_set_variable
   10129              :                                          : warn_unused_but_set_parameter) > 2
   10130         7007 :                 && !CLASS_TYPE_P (TREE_TYPE (lhs))
   10131      4377850 :                 && !CLASS_TYPE_P (TREE_TYPE (rhs)))
   10132              :               {
   10133         7007 :                 mark_exp_read (rhs);
   10134         7007 :                 if (!DECL_READ_P (stripped_lhs))
   10135      4370843 :                   clear_decl_read = true;
   10136              :               }
   10137      4370843 :             newrhs = cp_build_binary_op (loc, modifycode, lhs, rhs, complain);
   10138      4370843 :             if (clear_decl_read)
   10139         7007 :               DECL_READ_P (stripped_lhs) = 0;
   10140      4370843 :             if (newrhs == error_mark_node)
   10141              :               {
   10142          120 :                 if (complain & tf_error)
   10143           24 :                   inform (loc, "  in evaluation of %<%Q(%#T, %#T)%>",
   10144           24 :                           modifycode, TREE_TYPE (lhs), TREE_TYPE (rhs));
   10145          120 :                 return error_mark_node;
   10146              :               }
   10147      4370843 :           }
   10148              : 
   10149      4370723 :           if (init)
   10150       250384 :             newrhs = build2 (COMPOUND_EXPR, TREE_TYPE (newrhs), init, newrhs);
   10151              : 
   10152              :           /* Now it looks like a plain assignment.  */
   10153      4370723 :           modifycode = NOP_EXPR;
   10154      4370723 :           if (c_dialect_objc ())
   10155              :             {
   10156            0 :               result = objc_maybe_build_modify_expr (lhs, newrhs);
   10157            0 :               if (result)
   10158            0 :                 goto ret;
   10159              :             }
   10160              :         }
   10161     28739651 :       gcc_assert (!TYPE_REF_P (lhstype));
   10162     28739651 :       gcc_assert (!TYPE_REF_P (TREE_TYPE (newrhs)));
   10163              :     }
   10164              : 
   10165              :   /* The left-hand side must be an lvalue.  */
   10166     32787747 :   if (!lvalue_or_else (lhs, lv_assign, complain))
   10167          503 :     return error_mark_node;
   10168              : 
   10169              :   /* Warn about modifying something that is `const'.  Don't warn if
   10170              :      this is initialization.  */
   10171     32787244 :   if (modifycode != INIT_EXPR
   10172     32787244 :       && (TREE_READONLY (lhs) || CP_TYPE_CONST_P (lhstype)
   10173              :           /* Functions are not modifiable, even though they are
   10174              :              lvalues.  */
   10175     28703316 :           || FUNC_OR_METHOD_TYPE_P (TREE_TYPE (lhs))
   10176              :           /* If it's an aggregate and any field is const, then it is
   10177              :              effectively const.  */
   10178     28703244 :           || (CLASS_TYPE_P (lhstype)
   10179            0 :               && C_TYPE_FIELDS_READONLY (lhstype))))
   10180              :     {
   10181        35904 :       if (complain & tf_error)
   10182           89 :         cxx_readonly_error (loc, lhs, lv_assign);
   10183        35904 :       return error_mark_node;
   10184              :     }
   10185              : 
   10186              :   /* If storing into a structure or union member, it may have been given a
   10187              :      lowered bitfield type.  We need to convert to the declared type first,
   10188              :      so retrieve it now.  */
   10189              : 
   10190     32751340 :   olhstype = unlowered_expr_type (lhs);
   10191              : 
   10192              :   /* Convert new value to destination type.  */
   10193              : 
   10194     32751340 :   if (TREE_CODE (lhstype) == ARRAY_TYPE)
   10195              :     {
   10196          221 :       int from_array;
   10197              : 
   10198          221 :       if (BRACE_ENCLOSED_INITIALIZER_P (newrhs))
   10199              :         {
   10200           12 :           if (modifycode != INIT_EXPR)
   10201              :             {
   10202           12 :               if (complain & tf_error)
   10203           12 :                 error_at (loc,
   10204              :                           "assigning to an array from an initializer list");
   10205           12 :               return error_mark_node;
   10206              :             }
   10207            0 :           if (check_array_initializer (lhs, lhstype, newrhs))
   10208            0 :             return error_mark_node;
   10209            0 :           newrhs = digest_init (lhstype, newrhs, complain);
   10210            0 :           if (newrhs == error_mark_node)
   10211              :             return error_mark_node;
   10212              :         }
   10213              : 
   10214              :       /* C++11 8.5/17: "If the destination type is an array of characters,
   10215              :          an array of char16_t, an array of char32_t, or an array of wchar_t,
   10216              :          and the initializer is a string literal...".  */
   10217          209 :       else if ((TREE_CODE (tree_strip_any_location_wrapper (newrhs))
   10218              :                 == STRING_CST)
   10219           43 :                && char_type_p (TREE_TYPE (TYPE_MAIN_VARIANT (lhstype)))
   10220          252 :                && modifycode == INIT_EXPR)
   10221              :         {
   10222           28 :           newrhs = digest_init (lhstype, newrhs, complain);
   10223           28 :           if (newrhs == error_mark_node)
   10224              :             return error_mark_node;
   10225              :         }
   10226              : 
   10227          181 :       else if (!same_or_base_type_p (TYPE_MAIN_VARIANT (lhstype),
   10228              :                                      TYPE_MAIN_VARIANT (TREE_TYPE (newrhs))))
   10229              :         {
   10230           27 :           if (complain & tf_error)
   10231           12 :             error_at (loc, "incompatible types in assignment of %qT to %qT",
   10232           12 :                       TREE_TYPE (rhs), lhstype);
   10233           27 :           return error_mark_node;
   10234              :         }
   10235              : 
   10236              :       /* Allow array assignment in compiler-generated code.  */
   10237          154 :       else if (DECL_P (lhs) && DECL_ARTIFICIAL (lhs))
   10238              :         /* OK, used by coroutines (co-await-initlist1.C).  */;
   10239          148 :       else if (!current_function_decl
   10240          148 :                || !DECL_DEFAULTED_FN (current_function_decl))
   10241              :         {
   10242              :           /* This routine is used for both initialization and assignment.
   10243              :              Make sure the diagnostic message differentiates the context.  */
   10244           98 :           if (complain & tf_error)
   10245              :             {
   10246           30 :               if (modifycode == INIT_EXPR)
   10247            9 :                 error_at (loc, "array used as initializer");
   10248              :               else
   10249           21 :                 error_at (loc, "invalid array assignment");
   10250              :             }
   10251           98 :           return error_mark_node;
   10252              :         }
   10253              : 
   10254          131 :       from_array = TREE_CODE (TREE_TYPE (newrhs)) == ARRAY_TYPE
   10255           84 :                    ? 1 + (modifycode != INIT_EXPR) : 0;
   10256           84 :       result = build_vec_init (lhs, NULL_TREE, newrhs,
   10257              :                                /*explicit_value_init_p=*/false,
   10258              :                                from_array, complain);
   10259           84 :       goto ret;
   10260              :     }
   10261              : 
   10262     32751119 :   if (modifycode == INIT_EXPR)
   10263              :     /* Calls with INIT_EXPR are all direct-initialization, so don't set
   10264              :        LOOKUP_ONLYCONVERTING.  */
   10265      4048037 :     newrhs = convert_for_initialization (lhs, olhstype, newrhs, LOOKUP_NORMAL,
   10266              :                                          ICR_INIT, NULL_TREE, 0,
   10267              :                                          complain | tf_no_cleanup);
   10268              :   else
   10269     28703082 :     newrhs = convert_for_assignment (olhstype, newrhs, ICR_ASSIGN,
   10270              :                                      NULL_TREE, 0, complain, LOOKUP_IMPLICIT);
   10271              : 
   10272     32751119 :   if (!same_type_p (lhstype, olhstype))
   10273       377748 :     newrhs = cp_convert_and_check (lhstype, newrhs, complain);
   10274              : 
   10275     32751119 :   if (modifycode != INIT_EXPR)
   10276              :     {
   10277     28703082 :       if (TREE_CODE (newrhs) == CALL_EXPR
   10278     28703082 :           && TYPE_NEEDS_CONSTRUCTING (lhstype))
   10279            0 :         newrhs = build_cplus_new (lhstype, newrhs, complain);
   10280              : 
   10281              :       /* Can't initialize directly from a TARGET_EXPR, since that would
   10282              :          cause the lhs to be constructed twice, and possibly result in
   10283              :          accidental self-initialization.  So we force the TARGET_EXPR to be
   10284              :          expanded without a target.  */
   10285     28703082 :       if (TREE_CODE (newrhs) == TARGET_EXPR)
   10286           87 :         newrhs = build2 (COMPOUND_EXPR, TREE_TYPE (newrhs), newrhs,
   10287           87 :                          TARGET_EXPR_SLOT (newrhs));
   10288              :     }
   10289              : 
   10290     32751119 :   if (newrhs == error_mark_node)
   10291              :     return error_mark_node;
   10292              : 
   10293     32750442 :   if (c_dialect_objc () && flag_objc_gc)
   10294              :     {
   10295            0 :       result = objc_generate_write_barrier (lhs, modifycode, newrhs);
   10296              : 
   10297            0 :       if (result)
   10298            0 :         goto ret;
   10299              :     }
   10300              : 
   10301     36798430 :   result = build2_loc (loc, modifycode == NOP_EXPR ? MODIFY_EXPR : INIT_EXPR,
   10302              :                        lhstype, lhs, newrhs);
   10303     32750442 :   if (modifycode == INIT_EXPR)
   10304      4047988 :     set_target_expr_eliding (newrhs);
   10305              : 
   10306     32750442 :   TREE_SIDE_EFFECTS (result) = 1;
   10307     32750442 :   if (!plain_assign)
   10308      8418681 :     suppress_warning (result, OPT_Wparentheses);
   10309              : 
   10310     24331761 :  ret:
   10311     36150475 :   if (preeval)
   10312           39 :     result = build2 (COMPOUND_EXPR, TREE_TYPE (result), preeval, result);
   10313              :   return result;
   10314              : }
   10315              : 
   10316              : cp_expr
   10317     67938994 : build_x_modify_expr (location_t loc, tree lhs, enum tree_code modifycode,
   10318              :                      tree rhs, tree lookups, tsubst_flags_t complain)
   10319              : {
   10320     67938994 :   tree orig_lhs = lhs;
   10321     67938994 :   tree orig_rhs = rhs;
   10322     67938994 :   tree overload = NULL_TREE;
   10323              : 
   10324     67938994 :   if (lhs == error_mark_node || rhs == error_mark_node)
   10325         2192 :     return cp_expr (error_mark_node, loc);
   10326              : 
   10327     67936802 :   tree op = build_min (modifycode, void_type_node, NULL_TREE, NULL_TREE);
   10328              : 
   10329     67936802 :   if (processing_template_decl)
   10330              :     {
   10331     47590859 :       if (type_dependent_expression_p (lhs)
   10332     47590859 :           || type_dependent_expression_p (rhs))
   10333              :         {
   10334     35662045 :           tree rval = build_min_nt_loc (loc, MODOP_EXPR, lhs, op, rhs);
   10335     35662045 :           if (modifycode != NOP_EXPR)
   10336      6047663 :             TREE_TYPE (rval)
   10337     12095326 :               = build_dependent_operator_type (lookups, modifycode, true);
   10338     35662045 :           return rval;
   10339              :         }
   10340              :     }
   10341              : 
   10342     32274757 :   tree rval;
   10343     32274757 :   if (modifycode == NOP_EXPR)
   10344     25110741 :     rval = cp_build_modify_expr (loc, lhs, modifycode, rhs, complain);
   10345              :   else
   10346      7164016 :     rval = build_new_op (loc, MODIFY_EXPR, LOOKUP_NORMAL,
   10347              :                          lhs, rhs, op, lookups, &overload, complain);
   10348     32274757 :   if (rval == error_mark_node)
   10349         4501 :     return error_mark_node;
   10350     32270256 :   if (processing_template_decl)
   10351              :     {
   10352     11928793 :       if (overload != NULL_TREE)
   10353      1889584 :         return (build_min_non_dep_op_overload
   10354      1889584 :                 (MODIFY_EXPR, rval, overload, orig_lhs, orig_rhs));
   10355              : 
   10356     10039209 :       return (build_min_non_dep
   10357     10039209 :               (MODOP_EXPR, rval, orig_lhs, op, orig_rhs));
   10358              :     }
   10359     20341463 :   return rval;
   10360              : }
   10361              : 
   10362              : /* Helper function for get_delta_difference which assumes FROM is a base
   10363              :    class of TO.  Returns a delta for the conversion of pointer-to-member
   10364              :    of FROM to pointer-to-member of TO.  If the conversion is invalid and
   10365              :    tf_error is not set in COMPLAIN returns error_mark_node, otherwise
   10366              :    returns zero.  If FROM is not a base class of TO, returns NULL_TREE.
   10367              :    If C_CAST_P is true, this conversion is taking place as part of a
   10368              :    C-style cast.  */
   10369              : 
   10370              : static tree
   10371        28005 : get_delta_difference_1 (tree from, tree to, bool c_cast_p,
   10372              :                         tsubst_flags_t complain)
   10373              : {
   10374        28005 :   tree binfo;
   10375        28005 :   base_kind kind;
   10376              : 
   10377        55760 :   binfo = lookup_base (to, from, c_cast_p ? ba_unique : ba_check,
   10378              :                        &kind, complain);
   10379              : 
   10380        28005 :   if (binfo == error_mark_node)
   10381              :     {
   10382           51 :       if (!(complain & tf_error))
   10383              :         return error_mark_node;
   10384              : 
   10385           51 :       inform (input_location, "   in pointer to member function conversion");
   10386           51 :       return size_zero_node;
   10387              :     }
   10388        27954 :   else if (binfo)
   10389              :     {
   10390        27806 :       if (kind != bk_via_virtual)
   10391        27713 :         return BINFO_OFFSET (binfo);
   10392              :       else
   10393              :         /* FROM is a virtual base class of TO.  Issue an error or warning
   10394              :            depending on whether or not this is a reinterpret cast.  */
   10395              :         {
   10396           93 :           if (!(complain & tf_error))
   10397              :             return error_mark_node;
   10398              : 
   10399           78 :           error ("pointer to member conversion via virtual base %qT",
   10400           78 :                  BINFO_TYPE (binfo_from_vbase (binfo)));
   10401              : 
   10402           78 :           return size_zero_node;
   10403              :         }
   10404              :       }
   10405              :   else
   10406              :     return NULL_TREE;
   10407              : }
   10408              : 
   10409              : /* Get difference in deltas for different pointer to member function
   10410              :    types.  If the conversion is invalid and tf_error is not set in
   10411              :    COMPLAIN, returns error_mark_node, otherwise returns an integer
   10412              :    constant of type PTRDIFF_TYPE_NODE and its value is zero if the
   10413              :    conversion is invalid.  If ALLOW_INVERSE_P is true, then allow reverse
   10414              :    conversions as well.  If C_CAST_P is true this conversion is taking
   10415              :    place as part of a C-style cast.
   10416              : 
   10417              :    Note that the naming of FROM and TO is kind of backwards; the return
   10418              :    value is what we add to a TO in order to get a FROM.  They are named
   10419              :    this way because we call this function to find out how to convert from
   10420              :    a pointer to member of FROM to a pointer to member of TO.  */
   10421              : 
   10422              : static tree
   10423        87361 : get_delta_difference (tree from, tree to,
   10424              :                       bool allow_inverse_p,
   10425              :                       bool c_cast_p, tsubst_flags_t complain)
   10426              : {
   10427        87361 :   auto_diagnostic_group d;
   10428        87361 :   tree result;
   10429              : 
   10430        87361 :   if (same_type_ignoring_top_level_qualifiers_p (from, to))
   10431              :     /* Pointer to member of incomplete class is permitted*/
   10432        59504 :     result = size_zero_node;
   10433              :   else
   10434        27857 :     result = get_delta_difference_1 (from, to, c_cast_p, complain);
   10435              : 
   10436        87361 :   if (result == error_mark_node)
   10437              :     return error_mark_node;
   10438              : 
   10439        87346 :   if (!result)
   10440              :   {
   10441          148 :     if (!allow_inverse_p)
   10442              :       {
   10443            0 :         if (!(complain & tf_error))
   10444              :           return error_mark_node;
   10445              : 
   10446            0 :         error_not_base_type (from, to);
   10447            0 :         inform (input_location, "   in pointer to member conversion");
   10448            0 :         result = size_zero_node;
   10449              :       }
   10450              :     else
   10451              :       {
   10452          148 :         result = get_delta_difference_1 (to, from, c_cast_p, complain);
   10453              : 
   10454          148 :         if (result == error_mark_node)
   10455              :           return error_mark_node;
   10456              : 
   10457          148 :         if (result)
   10458          148 :           result = size_diffop_loc (input_location,
   10459              :                                     size_zero_node, result);
   10460              :         else
   10461              :           {
   10462            0 :             if (!(complain & tf_error))
   10463              :               return error_mark_node;
   10464              : 
   10465            0 :             error_not_base_type (from, to);
   10466            0 :             inform (input_location, "   in pointer to member conversion");
   10467            0 :             result = size_zero_node;
   10468              :           }
   10469              :       }
   10470              :   }
   10471              : 
   10472        87346 :   return convert_to_integer (ptrdiff_type_node, result);
   10473        87361 : }
   10474              : 
   10475              : /* Return a constructor for the pointer-to-member-function TYPE using
   10476              :    the other components as specified.  */
   10477              : 
   10478              : tree
   10479        59751 : build_ptrmemfunc1 (tree type, tree delta, tree pfn)
   10480              : {
   10481        59751 :   tree u = NULL_TREE;
   10482        59751 :   tree delta_field;
   10483        59751 :   tree pfn_field;
   10484        59751 :   vec<constructor_elt, va_gc> *v;
   10485              : 
   10486              :   /* Pull the FIELD_DECLs out of the type.  */
   10487        59751 :   pfn_field = TYPE_FIELDS (type);
   10488        59751 :   delta_field = DECL_CHAIN (pfn_field);
   10489              : 
   10490              :   /* Make sure DELTA has the type we want.  */
   10491        59751 :   delta = convert_and_check (input_location, delta_type_node, delta);
   10492              : 
   10493              :   /* Convert to the correct target type if necessary.  */
   10494        59751 :   pfn = fold_convert (TREE_TYPE (pfn_field), pfn);
   10495              : 
   10496              :   /* Finish creating the initializer.  */
   10497        59751 :   vec_alloc (v, 2);
   10498        59751 :   CONSTRUCTOR_APPEND_ELT(v, pfn_field, pfn);
   10499        59751 :   CONSTRUCTOR_APPEND_ELT(v, delta_field, delta);
   10500        59751 :   u = build_constructor (type, v);
   10501        59751 :   TREE_CONSTANT (u) = TREE_CONSTANT (pfn) & TREE_CONSTANT (delta);
   10502        59751 :   TREE_STATIC (u) = (TREE_CONSTANT (u)
   10503        59629 :                      && (initializer_constant_valid_p (pfn, TREE_TYPE (pfn))
   10504              :                          != NULL_TREE)
   10505       119380 :                      && (initializer_constant_valid_p (delta, TREE_TYPE (delta))
   10506              :                          != NULL_TREE));
   10507        59751 :   return u;
   10508              : }
   10509              : 
   10510              : /* Build a constructor for a pointer to member function.  It can be
   10511              :    used to initialize global variables, local variable, or used
   10512              :    as a value in expressions.  TYPE is the POINTER to METHOD_TYPE we
   10513              :    want to be.
   10514              : 
   10515              :    If FORCE is nonzero, then force this conversion, even if
   10516              :    we would rather not do it.  Usually set when using an explicit
   10517              :    cast.  A C-style cast is being processed iff C_CAST_P is true.
   10518              : 
   10519              :    Return error_mark_node, if something goes wrong.  */
   10520              : 
   10521              : tree
   10522        29322 : build_ptrmemfunc (tree type, tree pfn, int force, bool c_cast_p,
   10523              :                   tsubst_flags_t complain)
   10524              : {
   10525        29322 :   tree fn;
   10526        29322 :   tree pfn_type;
   10527        29322 :   tree to_type;
   10528              : 
   10529        29322 :   if (error_operand_p (pfn))
   10530            0 :     return error_mark_node;
   10531              : 
   10532        29322 :   pfn_type = TREE_TYPE (pfn);
   10533        29322 :   to_type = build_ptrmemfunc_type (type);
   10534              : 
   10535              :   /* Handle multiple conversions of pointer to member functions.  */
   10536        29322 :   if (TYPE_PTRMEMFUNC_P (pfn_type))
   10537              :     {
   10538        27556 :       tree delta = NULL_TREE;
   10539        27556 :       tree npfn = NULL_TREE;
   10540        27556 :       tree n;
   10541              : 
   10542        27556 :       if (!force
   10543        27556 :           && !can_convert_arg (to_type, TREE_TYPE (pfn), pfn,
   10544              :                                LOOKUP_NORMAL, complain))
   10545              :         {
   10546            0 :           if (complain & tf_error)
   10547            0 :             error ("invalid conversion to type %qT from type %qT",
   10548              :                    to_type, pfn_type);
   10549              :           else
   10550            0 :             return error_mark_node;
   10551              :         }
   10552              : 
   10553        27556 :       n = get_delta_difference (TYPE_PTRMEMFUNC_OBJECT_TYPE (pfn_type),
   10554        27556 :                                 TYPE_PTRMEMFUNC_OBJECT_TYPE (to_type),
   10555              :                                 force,
   10556              :                                 c_cast_p, complain);
   10557        27556 :       if (n == error_mark_node)
   10558              :         return error_mark_node;
   10559              : 
   10560        27547 :       STRIP_ANY_LOCATION_WRAPPER (pfn);
   10561              : 
   10562              :       /* We don't have to do any conversion to convert a
   10563              :          pointer-to-member to its own type.  But, we don't want to
   10564              :          just return a PTRMEM_CST if there's an explicit cast; that
   10565              :          cast should make the expression an invalid template argument.  */
   10566        27547 :       if (TREE_CODE (pfn) != PTRMEM_CST
   10567        27547 :           && same_type_p (to_type, pfn_type))
   10568              :         return pfn;
   10569              : 
   10570        27547 :       if (TREE_SIDE_EFFECTS (pfn))
   10571           18 :         pfn = save_expr (pfn);
   10572              : 
   10573              :       /* Obtain the function pointer and the current DELTA.  */
   10574        27547 :       if (TREE_CODE (pfn) == PTRMEM_CST)
   10575        27449 :         expand_ptrmemfunc_cst (pfn, &delta, &npfn);
   10576              :       else
   10577              :         {
   10578           98 :           npfn = build_ptrmemfunc_access_expr (pfn, pfn_identifier);
   10579           98 :           delta = build_ptrmemfunc_access_expr (pfn, delta_identifier);
   10580              :         }
   10581              : 
   10582              :       /* Just adjust the DELTA field.  */
   10583        27547 :       gcc_assert  (same_type_ignoring_top_level_qualifiers_p
   10584              :                    (TREE_TYPE (delta), ptrdiff_type_node));
   10585        27547 :       if (!integer_zerop (n))
   10586              :         {
   10587           50 :           if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_delta)
   10588              :             n = cp_build_binary_op (input_location,
   10589              :                                     LSHIFT_EXPR, n, integer_one_node,
   10590              :                                     complain);
   10591           50 :           delta = cp_build_binary_op (input_location,
   10592              :                                       PLUS_EXPR, delta, n, complain);
   10593              :         }
   10594        27547 :       return build_ptrmemfunc1 (to_type, delta, npfn);
   10595              :     }
   10596              : 
   10597              :   /* Handle null pointer to member function conversions.  */
   10598         1766 :   if (null_ptr_cst_p (pfn))
   10599              :     {
   10600          646 :       pfn = cp_build_c_cast (input_location,
   10601          646 :                              TYPE_PTRMEMFUNC_FN_TYPE_RAW (to_type),
   10602              :                              pfn, complain);
   10603          646 :       return build_ptrmemfunc1 (to_type,
   10604              :                                 integer_zero_node,
   10605          646 :                                 pfn);
   10606              :     }
   10607              : 
   10608         1120 :   if (type_unknown_p (pfn))
   10609            0 :     return instantiate_type (type, pfn, complain);
   10610              : 
   10611         1120 :   fn = TREE_OPERAND (pfn, 0);
   10612         1120 :   gcc_assert (TREE_CODE (fn) == FUNCTION_DECL
   10613              :               /* In a template, we will have preserved the
   10614              :                  OFFSET_REF.  */
   10615              :               || (processing_template_decl && TREE_CODE (fn) == OFFSET_REF));
   10616         1120 :   return make_ptrmem_cst (to_type, fn);
   10617              : }
   10618              : 
   10619              : /* Return the DELTA, IDX, PFN, and DELTA2 values for the PTRMEM_CST
   10620              :    given by CST.
   10621              : 
   10622              :    ??? There is no consistency as to the types returned for the above
   10623              :    values.  Some code acts as if it were a sizetype and some as if it were
   10624              :    integer_type_node.  */
   10625              : 
   10626              : void
   10627        59407 : expand_ptrmemfunc_cst (tree cst, tree *delta, tree *pfn)
   10628              : {
   10629        59407 :   tree type = TREE_TYPE (cst);
   10630        59407 :   tree fn = PTRMEM_CST_MEMBER (cst);
   10631        59407 :   tree ptr_class, fn_class;
   10632              : 
   10633        59407 :   gcc_assert (TREE_CODE (fn) == FUNCTION_DECL);
   10634              : 
   10635              :   /* The class that the function belongs to.  */
   10636        59407 :   fn_class = DECL_CONTEXT (fn);
   10637              : 
   10638              :   /* The class that we're creating a pointer to member of.  */
   10639        59407 :   ptr_class = TYPE_PTRMEMFUNC_OBJECT_TYPE (type);
   10640              : 
   10641              :   /* First, calculate the adjustment to the function's class.  */
   10642        59407 :   *delta = get_delta_difference (fn_class, ptr_class, /*force=*/0,
   10643              :                                  /*c_cast_p=*/0, tf_warning_or_error);
   10644              : 
   10645        59407 :   if (!DECL_VIRTUAL_P (fn))
   10646              :     {
   10647        58294 :       tree t = build_addr_func (fn, tf_warning_or_error);
   10648        58294 :       if (TREE_CODE (t) == ADDR_EXPR)
   10649        58294 :         SET_EXPR_LOCATION (t, PTRMEM_CST_LOCATION (cst));
   10650        58294 :       *pfn = convert (TYPE_PTRMEMFUNC_FN_TYPE (type), t);
   10651              :     }
   10652              :   else
   10653              :     {
   10654              :       /* If we're dealing with a virtual function, we have to adjust 'this'
   10655              :          again, to point to the base which provides the vtable entry for
   10656              :          fn; the call will do the opposite adjustment.  */
   10657         1113 :       tree orig_class = DECL_CONTEXT (fn);
   10658         1113 :       tree binfo = binfo_or_else (orig_class, fn_class);
   10659         1113 :       *delta = fold_build2 (PLUS_EXPR, TREE_TYPE (*delta),
   10660              :                             *delta, BINFO_OFFSET (binfo));
   10661              : 
   10662              :       /* We set PFN to the vtable offset at which the function can be
   10663              :          found, plus one (unless ptrmemfunc_vbit_in_delta, in which
   10664              :          case delta is shifted left, and then incremented).  */
   10665         1113 :       *pfn = DECL_VINDEX (fn);
   10666         1113 :       *pfn = fold_build2 (MULT_EXPR, integer_type_node, *pfn,
   10667              :                           TYPE_SIZE_UNIT (vtable_entry_type));
   10668              : 
   10669         1113 :       switch (TARGET_PTRMEMFUNC_VBIT_LOCATION)
   10670              :         {
   10671         1113 :         case ptrmemfunc_vbit_in_pfn:
   10672         1113 :           *pfn = fold_build2 (PLUS_EXPR, integer_type_node, *pfn,
   10673              :                               integer_one_node);
   10674         1113 :           break;
   10675              : 
   10676              :         case ptrmemfunc_vbit_in_delta:
   10677              :           *delta = fold_build2 (LSHIFT_EXPR, TREE_TYPE (*delta),
   10678              :                                 *delta, integer_one_node);
   10679              :           *delta = fold_build2 (PLUS_EXPR, TREE_TYPE (*delta),
   10680              :                                 *delta, integer_one_node);
   10681              :           break;
   10682              : 
   10683              :         default:
   10684              :           gcc_unreachable ();
   10685              :         }
   10686              : 
   10687         1113 :       *pfn = fold_convert (TYPE_PTRMEMFUNC_FN_TYPE (type), *pfn);
   10688              :     }
   10689        59407 : }
   10690              : 
   10691              : /* Return an expression for PFN from the pointer-to-member function
   10692              :    given by T.  */
   10693              : 
   10694              : static tree
   10695        83804 : pfn_from_ptrmemfunc (tree t)
   10696              : {
   10697        83804 :   if (TREE_CODE (t) == PTRMEM_CST)
   10698              :     {
   10699          200 :       tree delta;
   10700          200 :       tree pfn;
   10701              : 
   10702          200 :       expand_ptrmemfunc_cst (t, &delta, &pfn);
   10703          200 :       if (pfn)
   10704          200 :         return pfn;
   10705              :     }
   10706              : 
   10707        83604 :   return build_ptrmemfunc_access_expr (t, pfn_identifier);
   10708              : }
   10709              : 
   10710              : /* Return an expression for DELTA from the pointer-to-member function
   10711              :    given by T.  */
   10712              : 
   10713              : static tree
   10714        83804 : delta_from_ptrmemfunc (tree t)
   10715              : {
   10716        83804 :   if (TREE_CODE (t) == PTRMEM_CST)
   10717              :     {
   10718          200 :       tree delta;
   10719          200 :       tree pfn;
   10720              : 
   10721          200 :       expand_ptrmemfunc_cst (t, &delta, &pfn);
   10722          200 :       if (delta)
   10723          200 :         return delta;
   10724              :     }
   10725              : 
   10726        83604 :   return build_ptrmemfunc_access_expr (t, delta_identifier);
   10727              : }
   10728              : 
   10729              : /* Convert value RHS to type TYPE as preparation for an assignment to
   10730              :    an lvalue of type TYPE.  ERRTYPE indicates what kind of error the
   10731              :    implicit conversion is.  If FNDECL is non-NULL, we are doing the
   10732              :    conversion in order to pass the PARMNUMth argument of FNDECL.
   10733              :    If FNDECL is NULL, we are doing the conversion in function pointer
   10734              :    argument passing, conversion in initialization, etc. */
   10735              : 
   10736              : static tree
   10737    174860547 : convert_for_assignment (tree type, tree rhs,
   10738              :                         impl_conv_rhs errtype, tree fndecl, int parmnum,
   10739              :                         tsubst_flags_t complain, int flags)
   10740              : {
   10741    174860547 :   tree rhstype;
   10742    174860547 :   enum tree_code coder;
   10743              : 
   10744    174860547 :   location_t rhs_loc = cp_expr_loc_or_input_loc (rhs);
   10745    174860547 :   bool has_loc = EXPR_LOCATION (rhs) != UNKNOWN_LOCATION;
   10746              :   /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue,
   10747              :      but preserve location wrappers.  */
   10748    174860547 :   if (TREE_CODE (rhs) == NON_LVALUE_EXPR
   10749    174860547 :       && !location_wrapper_p (rhs))
   10750         8465 :     rhs = TREE_OPERAND (rhs, 0);
   10751              : 
   10752              :   /* Handle [dcl.init.list] direct-list-initialization from
   10753              :      single element of enumeration with a fixed underlying type.  */
   10754    174860547 :   if (is_direct_enum_init (type, rhs))
   10755              :     {
   10756           20 :       tree elt = CONSTRUCTOR_ELT (rhs, 0)->value;
   10757           20 :       if (check_narrowing (ENUM_UNDERLYING_TYPE (type), elt, complain))
   10758              :         {
   10759           11 :           warning_sentinel w (warn_useless_cast);
   10760           11 :           warning_sentinel w2 (warn_ignored_qualifiers);
   10761           11 :           rhs = cp_build_c_cast (rhs_loc, type, elt, complain);
   10762           11 :         }
   10763              :       else
   10764            9 :         rhs = error_mark_node;
   10765              :     }
   10766              : 
   10767    174860547 :   rhstype = TREE_TYPE (rhs);
   10768    174860547 :   coder = TREE_CODE (rhstype);
   10769              : 
   10770      1353723 :   if (VECTOR_TYPE_P (type) && coder == VECTOR_TYPE
   10771    176214164 :       && vector_types_convertible_p (type, rhstype, true))
   10772              :     {
   10773      1353608 :       rhs = mark_rvalue_use (rhs);
   10774      1353608 :       return convert (type, rhs);
   10775              :     }
   10776              : 
   10777    173506939 :   if (rhs == error_mark_node || rhstype == error_mark_node)
   10778              :     return error_mark_node;
   10779    173506930 :   if (TREE_CODE (rhs) == TREE_LIST && TREE_VALUE (rhs) == error_mark_node)
   10780              :     return error_mark_node;
   10781              : 
   10782              :   /* The RHS of an assignment cannot have void type.  */
   10783    173506930 :   if (coder == VOID_TYPE)
   10784              :     {
   10785           50 :       if (complain & tf_error)
   10786           30 :         error_at (rhs_loc, "void value not ignored as it ought to be");
   10787           50 :       return error_mark_node;
   10788              :     }
   10789              : 
   10790    173506880 :   if (c_dialect_objc ())
   10791              :     {
   10792            0 :       int parmno;
   10793            0 :       tree selector;
   10794            0 :       tree rname = fndecl;
   10795              : 
   10796            0 :       switch (errtype)
   10797              :         {
   10798              :           case ICR_ASSIGN:
   10799              :             parmno = -1;
   10800              :             break;
   10801            0 :           case ICR_INIT:
   10802            0 :             parmno = -2;
   10803            0 :             break;
   10804            0 :           default:
   10805            0 :             selector = objc_message_selector ();
   10806            0 :             parmno = parmnum;
   10807            0 :             if (selector && parmno > 1)
   10808              :               {
   10809            0 :                 rname = selector;
   10810            0 :                 parmno -= 1;
   10811              :               }
   10812              :         }
   10813              : 
   10814            0 :       if (objc_compare_types (type, rhstype, parmno, rname))
   10815              :         {
   10816            0 :           rhs = mark_rvalue_use (rhs);
   10817            0 :           return convert (type, rhs);
   10818              :         }
   10819              :     }
   10820              : 
   10821              :   /* [expr.ass]
   10822              : 
   10823              :      The expression is implicitly converted (clause _conv_) to the
   10824              :      cv-unqualified type of the left operand.
   10825              : 
   10826              :      We allow bad conversions here because by the time we get to this point
   10827              :      we are committed to doing the conversion.  If we end up doing a bad
   10828              :      conversion, convert_like will complain.  */
   10829    173506880 :   if (!can_convert_arg_bad (type, rhstype, rhs, flags, complain))
   10830              :     {
   10831              :       /* When -Wno-pmf-conversions is use, we just silently allow
   10832              :          conversions from pointers-to-members to plain pointers.  If
   10833              :          the conversion doesn't work, cp_convert will complain.  */
   10834         1592 :       if (!warn_pmf2ptr
   10835            9 :           && TYPE_PTR_P (type)
   10836         1601 :           && TYPE_PTRMEMFUNC_P (rhstype))
   10837            9 :         rhs = cp_convert (strip_top_quals (type), rhs, complain);
   10838              :       else
   10839              :         {
   10840         1583 :           if (complain & tf_error)
   10841              :             {
   10842         1310 :               auto_diagnostic_group d;
   10843              : 
   10844              :               /* If the right-hand side has unknown type, then it is an
   10845              :                  overloaded function.  Call instantiate_type to get error
   10846              :                  messages.  */
   10847         1310 :               if (rhstype == unknown_type_node)
   10848              :                 {
   10849          225 :                   tree r = instantiate_type (type, rhs, tf_warning_or_error);
   10850              :                   /* -fpermissive might allow this; recurse.  */
   10851          225 :                   if (!seen_error ())
   10852           15 :                     return convert_for_assignment (type, r, errtype, fndecl,
   10853              :                                                    parmnum, complain, flags);
   10854              :                 }
   10855         1085 :               else if (fndecl)
   10856           92 :                 complain_about_bad_argument (rhs_loc,
   10857              :                                              rhstype, type,
   10858              :                                              fndecl, parmnum);
   10859              :               else
   10860              :                 {
   10861          993 :                   range_label_for_type_mismatch label (rhstype, type);
   10862          993 :                   gcc_rich_location richloc
   10863              :                     (rhs_loc,
   10864              :                      has_loc ? &label : NULL,
   10865          993 :                      has_loc ? highlight_colors::percent_h : NULL);
   10866              : 
   10867          993 :                   switch (errtype)
   10868              :                     {
   10869            0 :                     case ICR_DEFAULT_ARGUMENT:
   10870            0 :                       error_at (&richloc,
   10871              :                                 "cannot convert %qH to %qI in default argument",
   10872              :                                 rhstype, type);
   10873            0 :                       break;
   10874            6 :                     case ICR_ARGPASS:
   10875            6 :                       error_at (&richloc,
   10876              :                                 "cannot convert %qH to %qI in argument passing",
   10877              :                                 rhstype, type);
   10878            6 :                       break;
   10879            0 :                     case ICR_CONVERTING:
   10880            0 :                       error_at (&richloc, "cannot convert %qH to %qI",
   10881              :                                 rhstype, type);
   10882            0 :                       break;
   10883          555 :                     case ICR_INIT:
   10884          555 :                       error_at (&richloc,
   10885              :                                 "cannot convert %qH to %qI in initialization",
   10886              :                                 rhstype, type);
   10887          555 :                       break;
   10888           18 :                     case ICR_RETURN:
   10889           18 :                       error_at (&richloc, "cannot convert %qH to %qI in return",
   10890              :                                 rhstype, type);
   10891           18 :                       break;
   10892          414 :                     case ICR_ASSIGN:
   10893          414 :                       error_at (&richloc,
   10894              :                                 "cannot convert %qH to %qI in assignment",
   10895              :                                 rhstype, type);
   10896          414 :                       break;
   10897            0 :                     default:
   10898            0 :                       gcc_unreachable();
   10899              :                   }
   10900          993 :                 }
   10901              : 
   10902              :               /* See if we can be more helpful.  */
   10903         1295 :               maybe_show_nonconverting_candidate (type, rhstype, rhs, flags);
   10904              : 
   10905         1295 :               if (TYPE_PTR_P (rhstype)
   10906          413 :                   && TYPE_PTR_P (type)
   10907          398 :                   && CLASS_TYPE_P (TREE_TYPE (rhstype))
   10908          280 :                   && CLASS_TYPE_P (TREE_TYPE (type))
   10909         1359 :                   && !COMPLETE_TYPE_P (TREE_TYPE (rhstype)))
   10910            3 :                 inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL
   10911              :                                               (TREE_TYPE (rhstype))),
   10912            3 :                         "class type %qT is incomplete", TREE_TYPE (rhstype));
   10913         1310 :             }
   10914         1568 :           return error_mark_node;
   10915              :         }
   10916              :     }
   10917    173505297 :   if (warn_suggest_attribute_format)
   10918              :     {
   10919         2383 :       const enum tree_code codel = TREE_CODE (type);
   10920         2383 :       if ((codel == POINTER_TYPE || codel == REFERENCE_TYPE)
   10921          596 :           && coder == codel
   10922          508 :           && check_missing_format_attribute (type, rhstype)
   10923         2401 :           && (complain & tf_warning))
   10924           18 :         switch (errtype)
   10925              :           {
   10926            0 :             case ICR_ARGPASS:
   10927            0 :             case ICR_DEFAULT_ARGUMENT:
   10928            0 :               if (fndecl)
   10929            0 :                 warning (OPT_Wsuggest_attribute_format,
   10930              :                          "parameter %qP of %qD might be a candidate "
   10931              :                          "for a format attribute", parmnum, fndecl);
   10932              :               else
   10933            0 :                 warning (OPT_Wsuggest_attribute_format,
   10934              :                          "parameter might be a candidate "
   10935              :                          "for a format attribute");
   10936              :               break;
   10937            0 :             case ICR_CONVERTING:
   10938            0 :               warning (OPT_Wsuggest_attribute_format,
   10939              :                        "target of conversion might be a candidate "
   10940              :                        "for a format attribute");
   10941            0 :               break;
   10942            6 :             case ICR_INIT:
   10943            6 :               warning (OPT_Wsuggest_attribute_format,
   10944              :                        "target of initialization might be a candidate "
   10945              :                        "for a format attribute");
   10946            6 :               break;
   10947            6 :             case ICR_RETURN:
   10948            6 :               warning (OPT_Wsuggest_attribute_format,
   10949              :                        "return type might be a candidate "
   10950              :                        "for a format attribute");
   10951            6 :               break;
   10952            6 :             case ICR_ASSIGN:
   10953            6 :               warning (OPT_Wsuggest_attribute_format,
   10954              :                        "left-hand side of assignment might be a candidate "
   10955              :                        "for a format attribute");
   10956            6 :               break;
   10957            0 :             default:
   10958            0 :               gcc_unreachable();
   10959              :           }
   10960              :     }
   10961              : 
   10962    173505297 :   if (TREE_CODE (type) == BOOLEAN_TYPE)
   10963     35392596 :     maybe_warn_unparenthesized_assignment (rhs, /*nested_p=*/true, complain);
   10964              : 
   10965    173505297 :   if (complain & tf_warning)
   10966    171064708 :     warn_for_address_of_packed_member (type, rhs);
   10967              : 
   10968    173505297 :   return perform_implicit_conversion_flags (strip_top_quals (type), rhs,
   10969    173505297 :                                             complain, flags);
   10970              : }
   10971              : 
   10972              : /* Convert RHS to be of type TYPE.
   10973              :    If EXP is nonzero, it is the target of the initialization.
   10974              :    ERRTYPE indicates what kind of error the implicit conversion is.
   10975              : 
   10976              :    Two major differences between the behavior of
   10977              :    `convert_for_assignment' and `convert_for_initialization'
   10978              :    are that references are bashed in the former, while
   10979              :    copied in the latter, and aggregates are assigned in
   10980              :    the former (operator=) while initialized in the
   10981              :    latter (X(X&)).
   10982              : 
   10983              :    If using constructor make sure no conversion operator exists, if one does
   10984              :    exist, an ambiguity exists.  */
   10985              : 
   10986              : tree
   10987    161676443 : convert_for_initialization (tree exp, tree type, tree rhs, int flags,
   10988              :                             impl_conv_rhs errtype, tree fndecl, int parmnum,
   10989              :                             tsubst_flags_t complain)
   10990              : {
   10991    161676443 :   enum tree_code codel = TREE_CODE (type);
   10992    161676443 :   tree rhstype;
   10993    161676443 :   enum tree_code coder;
   10994              : 
   10995              :   /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
   10996              :      Strip such NOP_EXPRs, since RHS is used in non-lvalue context.  */
   10997    161676443 :   if (TREE_CODE (rhs) == NOP_EXPR
   10998      5657915 :       && TREE_TYPE (rhs) == TREE_TYPE (TREE_OPERAND (rhs, 0))
   10999    162148810 :       && codel != REFERENCE_TYPE)
   11000       472367 :     rhs = TREE_OPERAND (rhs, 0);
   11001              : 
   11002    161676443 :   if (type == error_mark_node
   11003    161676400 :       || rhs == error_mark_node
   11004    323352775 :       || (TREE_CODE (rhs) == TREE_LIST && TREE_VALUE (rhs) == error_mark_node))
   11005              :     return error_mark_node;
   11006              : 
   11007    161676332 :   if (MAYBE_CLASS_TYPE_P (non_reference (type)))
   11008              :     ;
   11009    148011922 :   else if ((TREE_CODE (TREE_TYPE (rhs)) == ARRAY_TYPE
   11010      2075776 :             && TREE_CODE (type) != ARRAY_TYPE
   11011      2075776 :             && (!TYPE_REF_P (type)
   11012          878 :                 || TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE))
   11013    145937021 :            || (TREE_CODE (TREE_TYPE (rhs)) == FUNCTION_TYPE
   11014        24496 :                && !TYPE_REFFN_P (type))
   11015    293925393 :            || TREE_CODE (TREE_TYPE (rhs)) == METHOD_TYPE)
   11016      2098457 :     rhs = decay_conversion (rhs, complain);
   11017              : 
   11018    161676332 :   rhstype = TREE_TYPE (rhs);
   11019    161676332 :   coder = TREE_CODE (rhstype);
   11020              : 
   11021    161676332 :   if (coder == ERROR_MARK)
   11022            9 :     return error_mark_node;
   11023              : 
   11024              :   /* We accept references to incomplete types, so we can
   11025              :      return here before checking if RHS is of complete type.  */
   11026              : 
   11027    161676323 :   if (codel == REFERENCE_TYPE)
   11028              :     {
   11029      5712776 :       auto_diagnostic_group d;
   11030              :       /* This should eventually happen in convert_arguments.  */
   11031      5712776 :       int savew = 0, savee = 0;
   11032              : 
   11033      5712776 :       if (fndecl)
   11034       279594 :         savew = warningcount + werrorcount, savee = errorcount;
   11035      5712776 :       rhs = initialize_reference (type, rhs, flags, complain);
   11036              : 
   11037      5712776 :       if (fndecl
   11038      5712776 :           && (warningcount + werrorcount > savew || errorcount > savee))
   11039           36 :         inform (get_fndecl_argument_location (fndecl, parmnum),
   11040              :                 "in passing argument %P of %qD", parmnum, fndecl);
   11041      5712776 :       return rhs;
   11042      5712776 :     }
   11043              : 
   11044    155963547 :   if (exp != 0)
   11045      4048037 :     exp = require_complete_type (exp, complain);
   11046    155963547 :   if (exp == error_mark_node)
   11047              :     return error_mark_node;
   11048              : 
   11049    155963547 :   type = complete_type (type);
   11050              : 
   11051    155963547 :   if (DIRECT_INIT_EXPR_P (type, rhs))
   11052              :     /* Don't try to do copy-initialization if we already have
   11053              :        direct-initialization.  */
   11054              :     return rhs;
   11055              : 
   11056    155962398 :   if (MAYBE_CLASS_TYPE_P (type))
   11057      9804948 :     return perform_implicit_conversion_flags (type, rhs, complain, flags);
   11058              : 
   11059    146157450 :   return convert_for_assignment (type, rhs, errtype, fndecl, parmnum,
   11060    146157450 :                                  complain, flags);
   11061              : }
   11062              : 
   11063              : /* If RETVAL is the address of, or a reference to, a local variable or
   11064              :    temporary give an appropriate warning and return true.  */
   11065              : 
   11066              : static bool
   11067     41575806 : maybe_warn_about_returning_address_of_local (tree retval, location_t loc)
   11068              : {
   11069     41576776 :   tree valtype = TREE_TYPE (DECL_RESULT (current_function_decl));
   11070     41576776 :   tree whats_returned = fold_for_warn (retval);
   11071     41576776 :   if (!loc)
   11072     41576776 :     loc = cp_expr_loc_or_input_loc (retval);
   11073              : 
   11074     50645244 :   for (;;)
   11075              :     {
   11076     50645244 :       if (TREE_CODE (whats_returned) == COMPOUND_EXPR)
   11077       748763 :         whats_returned = TREE_OPERAND (whats_returned, 1);
   11078     49896481 :       else if (CONVERT_EXPR_P (whats_returned)
   11079     41593434 :                || TREE_CODE (whats_returned) == NON_LVALUE_EXPR)
   11080      8319705 :         whats_returned = TREE_OPERAND (whats_returned, 0);
   11081              :       else
   11082              :         break;
   11083              :     }
   11084              : 
   11085     41576776 :   if (TREE_CODE (whats_returned) == TARGET_EXPR
   11086     41576776 :       && is_std_init_list (TREE_TYPE (whats_returned)))
   11087              :     {
   11088           16 :       tree init = TARGET_EXPR_INITIAL (whats_returned);
   11089           16 :       if (TREE_CODE (init) == CONSTRUCTOR)
   11090              :         /* Pull out the array address.  */
   11091            7 :         whats_returned = CONSTRUCTOR_ELT (init, 0)->value;
   11092            9 :       else if (TREE_CODE (init) == INDIRECT_REF)
   11093              :         /* The source of a trivial copy looks like *(T*)&var.  */
   11094            6 :         whats_returned = TREE_OPERAND (init, 0);
   11095              :       else
   11096              :         return false;
   11097           13 :       STRIP_NOPS (whats_returned);
   11098              :     }
   11099              : 
   11100              :   /* As a special case, we handle a call to std::move or std::forward.  */
   11101     41576773 :   if (TREE_CODE (whats_returned) == CALL_EXPR
   11102     41576773 :       && (is_std_move_p (whats_returned)
   11103      9889442 :           || is_std_forward_p (whats_returned)))
   11104              :     {
   11105          958 :       tree arg = CALL_EXPR_ARG (whats_returned, 0);
   11106          958 :       return maybe_warn_about_returning_address_of_local (arg, loc);
   11107              :     }
   11108              : 
   11109     41575815 :   if (TREE_CODE (whats_returned) != ADDR_EXPR)
   11110              :     return false;
   11111       871758 :   whats_returned = TREE_OPERAND (whats_returned, 0);
   11112              : 
   11113       871758 :   while (TREE_CODE (whats_returned) == COMPONENT_REF
   11114      1697482 :          || TREE_CODE (whats_returned) == ARRAY_REF)
   11115       825724 :     whats_returned = TREE_OPERAND (whats_returned, 0);
   11116              : 
   11117       871758 :   if (TREE_CODE (whats_returned) == AGGR_INIT_EXPR
   11118       871758 :       || TREE_CODE (whats_returned) == TARGET_EXPR)
   11119              :     {
   11120           50 :       if (TYPE_REF_P (valtype))
   11121              :         /* P2748 made this an error in C++26.  */
   11122           72 :         emit_diagnostic ((cxx_dialect >= cxx26
   11123              :                           ? diagnostics::kind::permerror
   11124              :                           : diagnostics::kind::warning),
   11125           41 :                          loc, OPT_Wreturn_local_addr,
   11126              :                          "returning reference to temporary");
   11127            9 :       else if (TYPE_PTR_P (valtype))
   11128            3 :         warning_at (loc, OPT_Wreturn_local_addr,
   11129              :                     "returning pointer to temporary");
   11130            6 :       else if (is_std_init_list (valtype))
   11131            6 :         warning_at (loc, OPT_Winit_list_lifetime,
   11132              :                     "returning temporary %<initializer_list%> does not extend "
   11133              :                     "the lifetime of the underlying array");
   11134           50 :       return true;
   11135              :     }
   11136              : 
   11137       871708 :   STRIP_ANY_LOCATION_WRAPPER (whats_returned);
   11138              : 
   11139       871708 :   if (DECL_P (whats_returned)
   11140       108302 :       && DECL_NAME (whats_returned)
   11141       108302 :       && DECL_FUNCTION_SCOPE_P (whats_returned)
   11142        11939 :       && !is_capture_proxy (whats_returned)
   11143       883617 :       && !(TREE_STATIC (whats_returned)
   11144          155 :            || TREE_PUBLIC (whats_returned)))
   11145              :     {
   11146          108 :       if (DECL_DECOMPOSITION_P (whats_returned)
   11147           39 :           && !DECL_DECOMP_IS_BASE (whats_returned)
   11148          194 :           && DECL_HAS_VALUE_EXPR_P (whats_returned))
   11149              :         {
   11150              :           /* When returning address of a structured binding, if the structured
   11151              :              binding is not a reference, continue normally, if it is a
   11152              :              reference, recurse on the initializer of the structured
   11153              :              binding.  */
   11154           39 :           tree base = DECL_DECOMP_BASE (whats_returned);
   11155           39 :           if (TYPE_REF_P (TREE_TYPE (base)))
   11156              :             {
   11157           15 :               if (tree init = DECL_INITIAL (base))
   11158              :                 return maybe_warn_about_returning_address_of_local (init, loc);
   11159              :               else
   11160              :                 return false;
   11161              :             }
   11162              :         }
   11163          140 :       bool w = false;
   11164          140 :       auto_diagnostic_group d;
   11165          140 :       if (TYPE_REF_P (valtype))
   11166           89 :         w = warning_at (loc, OPT_Wreturn_local_addr,
   11167              :                         "reference to local variable %qD returned",
   11168              :                         whats_returned);
   11169           51 :       else if (is_std_init_list (valtype))
   11170            3 :         w = warning_at (loc, OPT_Winit_list_lifetime,
   11171              :                         "returning local %<initializer_list%> variable %qD "
   11172              :                         "does not extend the lifetime of the underlying array",
   11173              :                         whats_returned);
   11174           48 :       else if (POINTER_TYPE_P (valtype)
   11175           42 :                && TREE_CODE (whats_returned) == LABEL_DECL)
   11176            6 :         w = warning_at (loc, OPT_Wreturn_local_addr,
   11177              :                         "address of label %qD returned",
   11178              :                         whats_returned);
   11179           42 :       else if (POINTER_TYPE_P (valtype))
   11180           36 :         w = warning_at (loc, OPT_Wreturn_local_addr,
   11181              :                         "address of local variable %qD returned",
   11182              :                         whats_returned);
   11183          134 :       if (w)
   11184          111 :         inform (DECL_SOURCE_LOCATION (whats_returned),
   11185              :                 "declared here");
   11186          140 :       return true;
   11187          140 :     }
   11188              : 
   11189              :   return false;
   11190              : }
   11191              : 
   11192              : /* Returns true if DECL is in the std namespace.  */
   11193              : 
   11194              : bool
   11195     81548260 : decl_in_std_namespace_p (tree decl)
   11196              : {
   11197     94907624 :   while (decl)
   11198              :     {
   11199     94510673 :       decl = decl_namespace_context (decl);
   11200     94510673 :       if (DECL_NAMESPACE_STD_P (decl))
   11201              :         return true;
   11202              :       /* Allow inline namespaces inside of std namespace, e.g. with
   11203              :          --enable-symvers=gnu-versioned-namespace std::forward would be
   11204              :          actually std::_8::forward.  */
   11205     44546355 :       if (!DECL_NAMESPACE_INLINE_P (decl))
   11206              :         return false;
   11207     13359364 :       decl = CP_DECL_CONTEXT (decl);
   11208              :     }
   11209              :   return false;
   11210              : }
   11211              : 
   11212              : /* Returns true if FN, a CALL_EXPR, is a call to std::forward.  */
   11213              : 
   11214              : static bool
   11215      9889442 : is_std_forward_p (tree fn)
   11216              : {
   11217              :   /* std::forward only takes one argument.  */
   11218      9889442 :   if (call_expr_nargs (fn) != 1)
   11219              :     return false;
   11220              : 
   11221      4555759 :   tree fndecl = cp_get_callee_fndecl_nofold (fn);
   11222      4555759 :   if (!decl_in_std_namespace_p (fndecl))
   11223              :     return false;
   11224              : 
   11225      1719226 :   tree name = DECL_NAME (fndecl);
   11226      1719226 :   return name && id_equal (name, "forward");
   11227              : }
   11228              : 
   11229              : /* Returns true if FN, a CALL_EXPR, is a call to std::move.  */
   11230              : 
   11231              : static bool
   11232      9896927 : is_std_move_p (tree fn)
   11233              : {
   11234              :   /* std::move only takes one argument.  */
   11235      9896927 :   if (call_expr_nargs (fn) != 1)
   11236              :     return false;
   11237              : 
   11238      4562407 :   tree fndecl = cp_get_callee_fndecl_nofold (fn);
   11239      4562407 :   if (!decl_in_std_namespace_p (fndecl))
   11240              :     return false;
   11241              : 
   11242      1725396 :   tree name = DECL_NAME (fndecl);
   11243      1725396 :   return name && id_equal (name, "move");
   11244              : }
   11245              : 
   11246              : /* Returns true if RETVAL is a good candidate for the NRVO as per
   11247              :    [class.copy.elision].  FUNCTYPE is the type the function is declared
   11248              :    to return.  */
   11249              : 
   11250              : static bool
   11251     53878472 : can_do_nrvo_p (tree retval, tree functype)
   11252              : {
   11253     53878472 :   if (functype == error_mark_node)
   11254              :     return false;
   11255     53878426 :   if (retval)
   11256     52268786 :     STRIP_ANY_LOCATION_WRAPPER (retval);
   11257     53878426 :   tree result = DECL_RESULT (current_function_decl);
   11258     53878426 :   return (retval != NULL_TREE
   11259     52268786 :           && !processing_template_decl
   11260              :           /* Must be a local, automatic variable.  */
   11261     43005616 :           && VAR_P (retval)
   11262      3783909 :           && DECL_CONTEXT (retval) == current_function_decl
   11263      2767439 :           && !TREE_STATIC (retval)
   11264              :           /* And not a lambda or anonymous union proxy.  */
   11265      2764721 :           && !DECL_HAS_VALUE_EXPR_P (retval)
   11266      2764455 :           && (DECL_ALIGN (retval) <= DECL_ALIGN (result))
   11267              :           /* The cv-unqualified type of the returned value must be the
   11268              :              same as the cv-unqualified return type of the
   11269              :              function.  */
   11270      2764333 :           && same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (retval)),
   11271              :                           TYPE_MAIN_VARIANT (functype))
   11272              :           /* And the returned value must be non-volatile.  */
   11273     56620720 :           && !TYPE_VOLATILE (TREE_TYPE (retval)));
   11274              : }
   11275              : 
   11276              : /* True if we would like to perform NRVO, i.e. can_do_nrvo_p is true and we
   11277              :    would otherwise return in memory.  */
   11278              : 
   11279              : static bool
   11280     53878102 : want_nrvo_p (tree retval, tree functype)
   11281              : {
   11282     53878102 :   return (can_do_nrvo_p (retval, functype)
   11283     53878102 :           && aggregate_value_p (functype, current_function_decl));
   11284              : }
   11285              : 
   11286              : /* Like can_do_nrvo_p, but we check if we're trying to move a class
   11287              :    prvalue.  */
   11288              : 
   11289              : static bool
   11290         1399 : can_elide_copy_prvalue_p (tree retval, tree functype)
   11291              : {
   11292         1399 :   if (functype == error_mark_node)
   11293              :     return false;
   11294         1399 :   if (retval)
   11295         1399 :     STRIP_ANY_LOCATION_WRAPPER (retval);
   11296         1399 :   return (retval != NULL_TREE
   11297         1399 :           && !glvalue_p (retval)
   11298          135 :           && same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (retval)),
   11299              :                           TYPE_MAIN_VARIANT (functype))
   11300         1507 :           && !TYPE_VOLATILE (TREE_TYPE (retval)));
   11301              : }
   11302              : 
   11303              : /* If we should treat RETVAL, an expression being returned, as if it were
   11304              :    designated by an rvalue, returns it adjusted accordingly; otherwise, returns
   11305              :    NULL_TREE.  See [class.copy.elision].  RETURN_P is true if this is a return
   11306              :    context (rather than throw).  */
   11307              : 
   11308              : tree
   11309     10649410 : treat_lvalue_as_rvalue_p (tree expr, bool return_p)
   11310              : {
   11311     10649410 :   if (cxx_dialect == cxx98)
   11312              :     return NULL_TREE;
   11313              : 
   11314     10641322 :   tree retval = expr;
   11315     10641322 :   STRIP_ANY_LOCATION_WRAPPER (retval);
   11316     10641322 :   if (REFERENCE_REF_P (retval))
   11317       478144 :     retval = TREE_OPERAND (retval, 0);
   11318              : 
   11319              :   /* An implicitly movable entity is a variable of automatic storage duration
   11320              :      that is either a non-volatile object or (C++20) an rvalue reference to a
   11321              :      non-volatile object type.  */
   11322     10641322 :   if (!(((VAR_P (retval) && !DECL_HAS_VALUE_EXPR_P (retval))
   11323      9429808 :          || TREE_CODE (retval) == PARM_DECL)
   11324      1735535 :         && !TREE_STATIC (retval)
   11325      1650504 :         && !CP_TYPE_VOLATILE_P (non_reference (TREE_TYPE (retval)))
   11326      1650499 :         && (TREE_CODE (TREE_TYPE (retval)) != REFERENCE_TYPE
   11327       113419 :             || (cxx_dialect >= cxx20
   11328       112871 :                 && TYPE_REF_IS_RVALUE (TREE_TYPE (retval))))))
   11329      9103395 :     return NULL_TREE;
   11330              : 
   11331              :   /* If the expression in a return or co_return statement is a (possibly
   11332              :      parenthesized) id-expression that names an implicitly movable entity
   11333              :      declared in the body or parameter-declaration-clause of the innermost
   11334              :      enclosing function or lambda-expression, */
   11335      1537927 :   if (return_p)
   11336              :     {
   11337      1528807 :       if (DECL_CONTEXT (retval) != current_function_decl)
   11338              :         return NULL_TREE;
   11339      1528740 :       expr = move (expr);
   11340      1528740 :       if (expr == error_mark_node)
   11341              :         return NULL_TREE;
   11342      1528738 :       return set_implicit_rvalue_p (expr);
   11343              :     }
   11344              : 
   11345              :   /* if the id-expression (possibly parenthesized) is the operand of
   11346              :      a throw-expression, and names an implicitly movable entity that belongs
   11347              :      to a scope that does not contain the compound-statement of the innermost
   11348              :      lambda-expression, try-block, or function-try-block (if any) whose
   11349              :      compound-statement or ctor-initializer contains the throw-expression.  */
   11350              : 
   11351              :   /* C++20 added move on throw of parms.  */
   11352         9120 :   if (TREE_CODE (retval) == PARM_DECL && cxx_dialect < cxx20)
   11353              :     return NULL_TREE;
   11354              : 
   11355              :   /* We don't check for lambda-expression here, because we should not get past
   11356              :      the DECL_HAS_VALUE_EXPR_P check above.  */
   11357         9104 :   for (cp_binding_level *b = current_binding_level;
   11358         9200 :        b->kind != sk_namespace; b = b->level_chain)
   11359              :     {
   11360         9198 :       for (tree decl = b->names; decl; decl = TREE_CHAIN (decl))
   11361          103 :         if (decl == retval)
   11362           91 :           return set_implicit_rvalue_p (move (expr));
   11363         9095 :       if (b->kind == sk_try)
   11364              :         return NULL_TREE;
   11365              :     }
   11366              : 
   11367           14 :   return set_implicit_rvalue_p (move (expr));
   11368              : }
   11369              : 
   11370              : /* Warn about dubious usage of std::move (in a return statement, if RETURN_P
   11371              :    is true).  EXPR is the std::move expression; TYPE is the type of the object
   11372              :    being initialized.  */
   11373              : 
   11374              : void
   11375    147479148 : maybe_warn_pessimizing_move (tree expr, tree type, bool return_p)
   11376              : {
   11377    147479148 :   if (!(warn_pessimizing_move || warn_redundant_move))
   11378              :     return;
   11379              : 
   11380      4554550 :   const location_t loc = cp_expr_loc_or_input_loc (expr);
   11381              : 
   11382              :   /* C++98 doesn't know move.  */
   11383      4554550 :   if (cxx_dialect < cxx11)
   11384              :     return;
   11385              : 
   11386              :   /* Wait until instantiation time, since we can't gauge if we should do
   11387              :      the NRVO until then.  */
   11388      4491905 :   if (processing_template_decl)
   11389              :     return;
   11390              : 
   11391              :   /* This is only interesting for class types.  */
   11392      4402984 :   if (!CLASS_TYPE_P (type))
   11393              :     return;
   11394              : 
   11395       110697 :   bool wrapped_p = false;
   11396              :   /* A a = std::move (A());  */
   11397       110697 :   if (TREE_CODE (expr) == TREE_LIST)
   11398              :     {
   11399         8896 :       if (list_length (expr) == 1)
   11400              :         {
   11401         5969 :           expr = TREE_VALUE (expr);
   11402         5969 :           wrapped_p = true;
   11403              :         }
   11404              :       else
   11405              :         return;
   11406              :     }
   11407              :   /* A a = {std::move (A())};
   11408              :      A a{std::move (A())};  */
   11409       101801 :   else if (TREE_CODE (expr) == CONSTRUCTOR)
   11410              :     {
   11411         7878 :       if (CONSTRUCTOR_NELTS (expr) == 1)
   11412              :         {
   11413          879 :           expr = CONSTRUCTOR_ELT (expr, 0)->value;
   11414          879 :           wrapped_p = true;
   11415              :         }
   11416              :       else
   11417              :         return;
   11418              :     }
   11419              : 
   11420              :   /* First, check if this is a call to std::move.  */
   11421         6773 :   if (!REFERENCE_REF_P (expr)
   11422       105491 :       || TREE_CODE (TREE_OPERAND (expr, 0)) != CALL_EXPR)
   11423              :     return;
   11424         2632 :   tree fn = TREE_OPERAND (expr, 0);
   11425         2632 :   if (!is_std_move_p (fn))
   11426              :     return;
   11427         2042 :   tree arg = CALL_EXPR_ARG (fn, 0);
   11428         2042 :   if (TREE_CODE (arg) != NOP_EXPR)
   11429              :     return;
   11430              :   /* If we're looking at *std::move<T&> ((T &) &arg), do the pessimizing N/RVO
   11431              :      and implicitly-movable warnings.  */
   11432         2042 :   if (TREE_CODE (TREE_OPERAND (arg, 0)) == ADDR_EXPR)
   11433              :     {
   11434         1399 :       arg = TREE_OPERAND (arg, 0);
   11435         1399 :       arg = TREE_OPERAND (arg, 0);
   11436         1399 :       arg = convert_from_reference (arg);
   11437         1399 :       if (can_elide_copy_prvalue_p (arg, type))
   11438              :         {
   11439          108 :           auto_diagnostic_group d;
   11440          108 :           if (warning_at (loc, OPT_Wpessimizing_move,
   11441              :                           "moving a temporary object prevents copy elision"))
   11442          108 :             inform (loc, "remove %<std::move%> call");
   11443          108 :         }
   11444              :       /* The rest of the warnings is only relevant for when we are returning
   11445              :          from a function.  */
   11446         1399 :       if (!return_p)
   11447              :         return;
   11448              : 
   11449          370 :       tree moved;
   11450              :       /* Warn if we could do copy elision were it not for the move.  */
   11451          370 :       if (can_do_nrvo_p (arg, type))
   11452              :         {
   11453           48 :           auto_diagnostic_group d;
   11454           48 :           if (!warning_suppressed_p (expr, OPT_Wpessimizing_move)
   11455           48 :               && warning_at (loc, OPT_Wpessimizing_move,
   11456              :                              "moving a local object in a return statement "
   11457              :                              "prevents copy elision"))
   11458           42 :             inform (loc, "remove %<std::move%> call");
   11459           48 :         }
   11460              :       /* Warn if the move is redundant.  It is redundant when we would
   11461              :          do maybe-rvalue overload resolution even without std::move.  */
   11462          322 :       else if (warn_redundant_move
   11463              :                /* This doesn't apply for return {std::move (t)};.  */
   11464          224 :                && !wrapped_p
   11465          221 :                && !warning_suppressed_p (expr, OPT_Wredundant_move)
   11466          418 :                && (moved = treat_lvalue_as_rvalue_p (arg, /*return*/true)))
   11467              :         {
   11468              :           /* Make sure that overload resolution would actually succeed
   11469              :              if we removed the std::move call.  */
   11470           54 :           tree t = convert_for_initialization (NULL_TREE, type,
   11471              :                                                moved,
   11472              :                                                (LOOKUP_NORMAL
   11473              :                                                 | LOOKUP_ONLYCONVERTING),
   11474              :                                                ICR_RETURN, NULL_TREE, 0,
   11475              :                                                tf_none);
   11476              :           /* If this worked, implicit rvalue would work, so the call to
   11477              :              std::move is redundant.  */
   11478           54 :           if (t != error_mark_node)
   11479              :             {
   11480           54 :               auto_diagnostic_group d;
   11481           54 :               if (warning_at (loc, OPT_Wredundant_move,
   11482              :                               "redundant move in return statement"))
   11483           54 :                 inform (loc, "remove %<std::move%> call");
   11484           54 :             }
   11485              :         }
   11486              :      }
   11487              :   /* Also try to warn about redundant std::move in code such as
   11488              :       T f (const T& t)
   11489              :       {
   11490              :         return std::move(t);
   11491              :       }
   11492              :     for which EXPR will be something like
   11493              :       *std::move<const T&> ((const struct T &) (const struct T *) t)
   11494              :      and where the std::move does nothing if T does not have a T(const T&&)
   11495              :      constructor, because the argument is const.  It will not use T(T&&)
   11496              :      because that would mean losing the const.  */
   11497          643 :   else if (warn_redundant_move
   11498          521 :            && !warning_suppressed_p (expr, OPT_Wredundant_move)
   11499           66 :            && TYPE_REF_P (TREE_TYPE (arg))
   11500          709 :            && CP_TYPE_CONST_P (TREE_TYPE (TREE_TYPE (arg))))
   11501              :     {
   11502           18 :       tree rtype = TREE_TYPE (TREE_TYPE (arg));
   11503           18 :       if (!same_type_ignoring_top_level_qualifiers_p (rtype, type))
   11504            9 :         return;
   11505              :       /* Check for the unlikely case there's T(const T&&) (we don't care if
   11506              :          it's deleted).  */
   11507           54 :       for (tree fn : ovl_range (CLASSTYPE_CONSTRUCTORS (rtype)))
   11508           30 :         if (move_fn_p (fn))
   11509              :           {
   11510           15 :             tree t = TREE_VALUE (FUNCTION_FIRST_USER_PARMTYPE (fn));
   11511           15 :             if (UNLIKELY (CP_TYPE_CONST_P (TREE_TYPE (t))))
   11512            6 :               return;
   11513              :           }
   11514            9 :       auto_diagnostic_group d;
   11515           18 :       if (return_p
   11516            9 :           ? warning_at (loc, OPT_Wredundant_move,
   11517              :                         "redundant move in return statement")
   11518            9 :           : warning_at (loc, OPT_Wredundant_move,
   11519              :                         "redundant move in initialization"))
   11520            9 :         inform (loc, "remove %<std::move%> call");
   11521            9 :     }
   11522              : }
   11523              : 
   11524              : /* Check that returning RETVAL from the current function is valid.
   11525              :    Return an expression explicitly showing all conversions required to
   11526              :    change RETVAL into the function return type, and to assign it to
   11527              :    the DECL_RESULT for the function.  Set *NO_WARNING to true if
   11528              :    code reaches end of non-void function warning shouldn't be issued
   11529              :    on this RETURN_EXPR.  Set *DANGLING to true if code returns the
   11530              :    address of a local variable.  */
   11531              : 
   11532              : tree
   11533    124683283 : check_return_expr (tree retval, bool *no_warning, bool *dangling)
   11534              : {
   11535    124683283 :   tree result;
   11536              :   /* The type actually returned by the function.  */
   11537    124683283 :   tree valtype;
   11538              :   /* The type the function is declared to return, or void if
   11539              :      the declared type is incomplete.  */
   11540    124683283 :   tree functype;
   11541    124683283 :   int fn_returns_value_p;
   11542    124683283 :   location_t loc = cp_expr_loc_or_input_loc (retval);
   11543              : 
   11544    124683283 :   *no_warning = false;
   11545    124683283 :   *dangling = false;
   11546              : 
   11547              :   /* A `volatile' function is one that isn't supposed to return, ever.
   11548              :      (This is a G++ extension, used to get better code for functions
   11549              :      that call the `volatile' function.)  */
   11550    124683283 :   if (TREE_THIS_VOLATILE (current_function_decl))
   11551           12 :     warning (0, "function declared %<noreturn%> has a %<return%> statement");
   11552              : 
   11553              :   /* Check for various simple errors.  */
   11554    249366566 :   if (DECL_DESTRUCTOR_P (current_function_decl))
   11555              :     {
   11556         2794 :       if (retval)
   11557            3 :         error_at (loc, "returning a value from a destructor");
   11558              : 
   11559         2794 :       if (targetm.cxx.cdtor_returns_this () && !processing_template_decl)
   11560            0 :         retval = current_class_ptr;
   11561              :       else
   11562              :         return NULL_TREE;
   11563              :     }
   11564    124680489 :   else if (DECL_CONSTRUCTOR_P (current_function_decl))
   11565              :     {
   11566       152982 :       if (in_function_try_handler)
   11567              :         /* If a return statement appears in a handler of the
   11568              :            function-try-block of a constructor, the program is ill-formed.  */
   11569            0 :         error ("cannot return from a handler of a function-try-block of a constructor");
   11570       152982 :       else if (retval)
   11571              :         /* You can't return a value from a constructor.  */
   11572            3 :         error_at (loc, "returning a value from a constructor");
   11573              : 
   11574       152982 :       if (targetm.cxx.cdtor_returns_this () && !processing_template_decl)
   11575            0 :         retval = current_class_ptr;
   11576              :       else
   11577              :         return NULL_TREE;
   11578              :     }
   11579              : 
   11580    124527507 :   const tree saved_retval = retval;
   11581              : 
   11582    124527507 :   if (processing_template_decl)
   11583              :     {
   11584     80890472 :       current_function_returns_value = 1;
   11585              : 
   11586     80890472 :       if (check_for_bare_parameter_packs (retval))
   11587           14 :         return error_mark_node;
   11588              : 
   11589              :       /* If one of the types might be void, we can't tell whether we're
   11590              :          returning a value.  */
   11591     80890458 :       if ((WILDCARD_TYPE_P (TREE_TYPE (DECL_RESULT (current_function_decl)))
   11592     34074723 :            && !FNDECL_USED_AUTO (current_function_decl))
   11593     46815744 :           || (retval != NULL_TREE
   11594     45695812 :               && (TREE_TYPE (retval) == NULL_TREE
   11595     31771830 :                   || WILDCARD_TYPE_P (TREE_TYPE (retval)))))
   11596     54831757 :         goto dependent;
   11597              :     }
   11598              : 
   11599     69695736 :   functype = TREE_TYPE (TREE_TYPE (current_function_decl));
   11600              : 
   11601              :   /* Deduce auto return type from a return statement.  */
   11602     69695736 :   if (FNDECL_USED_AUTO (current_function_decl))
   11603              :     {
   11604       978732 :       tree pattern = DECL_SAVED_AUTO_RETURN_TYPE (current_function_decl);
   11605       978732 :       tree auto_node;
   11606       978732 :       tree type;
   11607              : 
   11608       978732 :       if (!retval && !is_auto (pattern))
   11609              :         {
   11610              :           /* Give a helpful error message.  */
   11611            3 :           auto_diagnostic_group d;
   11612            3 :           error ("return-statement with no value, in function returning %qT",
   11613              :                  pattern);
   11614            3 :           inform (input_location, "only plain %<auto%> return type can be "
   11615              :                   "deduced to %<void%>");
   11616            3 :           type = error_mark_node;
   11617            3 :         }
   11618       978729 :       else if (retval && BRACE_ENCLOSED_INITIALIZER_P (retval))
   11619              :         {
   11620            6 :           error ("returning initializer list");
   11621            6 :           type = error_mark_node;
   11622              :         }
   11623              :       else
   11624              :         {
   11625       978723 :           if (!retval)
   11626         2008 :             retval = void_node;
   11627       978723 :           auto_node = type_uses_auto (pattern);
   11628       978723 :           type = do_auto_deduction (pattern, retval, auto_node,
   11629              :                                     tf_warning_or_error, adc_return_type);
   11630              :         }
   11631              : 
   11632       978732 :       if (type == error_mark_node)
   11633              :         /* Leave it.  */;
   11634       978496 :       else if (functype == pattern)
   11635       796751 :         apply_deduced_return_type (current_function_decl, type);
   11636       181745 :       else if (!same_type_p (type, functype))
   11637              :         {
   11638           24 :           if (LAMBDA_FUNCTION_P (current_function_decl))
   11639            6 :             error_at (loc, "inconsistent types %qT and %qT deduced for "
   11640              :                       "lambda return type", functype, type);
   11641              :           else
   11642           12 :             error_at (loc, "inconsistent deduction for auto return type: "
   11643              :                       "%qT and then %qT", functype, type);
   11644              :         }
   11645              :       functype = type;
   11646              :     }
   11647              : 
   11648     69695736 :   result = DECL_RESULT (current_function_decl);
   11649     69695736 :   valtype = TREE_TYPE (result);
   11650     69695736 :   gcc_assert (valtype != NULL_TREE);
   11651     69695736 :   fn_returns_value_p = !VOID_TYPE_P (valtype);
   11652              : 
   11653              :   /* Check for a return statement with no return value in a function
   11654              :      that's supposed to return a value.  */
   11655     69695736 :   if (!retval && fn_returns_value_p)
   11656              :     {
   11657           33 :       if (functype != error_mark_node)
   11658           30 :         permerror (input_location, "return-statement with no value, in "
   11659              :                    "function returning %qT", valtype);
   11660              :       /* Remember that this function did return.  */
   11661           33 :       current_function_returns_value = 1;
   11662              :       /* But suppress NRV  .*/
   11663           33 :       current_function_return_value = error_mark_node;
   11664              :       /* And signal caller that TREE_NO_WARNING should be set on the
   11665              :          RETURN_EXPR to avoid control reaches end of non-void function
   11666              :          warnings in tree-cfg.cc.  */
   11667           33 :       *no_warning = true;
   11668              :     }
   11669              :   /* Check for a return statement with a value in a function that
   11670              :      isn't supposed to return a value.  */
   11671     69695703 :   else if (retval && !fn_returns_value_p)
   11672              :     {
   11673       150370 :       if (VOID_TYPE_P (TREE_TYPE (retval)))
   11674              :         /* You can return a `void' value from a function of `void'
   11675              :            type.  In that case, we have to evaluate the expression for
   11676              :            its side-effects.  */
   11677       150331 :         finish_expr_stmt (retval);
   11678           39 :       else if (retval != error_mark_node)
   11679           36 :         permerror (loc, "return-statement with a value, in function "
   11680              :                    "returning %qT", valtype);
   11681       150370 :       current_function_returns_null = 1;
   11682              : 
   11683              :       /* There's really no value to return, after all.  */
   11684       150370 :       return NULL_TREE;
   11685              :     }
   11686     69545333 :   else if (!retval)
   11687              :     /* Remember that this function can sometimes return without a
   11688              :        value.  */
   11689      1609625 :     current_function_returns_null = 1;
   11690              :   else
   11691              :     /* Remember that this function did return a value.  */
   11692     67935708 :     current_function_returns_value = 1;
   11693              : 
   11694              :   /* Check for erroneous operands -- but after giving ourselves a
   11695              :      chance to provide an error about returning a value from a void
   11696              :      function.  */
   11697     69545366 :   if (error_operand_p (retval))
   11698              :     {
   11699         1033 :       current_function_return_value = error_mark_node;
   11700         1033 :       return error_mark_node;
   11701              :     }
   11702              : 
   11703              :   /* Only operator new(...) throw(), can return NULL [expr.new/13].  */
   11704    139088666 :   if (IDENTIFIER_NEW_OP_P (DECL_NAME (current_function_decl))
   11705        30858 :       && !TYPE_NOTHROW_P (TREE_TYPE (current_function_decl))
   11706         2365 :       && ! flag_check_new
   11707     69546689 :       && retval && null_ptr_cst_p (retval))
   11708           24 :     warning (0, "%<operator new%> must not return NULL unless it is "
   11709              :              "declared %<throw()%> (or %<-fcheck-new%> is in effect)");
   11710              : 
   11711              :   /* Effective C++ rule 15.  See also start_function.  */
   11712     69544333 :   if (warn_ecpp
   11713           42 :       && DECL_NAME (current_function_decl) == assign_op_identifier
   11714     69544363 :       && !type_dependent_expression_p (retval))
   11715              :     {
   11716           27 :       bool warn = true;
   11717              : 
   11718              :       /* The function return type must be a reference to the current
   11719              :         class.  */
   11720           27 :       if (TYPE_REF_P (valtype)
   11721           45 :           && same_type_ignoring_top_level_qualifiers_p
   11722           18 :               (TREE_TYPE (valtype), TREE_TYPE (current_class_ref)))
   11723              :         {
   11724              :           /* Returning '*this' is obviously OK.  */
   11725           18 :           if (retval == current_class_ref)
   11726              :             warn = false;
   11727              :           /* If we are calling a function whose return type is the same of
   11728              :              the current class reference, it is ok.  */
   11729            6 :           else if (INDIRECT_REF_P (retval)
   11730            6 :                    && TREE_CODE (TREE_OPERAND (retval, 0)) == CALL_EXPR)
   11731              :             warn = false;
   11732              :         }
   11733              : 
   11734              :       if (warn)
   11735            9 :         warning_at (loc, OPT_Weffc__,
   11736              :                     "%<operator=%> should return a reference to %<*this%>");
   11737              :     }
   11738              : 
   11739     69544333 :   if (dependent_type_p (functype)
   11740     69544333 :       || type_dependent_expression_p (retval))
   11741              :     {
   11742     70497988 :     dependent:
   11743              :       /* We should not have changed the return value.  */
   11744     70497988 :       gcc_assert (retval == saved_retval);
   11745              :       /* We don't know if this is an lvalue or rvalue use, but
   11746              :          either way we can mark it as read.  */
   11747     70497988 :       mark_exp_read (retval);
   11748     70497988 :       return retval;
   11749              :     }
   11750              : 
   11751              :   /* The fabled Named Return Value optimization, as per [class.copy]/15:
   11752              : 
   11753              :      [...]      For  a function with a class return type, if the expression
   11754              :      in the return statement is the name of a local  object,  and  the  cv-
   11755              :      unqualified  type  of  the  local  object  is the same as the function
   11756              :      return type, an implementation is permitted to omit creating the  tem-
   11757              :      porary  object  to  hold  the function return value [...]
   11758              : 
   11759              :      So, if this is a value-returning function that always returns the same
   11760              :      local variable, remember it.
   11761              : 
   11762              :      We choose the first suitable variable even if the function sometimes
   11763              :      returns something else, but only if the variable is out of scope at the
   11764              :      other return sites, or else we run the risk of clobbering the variable we
   11765              :      chose if the other returned expression uses the chosen variable somehow.
   11766              : 
   11767              :      We don't currently do this if the first return is a non-variable, as it
   11768              :      would be complicated to determine whether an NRV selected later was in
   11769              :      scope at the point of the earlier return.  We also don't currently support
   11770              :      multiple variables with non-overlapping scopes (53637).
   11771              : 
   11772              :      See finish_function and finalize_nrv for the rest of this optimization.  */
   11773     53878102 :   tree bare_retval = NULL_TREE;
   11774     53878102 :   if (retval)
   11775              :     {
   11776     52268459 :       retval = maybe_undo_parenthesized_ref (retval);
   11777     52268459 :       bare_retval = tree_strip_any_location_wrapper (retval);
   11778              :     }
   11779              : 
   11780     53878102 :   bool named_return_value_okay_p = want_nrvo_p (bare_retval, functype);
   11781     53878102 :   if (fn_returns_value_p && flag_elide_constructors
   11782     52268436 :       && current_function_return_value != bare_retval)
   11783              :     {
   11784     52263540 :       if (named_return_value_okay_p
   11785       258282 :           && current_function_return_value == NULL_TREE)
   11786       219034 :         current_function_return_value = bare_retval;
   11787     52044506 :       else if (current_function_return_value
   11788     10526770 :                && VAR_P (current_function_return_value)
   11789          204 :                && DECL_NAME (current_function_return_value)
   11790     52044710 :                && !decl_in_scope_p (current_function_return_value))
   11791              :         {
   11792              :           /* The earlier NRV is out of scope at this point, so it's safe to
   11793          141 :              leave it alone; the current return can't refer to it.  */;
   11794          141 :           if (named_return_value_okay_p
   11795          141 :               && !warning_suppressed_p (current_function_decl, OPT_Wnrvo))
   11796              :             {
   11797           12 :               warning (OPT_Wnrvo, "not eliding copy on return from %qD",
   11798              :                        bare_retval);
   11799           12 :               suppress_warning (current_function_decl, OPT_Wnrvo);
   11800              :             }
   11801              :         }
   11802              :       else
   11803              :         {
   11804     52044365 :           if ((named_return_value_okay_p
   11805     52005131 :                || (current_function_return_value
   11806     10487395 :                    && current_function_return_value != error_mark_node))
   11807     52044406 :               && !warning_suppressed_p (current_function_decl, OPT_Wnrvo))
   11808              :             {
   11809        39198 :               warning (OPT_Wnrvo, "not eliding copy on return in %qD",
   11810              :                        current_function_decl);
   11811        39198 :               suppress_warning (current_function_decl, OPT_Wnrvo);
   11812              :             }
   11813     52044365 :           current_function_return_value = error_mark_node;
   11814              :         }
   11815              :     }
   11816              : 
   11817              :   /* We don't need to do any conversions when there's nothing being
   11818              :      returned.  */
   11819     53878102 :   if (!retval)
   11820              :     return NULL_TREE;
   11821              : 
   11822     52268459 :   if (!named_return_value_okay_p)
   11823     52005281 :     maybe_warn_pessimizing_move (retval, functype, /*return_p*/true);
   11824              : 
   11825              :   /* Do any required conversions.  */
   11826    104536918 :   if (bare_retval == result || DECL_CONSTRUCTOR_P (current_function_decl))
   11827              :     /* No conversions are required.  */
   11828              :     ;
   11829              :   else
   11830              :     {
   11831     52268459 :       int flags = LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING;
   11832              : 
   11833              :       /* The functype's return type will have been set to void, if it
   11834              :          was an incomplete type.  Just treat this as 'return;' */
   11835     52268459 :       if (VOID_TYPE_P (functype))
   11836            6 :         return error_mark_node;
   11837              : 
   11838              :       /* Under C++11 [12.8/32 class.copy], a returned lvalue is sometimes
   11839              :          treated as an rvalue for the purposes of overload resolution to
   11840              :          favor move constructors over copy constructors.
   11841              : 
   11842              :          Note that these conditions are similar to, but not as strict as,
   11843              :          the conditions for the named return value optimization.  */
   11844     52268453 :       bool converted = false;
   11845     52268453 :       tree moved;
   11846              :       /* Until C++23, this was only interesting for class type, but in C++23,
   11847              :          we should do the below when we're converting from/to a class/reference
   11848              :          (a non-scalar type).  */
   11849     52268453 :         if ((cxx_dialect < cxx23
   11850      7667325 :              ? CLASS_TYPE_P (functype)
   11851      7733548 :              : !SCALAR_TYPE_P (functype) || !SCALAR_TYPE_P (TREE_TYPE (retval)))
   11852     62309901 :             && (moved = treat_lvalue_as_rvalue_p (retval, /*return*/true)))
   11853              :           /* In C++20 and earlier we treat the return value as an rvalue
   11854              :              that can bind to lvalue refs.  In C++23, such an expression is just
   11855              :              an xvalue (see reference_binding).  */
   11856              :           retval = moved;
   11857              : 
   11858              :       /* The call in a (lambda) thunk needs no conversions.  */
   11859     52268453 :       if (TREE_CODE (retval) == CALL_EXPR
   11860     52268453 :           && call_from_lambda_thunk_p (retval))
   11861              :         converted = true;
   11862              : 
   11863              :       /* Don't check copy-initialization for NRV in a coroutine ramp; we
   11864              :          implement this case as NRV, but it's specified as directly
   11865              :          initializing the return value from get_return_object().  */
   11866     52268453 :       if (DECL_RAMP_P (current_function_decl) && named_return_value_okay_p)
   11867              :         converted = true;
   11868              : 
   11869              :       /* First convert the value to the function's return type, then
   11870              :          to the type of return value's location to handle the
   11871              :          case that functype is smaller than the valtype.  */
   11872     52268198 :       if (!converted)
   11873     52219259 :         retval = convert_for_initialization
   11874     52219259 :           (NULL_TREE, functype, retval, flags, ICR_RETURN, NULL_TREE, 0,
   11875              :            tf_warning_or_error);
   11876     52268453 :       retval = convert (valtype, retval);
   11877              : 
   11878              :       /* If the conversion failed, treat this just like `return;'.  */
   11879     52268453 :       if (retval == error_mark_node)
   11880              :         {
   11881              :           /* And suppress NRV.  */
   11882          213 :           current_function_return_value = error_mark_node;
   11883          213 :           return retval;
   11884              :         }
   11885              :       /* We can't initialize a register from a AGGR_INIT_EXPR.  */
   11886     52268240 :       else if (! cfun->returns_struct
   11887     50213761 :                && TREE_CODE (retval) == TARGET_EXPR
   11888     58574432 :                && TREE_CODE (TARGET_EXPR_INITIAL (retval)) == AGGR_INIT_EXPR)
   11889      1429276 :         retval = build2 (COMPOUND_EXPR, TREE_TYPE (retval), retval,
   11890      1429276 :                          TARGET_EXPR_SLOT (retval));
   11891     50838964 :       else if (!processing_template_decl
   11892     41575806 :                && maybe_warn_about_returning_address_of_local (retval, loc)
   11893     50839154 :                && INDIRECT_TYPE_P (valtype))
   11894          175 :         *dangling = true;
   11895              :     }
   11896              : 
   11897     52268240 :   if (check_out_of_consteval_use (retval))
   11898              :     {
   11899           12 :       current_function_return_value = error_mark_node;
   11900           12 :       return error_mark_node;
   11901              :     }
   11902              : 
   11903              :   /* A naive attempt to reduce the number of -Wdangling-reference false
   11904              :      positives: if we know that this function can return a variable with
   11905              :      static storage duration rather than one of its parameters, suppress
   11906              :      the warning.  */
   11907     52268228 :   if (warn_dangling_reference
   11908       413280 :       && TYPE_REF_P (functype)
   11909        27533 :       && bare_retval
   11910        27533 :       && VAR_P (bare_retval)
   11911           50 :       && TREE_STATIC (bare_retval))
   11912           50 :     suppress_warning (current_function_decl, OPT_Wdangling_reference);
   11913              : 
   11914     52268228 :   if (processing_template_decl)
   11915              :     return saved_retval;
   11916              : 
   11917              :   /* Actually copy the value returned into the appropriate location.  */
   11918     43005072 :   if (retval && retval != result)
   11919     43005072 :     retval = cp_build_init_expr (result, retval);
   11920              : 
   11921     43005072 :   if (current_function_return_value == bare_retval)
   11922       223924 :     INIT_EXPR_NRV_P (retval) = true;
   11923              : 
   11924     43005072 :   if (tree set = maybe_set_retval_sentinel ())
   11925       125979 :     retval = build2 (COMPOUND_EXPR, void_type_node, retval, set);
   11926              : 
   11927              :   return retval;
   11928              : }
   11929              : 
   11930              : 
   11931              : /* Returns nonzero if the pointer-type FROM can be converted to the
   11932              :    pointer-type TO via a qualification conversion.  If CONSTP is -1,
   11933              :    then we return nonzero if the pointers are similar, and the
   11934              :    cv-qualification signature of FROM is a proper subset of that of TO.
   11935              : 
   11936              :    If CONSTP is positive, then all outer pointers have been
   11937              :    const-qualified.  */
   11938              : 
   11939              : static bool
   11940    182092440 : comp_ptr_ttypes_real (tree to, tree from, int constp)
   11941              : {
   11942    182092440 :   bool to_more_cv_qualified = false;
   11943    182092440 :   bool is_opaque_pointer = false;
   11944              : 
   11945       619196 :   for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from))
   11946              :     {
   11947    182711636 :       if (TREE_CODE (to) != TREE_CODE (from))
   11948              :         return false;
   11949              : 
   11950    122043952 :       if (TREE_CODE (from) == OFFSET_TYPE
   11951    122043952 :           && !same_type_p (TYPE_OFFSET_BASETYPE (from),
   11952              :                            TYPE_OFFSET_BASETYPE (to)))
   11953              :         return false;
   11954              : 
   11955              :       /* Const and volatile mean something different for function and
   11956              :          array types, so the usual checks are not appropriate.  We'll
   11957              :          check the array type elements in further iterations.  */
   11958    122043952 :       if (!FUNC_OR_METHOD_TYPE_P (to) && TREE_CODE (to) != ARRAY_TYPE)
   11959              :         {
   11960    121806715 :           if (!at_least_as_qualified_p (to, from))
   11961              :             return false;
   11962              : 
   11963    108489764 :           if (!at_least_as_qualified_p (from, to))
   11964              :             {
   11965     73503638 :               if (constp == 0)
   11966              :                 return false;
   11967              :               to_more_cv_qualified = true;
   11968              :             }
   11969              : 
   11970    108489499 :           if (constp > 0)
   11971    108485486 :             constp &= TYPE_READONLY (to);
   11972              :         }
   11973              : 
   11974    108726736 :       if (VECTOR_TYPE_P (to))
   11975         8511 :         is_opaque_pointer = vector_targets_convertible_p (to, from);
   11976              : 
   11977              :       /* P0388R4 allows a conversion from int[N] to int[] but not the
   11978              :          other way round.  When both arrays have bounds but they do
   11979              :          not match, then no conversion is possible.  */
   11980    108726736 :       if (TREE_CODE (to) == ARRAY_TYPE
   11981    108726736 :           && !comp_array_types (to, from, bounds_first, /*strict=*/false))
   11982              :         return false;
   11983              : 
   11984    108726126 :       if (!TYPE_PTR_P (to)
   11985              :           && !TYPE_PTRDATAMEM_P (to)
   11986              :           /* CWG 330 says we need to look through arrays.  */
   11987              :           && TREE_CODE (to) != ARRAY_TYPE)
   11988    108106930 :         return ((constp >= 0 || to_more_cv_qualified)
   11989    108106930 :                 && (is_opaque_pointer
   11990    108106400 :                     || same_type_ignoring_top_level_qualifiers_p (to, from)));
   11991              :     }
   11992              : }
   11993              : 
   11994              : /* When comparing, say, char ** to char const **, this function takes
   11995              :    the 'char *' and 'char const *'.  Do not pass non-pointer/reference
   11996              :    types to this function.  */
   11997              : 
   11998              : int
   11999    182091812 : comp_ptr_ttypes (tree to, tree from)
   12000              : {
   12001    182091812 :   return comp_ptr_ttypes_real (to, from, 1);
   12002              : }
   12003              : 
   12004              : /* Returns true iff FNTYPE is a non-class type that involves
   12005              :    error_mark_node.  We can get FUNCTION_TYPE with buried error_mark_node
   12006              :    if a parameter type is ill-formed.  */
   12007              : 
   12008              : bool
   12009       690534 : error_type_p (const_tree type)
   12010              : {
   12011       729087 :   tree t;
   12012              : 
   12013       729087 :   switch (TREE_CODE (type))
   12014              :     {
   12015              :     case ERROR_MARK:
   12016              :       return true;
   12017              : 
   12018        38464 :     case POINTER_TYPE:
   12019        38464 :     case REFERENCE_TYPE:
   12020        38464 :     case OFFSET_TYPE:
   12021        38464 :       return error_type_p (TREE_TYPE (type));
   12022              : 
   12023         2909 :     case FUNCTION_TYPE:
   12024         2909 :     case METHOD_TYPE:
   12025         2909 :       if (error_type_p (TREE_TYPE (type)))
   12026              :         return true;
   12027         7798 :       for (t = TYPE_ARG_TYPES (type); t; t = TREE_CHAIN (t))
   12028         4895 :         if (error_type_p (TREE_VALUE (t)))
   12029              :           return true;
   12030              :       return false;
   12031              : 
   12032       183435 :     case RECORD_TYPE:
   12033       183435 :       if (TYPE_PTRMEMFUNC_P (type))
   12034           89 :         return error_type_p (TYPE_PTRMEMFUNC_FN_TYPE (type));
   12035              :       return false;
   12036              : 
   12037              :     default:
   12038              :       return false;
   12039              :     }
   12040              : }
   12041              : 
   12042              : /* Returns true if to and from are (possibly multi-level) pointers to the same
   12043              :    type or inheritance-related types, regardless of cv-quals.  */
   12044              : 
   12045              : bool
   12046    130746212 : ptr_reasonably_similar (const_tree to, const_tree from)
   12047              : {
   12048         1211 :   for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from))
   12049              :     {
   12050              :       /* Any target type is similar enough to void.  */
   12051    130747423 :       if (VOID_TYPE_P (to))
   12052         1341 :         return !error_type_p (from);
   12053    130746082 :       if (VOID_TYPE_P (from))
   12054       679327 :         return !error_type_p (to);
   12055              : 
   12056    130066755 :       if (TREE_CODE (to) != TREE_CODE (from))
   12057              :         return false;
   12058              : 
   12059     69940216 :       if (TREE_CODE (from) == OFFSET_TYPE
   12060     69940216 :           && comptypes (TYPE_OFFSET_BASETYPE (to),
   12061            3 :                         TYPE_OFFSET_BASETYPE (from),
   12062              :                         COMPARE_BASE | COMPARE_DERIVED))
   12063            3 :         continue;
   12064              : 
   12065     69940210 :       if (VECTOR_TYPE_P (to)
   12066     69940210 :           && vector_types_convertible_p (to, from, false))
   12067              :         return true;
   12068              : 
   12069     69940126 :       if (TREE_CODE (to) == INTEGER_TYPE
   12070     69940126 :           && TYPE_PRECISION (to) == TYPE_PRECISION (from))
   12071              :         return true;
   12072              : 
   12073     69764726 :       if (TREE_CODE (to) == FUNCTION_TYPE)
   12074         1031 :         return !error_type_p (to) && !error_type_p (from);
   12075              : 
   12076     69763695 :       if (!TYPE_PTR_P (to))
   12077              :         {
   12078              :           /* When either type is incomplete avoid DERIVED_FROM_P,
   12079              :              which may call complete_type (c++/57942).  */
   12080     69762487 :           bool b = !COMPLETE_TYPE_P (to) || !COMPLETE_TYPE_P (from);
   12081              :           return comptypes
   12082     69762487 :             (TYPE_MAIN_VARIANT (to), TYPE_MAIN_VARIANT (from),
   12083     69762487 :              b ? COMPARE_STRICT : COMPARE_BASE | COMPARE_DERIVED);
   12084              :         }
   12085         1211 :     }
   12086              : }
   12087              : 
   12088              : /* Return true if TO and FROM (both of which are POINTER_TYPEs or
   12089              :    pointer-to-member types) are the same, ignoring cv-qualification at
   12090              :    all levels.  CB says how we should behave when comparing array bounds.  */
   12091              : 
   12092              : bool
   12093      1056350 : comp_ptr_ttypes_const (tree to, tree from, compare_bounds_t cb)
   12094              : {
   12095      1056350 :   bool is_opaque_pointer = false;
   12096              : 
   12097      1057901 :   for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from))
   12098              :     {
   12099      2114251 :       if (TREE_CODE (to) != TREE_CODE (from))
   12100              :         return false;
   12101              : 
   12102      1786463 :       if (TREE_CODE (from) == OFFSET_TYPE
   12103      1785456 :           && same_type_p (TYPE_OFFSET_BASETYPE (from),
   12104              :                           TYPE_OFFSET_BASETYPE (to)))
   12105         1007 :           continue;
   12106              : 
   12107      1784449 :       if (VECTOR_TYPE_P (to))
   12108         8706 :         is_opaque_pointer = vector_targets_convertible_p (to, from);
   12109              : 
   12110      1784449 :       if (TREE_CODE (to) == ARRAY_TYPE
   12111              :           /* Ignore cv-qualification, but if we see e.g. int[3] and int[4],
   12112              :              we must fail.  */
   12113      1784449 :           && !comp_array_types (to, from, cb, /*strict=*/false))
   12114              :         return false;
   12115              : 
   12116              :       /* CWG 330 says we need to look through arrays.  */
   12117      1782485 :       if (!TYPE_PTR_P (to) && TREE_CODE (to) != ARRAY_TYPE)
   12118       725591 :         return (is_opaque_pointer
   12119       725591 :                 || same_type_ignoring_top_level_qualifiers_p (to, from));
   12120              :     }
   12121              : }
   12122              : 
   12123              : /* Returns the type qualifiers for this type, including the qualifiers on the
   12124              :    elements for an array type.  */
   12125              : 
   12126              : int
   12127  61110866850 : cp_type_quals (const_tree type)
   12128              : {
   12129  61110866850 :   int quals;
   12130              :   /* This CONST_CAST is okay because strip_array_types returns its
   12131              :      argument unmodified and we assign it to a const_tree.  */
   12132  61110866850 :   type = strip_array_types (const_cast<tree> (type));
   12133  61110866850 :   if (type == error_mark_node
   12134              :       /* Quals on a FUNCTION_TYPE are memfn quals.  */
   12135  61076890440 :       || TREE_CODE (type) == FUNCTION_TYPE)
   12136              :     return TYPE_UNQUALIFIED;
   12137  61009628267 :   quals = TYPE_QUALS (type);
   12138              :   /* METHOD and REFERENCE_TYPEs should never have quals.  */
   12139  61009628267 :   gcc_assert ((TREE_CODE (type) != METHOD_TYPE
   12140              :                && !TYPE_REF_P (type))
   12141              :               || ((quals & (TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE))
   12142              :                   == TYPE_UNQUALIFIED));
   12143              :   return quals;
   12144              : }
   12145              : 
   12146              : /* Returns the function-ref-qualifier for TYPE */
   12147              : 
   12148              : cp_ref_qualifier
   12149   3303792068 : type_memfn_rqual (const_tree type)
   12150              : {
   12151   3303792068 :   gcc_assert (FUNC_OR_METHOD_TYPE_P (type));
   12152              : 
   12153   3303792068 :   if (!FUNCTION_REF_QUALIFIED (type))
   12154              :     return REF_QUAL_NONE;
   12155     31081936 :   else if (FUNCTION_RVALUE_QUALIFIED (type))
   12156              :     return REF_QUAL_RVALUE;
   12157              :   else
   12158     15443930 :     return REF_QUAL_LVALUE;
   12159              : }
   12160              : 
   12161              : /* Returns the function-cv-quals for TYPE, which must be a FUNCTION_TYPE or
   12162              :    METHOD_TYPE.  */
   12163              : 
   12164              : int
   12165   1077300558 : type_memfn_quals (const_tree type)
   12166              : {
   12167   1077300558 :   if (TREE_CODE (type) == FUNCTION_TYPE)
   12168    107084603 :     return TYPE_QUALS (type);
   12169    970215955 :   else if (TREE_CODE (type) == METHOD_TYPE)
   12170    970215955 :     return cp_type_quals (class_of_this_parm (type));
   12171              :   else
   12172            0 :     gcc_unreachable ();
   12173              : }
   12174              : 
   12175              : /* Returns the FUNCTION_TYPE TYPE with its function-cv-quals changed to
   12176              :    MEMFN_QUALS and its ref-qualifier to RQUAL. */
   12177              : 
   12178              : tree
   12179     71165182 : apply_memfn_quals (tree type, cp_cv_quals memfn_quals, cp_ref_qualifier rqual)
   12180              : {
   12181              :   /* Could handle METHOD_TYPE here if necessary.  */
   12182     71165182 :   gcc_assert (TREE_CODE (type) == FUNCTION_TYPE);
   12183     71165182 :   if (TYPE_QUALS (type) == memfn_quals
   12184     71165182 :       && type_memfn_rqual (type) == rqual)
   12185              :     return type;
   12186              : 
   12187              :   /* This should really have a different TYPE_MAIN_VARIANT, but that gets
   12188              :      complex.  */
   12189       584595 :   tree result = build_qualified_type (type, memfn_quals);
   12190       584595 :   return build_ref_qualified_type (result, rqual);
   12191              : }
   12192              : 
   12193              : /* Returns nonzero if TYPE is const or volatile.  */
   12194              : 
   12195              : bool
   12196   1186954448 : cv_qualified_p (const_tree type)
   12197              : {
   12198   1186954448 :   int quals = cp_type_quals (type);
   12199   1186954448 :   return (quals & (TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE)) != 0;
   12200              : }
   12201              : 
   12202              : /* Returns nonzero if the TYPE contains a mutable member.  */
   12203              : 
   12204              : bool
   12205    920178873 : cp_has_mutable_p (const_tree type)
   12206              : {
   12207              :   /* This CONST_CAST is okay because strip_array_types returns its
   12208              :      argument unmodified and we assign it to a const_tree.  */
   12209    920178873 :   type = strip_array_types (const_cast<tree> (type));
   12210              : 
   12211    920178873 :   return CLASS_TYPE_P (type) && CLASSTYPE_HAS_MUTABLE (type);
   12212              : }
   12213              : 
   12214              : /* Set TREE_READONLY and TREE_VOLATILE on DECL as indicated by the
   12215              :    TYPE_QUALS.  For a VAR_DECL, this may be an optimistic
   12216              :    approximation.  In particular, consider:
   12217              : 
   12218              :      int f();
   12219              :      struct S { int i; };
   12220              :      const S s = { f(); }
   12221              : 
   12222              :    Here, we will make "s" as TREE_READONLY (because it is declared
   12223              :    "const") -- only to reverse ourselves upon seeing that the
   12224              :    initializer is non-constant.  */
   12225              : 
   12226              : void
   12227    992521123 : cp_apply_type_quals_to_decl (int type_quals, tree decl)
   12228              : {
   12229    992521123 :   tree type = TREE_TYPE (decl);
   12230              : 
   12231    992521123 :   if (type == error_mark_node)
   12232              :     return;
   12233              : 
   12234    992520365 :   if (TREE_CODE (decl) == TYPE_DECL)
   12235              :     return;
   12236              : 
   12237    875720552 :   gcc_assert (!(TREE_CODE (type) == FUNCTION_TYPE
   12238              :                 && type_quals != TYPE_UNQUALIFIED));
   12239              : 
   12240              :   /* Avoid setting TREE_READONLY incorrectly.  */
   12241              :   /* We used to check TYPE_NEEDS_CONSTRUCTING here, but now a constexpr
   12242              :      constructor can produce constant init, so rely on cp_finish_decl to
   12243              :      clear TREE_READONLY if the variable has non-constant init.  */
   12244              : 
   12245              :   /* If the type has (or might have) a mutable component, that component
   12246              :      might be modified.  */
   12247    875720552 :   if (TYPE_HAS_MUTABLE_P (type) || !COMPLETE_TYPE_P (type))
   12248     80591474 :     type_quals &= ~TYPE_QUAL_CONST;
   12249              : 
   12250    875720552 :   c_apply_type_quals_to_decl (type_quals, decl);
   12251              : }
   12252              : 
   12253              : /* Subroutine of casts_away_constness.  Make T1 and T2 point at
   12254              :    exemplar types such that casting T1 to T2 is casting away constness
   12255              :    if and only if there is no implicit conversion from T1 to T2.  */
   12256              : 
   12257              : static void
   12258      1257633 : casts_away_constness_r (tree *t1, tree *t2, tsubst_flags_t complain)
   12259              : {
   12260      1257633 :   int quals1;
   12261      1257633 :   int quals2;
   12262              : 
   12263              :   /* [expr.const.cast]
   12264              : 
   12265              :      For multi-level pointer to members and multi-level mixed pointers
   12266              :      and pointers to members (conv.qual), the "member" aspect of a
   12267              :      pointer to member level is ignored when determining if a const
   12268              :      cv-qualifier has been cast away.  */
   12269              :   /* [expr.const.cast]
   12270              : 
   12271              :      For  two  pointer types:
   12272              : 
   12273              :             X1 is T1cv1,1 * ... cv1,N *   where T1 is not a pointer type
   12274              :             X2 is T2cv2,1 * ... cv2,M *   where T2 is not a pointer type
   12275              :             K is min(N,M)
   12276              : 
   12277              :      casting from X1 to X2 casts away constness if, for a non-pointer
   12278              :      type T there does not exist an implicit conversion (clause
   12279              :      _conv_) from:
   12280              : 
   12281              :             Tcv1,(N-K+1) * cv1,(N-K+2) * ... cv1,N *
   12282              : 
   12283              :      to
   12284              : 
   12285              :             Tcv2,(M-K+1) * cv2,(M-K+2) * ... cv2,M *.  */
   12286      1257633 :   if ((!TYPE_PTR_P (*t1) && !TYPE_PTRDATAMEM_P (*t1))
   12287       629167 :       || (!TYPE_PTR_P (*t2) && !TYPE_PTRDATAMEM_P (*t2)))
   12288              :     {
   12289       628644 :       *t1 = cp_build_qualified_type (void_type_node,
   12290              :                                      cp_type_quals (*t1));
   12291       628644 :       *t2 = cp_build_qualified_type (void_type_node,
   12292              :                                      cp_type_quals (*t2));
   12293       628644 :       return;
   12294              :     }
   12295              : 
   12296       628989 :   quals1 = cp_type_quals (*t1);
   12297       628989 :   quals2 = cp_type_quals (*t2);
   12298              : 
   12299       628989 :   if (TYPE_PTRDATAMEM_P (*t1))
   12300            0 :     *t1 = TYPE_PTRMEM_POINTED_TO_TYPE (*t1);
   12301              :   else
   12302       628989 :     *t1 = TREE_TYPE (*t1);
   12303       628989 :   if (TYPE_PTRDATAMEM_P (*t2))
   12304            0 :     *t2 = TYPE_PTRMEM_POINTED_TO_TYPE (*t2);
   12305              :   else
   12306       628989 :     *t2 = TREE_TYPE (*t2);
   12307              : 
   12308       628989 :   casts_away_constness_r (t1, t2, complain);
   12309       628989 :   *t1 = build_pointer_type (*t1);
   12310       628989 :   *t2 = build_pointer_type (*t2);
   12311       628989 :   *t1 = cp_build_qualified_type (*t1, quals1);
   12312       628989 :   *t2 = cp_build_qualified_type (*t2, quals2);
   12313              : }
   12314              : 
   12315              : /* Returns nonzero if casting from TYPE1 to TYPE2 casts away
   12316              :    constness.
   12317              : 
   12318              :    ??? This function returns non-zero if casting away qualifiers not
   12319              :    just const.  We would like to return to the caller exactly which
   12320              :    qualifiers are casted away to give more accurate diagnostics.
   12321              : */
   12322              : 
   12323              : static bool
   12324       628716 : casts_away_constness (tree t1, tree t2, tsubst_flags_t complain)
   12325              : {
   12326       628716 :   if (TYPE_REF_P (t2))
   12327              :     {
   12328              :       /* [expr.const.cast]
   12329              : 
   12330              :          Casting from an lvalue of type T1 to an lvalue of type T2
   12331              :          using a reference cast casts away constness if a cast from an
   12332              :          rvalue of type "pointer to T1" to the type "pointer to T2"
   12333              :          casts away constness.  */
   12334            0 :       t1 = (TYPE_REF_P (t1) ? TREE_TYPE (t1) : t1);
   12335            0 :       return casts_away_constness (build_pointer_type (t1),
   12336            0 :                                    build_pointer_type (TREE_TYPE (t2)),
   12337            0 :                                    complain);
   12338              :     }
   12339              : 
   12340       628716 :   if (TYPE_PTRDATAMEM_P (t1) && TYPE_PTRDATAMEM_P (t2))
   12341              :     /* [expr.const.cast]
   12342              : 
   12343              :        Casting from an rvalue of type "pointer to data member of X
   12344              :        of type T1" to the type "pointer to data member of Y of type
   12345              :        T2" casts away constness if a cast from an rvalue of type
   12346              :        "pointer to T1" to the type "pointer to T2" casts away
   12347              :        constness.  */
   12348           48 :     return casts_away_constness
   12349           48 :       (build_pointer_type (TYPE_PTRMEM_POINTED_TO_TYPE (t1)),
   12350           48 :        build_pointer_type (TYPE_PTRMEM_POINTED_TO_TYPE (t2)),
   12351           48 :        complain);
   12352              : 
   12353              :   /* Casting away constness is only something that makes sense for
   12354              :      pointer or reference types.  */
   12355       628668 :   if (!TYPE_PTR_P (t1) || !TYPE_PTR_P (t2))
   12356              :     return false;
   12357              : 
   12358              :   /* Top-level qualifiers don't matter.  */
   12359       628644 :   t1 = TYPE_MAIN_VARIANT (t1);
   12360       628644 :   t2 = TYPE_MAIN_VARIANT (t2);
   12361       628644 :   casts_away_constness_r (&t1, &t2, complain);
   12362       628644 :   if (!can_convert (t2, t1, complain))
   12363              :     return true;
   12364              : 
   12365              :   return false;
   12366              : }
   12367              : 
   12368              : /* If T is a REFERENCE_TYPE return the type to which T refers.
   12369              :    Otherwise, return T itself.  */
   12370              : 
   12371              : tree
   12372   4232014930 : non_reference (tree t)
   12373              : {
   12374   4232014930 :   if (t && TYPE_REF_P (t))
   12375    379699349 :     t = TREE_TYPE (t);
   12376   4232014930 :   return t;
   12377              : }
   12378              : 
   12379              : 
   12380              : /* Return nonzero if REF is an lvalue valid for this language;
   12381              :    otherwise, print an error message and return zero.  USE says
   12382              :    how the lvalue is being used and so selects the error message.  */
   12383              : 
   12384              : int
   12385     41153305 : lvalue_or_else (tree ref, enum lvalue_use use, tsubst_flags_t complain)
   12386              : {
   12387     41153305 :   cp_lvalue_kind kind = lvalue_kind (ref);
   12388              : 
   12389     41153305 :   if (kind == clk_none)
   12390              :     {
   12391          382 :       if (complain & tf_error)
   12392          126 :         lvalue_error (cp_expr_loc_or_input_loc (ref), use);
   12393          382 :       return 0;
   12394              :     }
   12395     41152923 :   else if (kind & (clk_rvalueref|clk_class))
   12396              :     {
   12397          192 :       if (!(complain & tf_error))
   12398              :         return 0;
   12399              :       /* Make this a permerror because we used to accept it.  */
   12400           18 :       permerror (cp_expr_loc_or_input_loc (ref),
   12401              :                  "using rvalue as lvalue");
   12402              :     }
   12403              :   return 1;
   12404              : }
   12405              : 
   12406              : /* Return true if a user-defined literal operator is a raw operator.  */
   12407              : 
   12408              : bool
   12409       111346 : check_raw_literal_operator (const_tree decl)
   12410              : {
   12411       111346 :   tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl));
   12412       111346 :   tree argtype;
   12413       111346 :   int arity;
   12414       111346 :   bool maybe_raw_p = false;
   12415              : 
   12416              :   /* Count the number and type of arguments and check for ellipsis.  */
   12417       111346 :   for (argtype = argtypes, arity = 0;
   12418       167036 :        argtype && argtype != void_list_node;
   12419        55690 :        ++arity, argtype = TREE_CHAIN (argtype))
   12420              :     {
   12421        55690 :       tree t = TREE_VALUE (argtype);
   12422              : 
   12423        55690 :       if (same_type_p (t, const_string_type_node))
   12424            9 :         maybe_raw_p = true;
   12425              :     }
   12426       111346 :   if (!argtype)
   12427              :     return false; /* Found ellipsis.  */
   12428              : 
   12429       111346 :   if (!maybe_raw_p || arity != 1)
   12430       111340 :     return false;
   12431              : 
   12432              :   return true;
   12433              : }
   12434              : 
   12435              : 
   12436              : /* Return true if a user-defined literal operator has one of the allowed
   12437              :    argument types.  */
   12438              : 
   12439              : bool
   12440       303374 : check_literal_operator_args (const_tree decl,
   12441              :                              bool *long_long_unsigned_p, bool *long_double_p)
   12442              : {
   12443       303374 :   tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl));
   12444              : 
   12445       303374 :   *long_long_unsigned_p = false;
   12446       303374 :   *long_double_p = false;
   12447       303374 :   if (processing_template_decl || processing_specialization)
   12448        55815 :     return argtypes == void_list_node;
   12449              :   else
   12450              :     {
   12451              :       tree argtype;
   12452              :       int arity;
   12453              :       int max_arity = 2;
   12454              : 
   12455              :       /* Count the number and type of arguments and check for ellipsis.  */
   12456       247431 :       for (argtype = argtypes, arity = 0;
   12457       494990 :            argtype && argtype != void_list_node;
   12458       247431 :            argtype = TREE_CHAIN (argtype))
   12459              :         {
   12460       247565 :           tree t = TREE_VALUE (argtype);
   12461       247565 :           ++arity;
   12462              : 
   12463       247565 :           if (TYPE_PTR_P (t))
   12464              :             {
   12465       119171 :               bool maybe_raw_p = false;
   12466       119171 :               t = TREE_TYPE (t);
   12467       119171 :               if (cp_type_quals (t) != TYPE_QUAL_CONST)
   12468              :                 return false;
   12469       119168 :               t = TYPE_MAIN_VARIANT (t);
   12470       119168 :               if ((maybe_raw_p = same_type_p (t, char_type_node))
   12471        95144 :                   || same_type_p (t, wchar_type_node)
   12472        71306 :                   || same_type_p (t, char8_type_node)
   12473        47688 :                   || same_type_p (t, char16_type_node)
   12474       143012 :                   || same_type_p (t, char32_type_node))
   12475              :                 {
   12476       119165 :                   argtype = TREE_CHAIN (argtype);
   12477       119165 :                   if (!argtype)
   12478              :                     return false;
   12479       119165 :                   t = TREE_VALUE (argtype);
   12480       119165 :                   if (maybe_raw_p && argtype == void_list_node)
   12481              :                     return true;
   12482       119058 :                   else if (same_type_p (t, size_type_node))
   12483              :                     {
   12484       119052 :                       ++arity;
   12485       119052 :                       continue;
   12486              :                     }
   12487              :                   else
   12488              :                     return false;
   12489              :                 }
   12490              :             }
   12491       128394 :           else if (same_type_p (t, long_long_unsigned_type_node))
   12492              :             {
   12493        45297 :               max_arity = 1;
   12494        45297 :               *long_long_unsigned_p = true;
   12495              :             }
   12496        83097 :           else if (same_type_p (t, long_double_type_node))
   12497              :             {
   12498        82997 :               max_arity = 1;
   12499        82997 :               *long_double_p = true;
   12500              :             }
   12501          100 :           else if (same_type_p (t, char_type_node))
   12502              :             max_arity = 1;
   12503           56 :           else if (same_type_p (t, wchar_type_node))
   12504              :             max_arity = 1;
   12505           45 :           else if (same_type_p (t, char8_type_node))
   12506              :             max_arity = 1;
   12507           40 :           else if (same_type_p (t, char16_type_node))
   12508              :             max_arity = 1;
   12509           29 :           else if (same_type_p (t, char32_type_node))
   12510              :             max_arity = 1;
   12511              :           else
   12512              :             return false;
   12513              :         }
   12514       247425 :       if (!argtype)
   12515              :         return false; /* Found ellipsis.  */
   12516              : 
   12517       247422 :       if (arity != max_arity)
   12518              :         return false;
   12519              : 
   12520              :       return true;
   12521              :     }
   12522              : }
   12523              : 
   12524              : /* Always returns false since unlike C90, C++ has no concept of implicit
   12525              :    function declarations.  */
   12526              : 
   12527              : bool
   12528          395 : c_decl_implicit (const_tree)
   12529              : {
   12530          395 :   return false;
   12531              : }
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.