LCOV - code coverage report
Current view: top level - gcc/cp - typeck.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 92.2 % 5524 5094
Test Date: 2026-04-20 14:57:17 Functions: 97.7 % 175 171
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    139953103 : require_complete_type (tree value,
      75              :                        tsubst_flags_t complain /* = tf_warning_or_error */)
      76              : {
      77    139953103 :   tree type;
      78              : 
      79    139953103 :   if (processing_template_decl || value == error_mark_node)
      80              :     return value;
      81              : 
      82    129718953 :   if (TREE_CODE (value) == OVERLOAD)
      83            0 :     type = unknown_type_node;
      84              :   else
      85    129718953 :     type = TREE_TYPE (value);
      86              : 
      87    129718953 :   if (type == error_mark_node)
      88              :     return error_mark_node;
      89              : 
      90              :   /* First, detect a valid value with a complete type.  */
      91    129718941 :   if (COMPLETE_TYPE_P (type))
      92              :     return value;
      93              : 
      94       142633 :   if (complete_type_or_maybe_complain (type, value, complain))
      95              :     return value;
      96              :   else
      97          117 :     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  15135805642 : complete_type (tree type)
     107              : {
     108  15135805642 :   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  15135805642 :   if (type == error_mark_node || COMPLETE_TYPE_P (type))
     114              :     ;
     115   4910675059 :   else if (TREE_CODE (type) == ARRAY_TYPE)
     116              :     {
     117       778562 :       tree t = complete_type (TREE_TYPE (type));
     118       778562 :       unsigned int needs_constructing, has_nontrivial_dtor;
     119       778562 :       if (COMPLETE_TYPE_P (t) && !dependent_type_p (type))
     120       759491 :         layout_type (type);
     121       778562 :       needs_constructing
     122       778562 :         = TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (t));
     123       778562 :       has_nontrivial_dtor
     124       778562 :         = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TYPE_MAIN_VARIANT (t));
     125      2563816 :       for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
     126              :         {
     127      1785254 :           TYPE_NEEDS_CONSTRUCTING (t) = needs_constructing;
     128      1785254 :           TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = has_nontrivial_dtor;
     129              :         }
     130              :     }
     131   4909896497 :   else if (CLASS_TYPE_P (type))
     132              :     {
     133   4814645196 :       if (modules_p ())
     134              :         /* TYPE could be a class member we've not loaded the definition of.  */
     135     15673909 :         lazy_load_pendings (TYPE_NAME (TYPE_MAIN_VARIANT (type)));
     136              : 
     137   4814645196 :       if (CLASSTYPE_TEMPLATE_INSTANTIATION (type))
     138    924457222 :         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   1613467338 : complete_type_or_maybe_complain (tree type, tree value, tsubst_flags_t complain)
     150              : {
     151   1613467338 :   type = complete_type (type);
     152   1613467335 :   if (type == error_mark_node)
     153              :     /* We already issued an error.  */
     154              :     return NULL_TREE;
     155   1613467183 :   else if (!COMPLETE_TYPE_P (type))
     156              :     {
     157         3810 :       if (complain & tf_error)
     158          472 :         cxx_incomplete_type_diagnostic (value, type, diagnostics::kind::error);
     159         3810 :       note_failed_type_completion (type, complain);
     160         3810 :       return NULL_TREE;
     161              :     }
     162              :   else
     163              :     return type;
     164              : }
     165              : 
     166              : tree
     167    164403842 : complete_type_or_else (tree type, tree value)
     168              : {
     169    164403842 :   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      4136920 : commonparms (tree p1, tree p2)
     182              : {
     183      4136920 :   tree oldargs = p1, newargs, n;
     184      4136920 :   int i, len;
     185      4136920 :   int any_change = 0;
     186              : 
     187      4136920 :   len = list_length (p1);
     188      4136920 :   newargs = tree_last (p1);
     189              : 
     190      4136920 :   if (newargs == void_list_node)
     191              :     i = 1;
     192              :   else
     193              :     {
     194        39102 :       i = 0;
     195        39102 :       newargs = 0;
     196              :     }
     197              : 
     198     13703062 :   for (; i < len; i++)
     199      9566142 :     newargs = tree_cons (NULL_TREE, NULL_TREE, newargs);
     200              : 
     201              :   n = newargs;
     202              : 
     203     17800880 :   for (i = 0; p1;
     204     13663960 :        p1 = TREE_CHAIN (p1), p2 = TREE_CHAIN (p2), n = TREE_CHAIN (n), i++)
     205              :     {
     206     13664163 :       if (TREE_PURPOSE (p1) && !TREE_PURPOSE (p2))
     207              :         {
     208          170 :           TREE_PURPOSE (n) = TREE_PURPOSE (p1);
     209          170 :           any_change = 1;
     210              :         }
     211     13663790 :       else if (! TREE_PURPOSE (p1))
     212              :         {
     213     13663757 :           if (TREE_PURPOSE (p2))
     214              :             {
     215       417327 :               TREE_PURPOSE (n) = TREE_PURPOSE (p2);
     216       417327 :               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     13663960 :       if (TREE_VALUE (p1) != TREE_VALUE (p2))
     226              :         {
     227      3800237 :           any_change = 1;
     228      3800237 :           TREE_VALUE (n) = merge_types (TREE_VALUE (p1), TREE_VALUE (p2));
     229              :         }
     230              :       else
     231      9863723 :         TREE_VALUE (n) = TREE_VALUE (p1);
     232              :     }
     233      4136920 :   if (! any_change)
     234      1401456 :     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     32330684 : original_type (tree t)
     243              : {
     244     32330684 :   int quals = cp_type_quals (t);
     245     32330684 :   while (t != error_mark_node
     246     33461253 :          && TYPE_NAME (t) != NULL_TREE)
     247              :     {
     248     11290047 :       tree x = TYPE_NAME (t);
     249     11290047 :       if (TREE_CODE (x) != TYPE_DECL)
     250              :         break;
     251     11290047 :       x = DECL_ORIGINAL_TYPE (x);
     252     11290047 :       if (x == NULL_TREE)
     253              :         break;
     254              :       t = x;
     255              :     }
     256     32330684 :   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        59966 : merge_type_attributes_from (tree type, tree other_type)
     264              : {
     265        59966 :   tree attrs = targetm.merge_type_attributes (type, other_type);
     266        59966 :   attrs = restrict_type_identity_attributes_to (attrs, TYPE_ATTRIBUTES (type));
     267        59966 :   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      5228614 : cp_compare_floating_point_conversion_ranks (tree t1, tree t2)
     280              : {
     281      5228614 :   tree mv1 = TYPE_MAIN_VARIANT (t1);
     282      5228614 :   tree mv2 = TYPE_MAIN_VARIANT (t2);
     283      5228614 :   int extended1 = 0;
     284      5228614 :   int extended2 = 0;
     285              : 
     286      5228614 :   if (mv1 == mv2)
     287              :     return 0;
     288              : 
     289     41817592 :   for (int i = 0; i < NUM_FLOATN_NX_TYPES; ++i)
     290              :     {
     291     36590393 :       if (mv1 == FLOATN_NX_TYPE_NODE (i))
     292      2363156 :         extended1 = i + 1;
     293     36590393 :       if (mv2 == FLOATN_NX_TYPE_NODE (i))
     294      1962230 :         extended2 = i + 1;
     295              :     }
     296      5227199 :   if (mv1 == bfloat16_type_node)
     297       544258 :     extended1 = true;
     298      5227199 :   if (mv2 == bfloat16_type_node)
     299       434524 :     extended2 = true;
     300      5227199 :   if (extended2 && !extended1)
     301              :     {
     302      2289129 :       int ret = cp_compare_floating_point_conversion_ranks (t2, t1);
     303      2289129 :       return ret == 3 ? 3 : -ret;
     304              :     }
     305              : 
     306      2938070 :   const struct real_format *fmt1 = REAL_MODE_FORMAT (TYPE_MODE (t1));
     307      2938070 :   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      2938070 :   gcc_assert (fmt1->b == 2);
     313      2938070 :   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      2938037 :   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     23504296 :   int p1 = (MODE_COMPOSITE_P (TYPE_MODE (t1))
     338      5876074 :             ? fmt1->emax - fmt1->emin + fmt1->p - 1 : fmt1->p);
     339     23504296 :   int p2 = (MODE_COMPOSITE_P (TYPE_MODE (t2))
     340      5876074 :             ? 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      2938037 :   if ((p1 > p2 && fmt1->emax >= fmt2->emax)
     345      2292718 :        || (p1 == p2 && fmt1->emax > fmt2->emax))
     346              :     return 2;
     347      2292718 :   if ((p1 < p2 && fmt1->emax <= fmt2->emax)
     348       789996 :        || (p1 == p2 && fmt1->emax < fmt2->emax))
     349              :     return -2;
     350       789996 :   if ((p1 > p2 && fmt1->emax < fmt2->emax)
     351       785361 :        || (p1 < p2 && fmt1->emax > fmt2->emax))
     352              :     return 3;
     353       780726 :   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       780726 :   if (extended1 && extended2)
     374              :     {
     375            4 :       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            4 :       else if (extended1 <= NUM_FLOATN_TYPES)
     386              :         /* Prefer _FloatN type over _FloatMx type.  */
     387              :         return 1;
     388            2 :       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      3122888 :   for (p = &float_type_node; p <= &long_double_type_node; ++p)
     398              :     {
     399      2342166 :       const struct real_format *fmt3 = REAL_MODE_FORMAT (TYPE_MODE (*p));
     400      2342166 :       gcc_assert (fmt3->b == 2);
     401     18737328 :       int p3 = (MODE_COMPOSITE_P (TYPE_MODE (*p))
     402      4684332 :                 ? fmt3->emax - fmt3->emin + fmt3->p - 1 : fmt3->p);
     403      2342166 :       if (p1 == p3 && fmt1->emax == fmt3->emax)
     404       683626 :         ++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       780722 :   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    109144044 : cp_common_type (tree t1, tree t2)
     436              : {
     437    109144044 :   enum tree_code code1 = TREE_CODE (t1);
     438    109144044 :   enum tree_code code2 = TREE_CODE (t2);
     439    109144044 :   tree attributes;
     440    109144044 :   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    109144044 :   attributes = (*targetm.merge_type_attributes) (t1, t2);
     447              : 
     448    109144044 :   if (SCOPED_ENUM_P (t1) || SCOPED_ENUM_P (t2))
     449              :     {
     450      1979976 :       if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
     451      1979976 :         return build_type_attribute_variant (t1, attributes);
     452              :       else
     453              :         return NULL_TREE;
     454              :     }
     455              : 
     456              :   /* FIXME: Attributes.  */
     457    107164068 :   gcc_assert (ARITHMETIC_TYPE_P (t1)
     458              :               || VECTOR_TYPE_P (t1)
     459              :               || UNSCOPED_ENUM_P (t1));
     460    107164068 :   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    107164068 :   if (code1 == COMPLEX_TYPE || code2 == COMPLEX_TYPE)
     468              :     {
     469       217144 :       tree subtype1 = code1 == COMPLEX_TYPE ? TREE_TYPE (t1) : t1;
     470       217144 :       tree subtype2 = code2 == COMPLEX_TYPE ? TREE_TYPE (t2) : t2;
     471       217144 :       tree subtype
     472       217144 :         = type_after_usual_arithmetic_conversions (subtype1, subtype2);
     473              : 
     474       217144 :       if (subtype == error_mark_node)
     475              :         return subtype;
     476       217144 :       if (code1 == COMPLEX_TYPE && TREE_TYPE (t1) == subtype)
     477       183736 :         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    106946924 :   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        59966 :       if (TYPE_UNSIGNED (t1))
     490        12919 :         return merge_type_attributes_from (t1, t2);
     491              :       else
     492        47047 :         return merge_type_attributes_from (t2, t1);
     493              :     }
     494              : 
     495              :   /* If only one is real, use it as the result.  */
     496    106886958 :   if (code1 == REAL_TYPE && code2 != REAL_TYPE)
     497      1145668 :     return build_type_attribute_variant (t1, attributes);
     498    105741290 :   if (code2 == REAL_TYPE && code1 != REAL_TYPE)
     499      1006477 :     return build_type_attribute_variant (t2, attributes);
     500              : 
     501    104734813 :   if (code1 == REAL_TYPE
     502    104734813 :       && (extended_float_type_p (t1) || extended_float_type_p (t2)))
     503              :     {
     504       101712 :       tree mv1 = TYPE_MAIN_VARIANT (t1);
     505       101712 :       tree mv2 = TYPE_MAIN_VARIANT (t2);
     506       101712 :       if (mv1 == mv2)
     507        99492 :         return build_type_attribute_variant (t1, attributes);
     508              : 
     509         2220 :       int cmpret = cp_compare_floating_point_conversion_ranks (mv1, mv2);
     510         2220 :       if (cmpret == 3)
     511            6 :         return error_mark_node;
     512         2214 :       else if (cmpret >= 0)
     513         1938 :         return build_type_attribute_variant (t1, attributes);
     514              :       else
     515          276 :         return build_type_attribute_variant (t2, attributes);
     516              :     }
     517              : 
     518              :   /* Both real or both integers; use the one with greater precision.  */
     519    104633101 :   if (TYPE_PRECISION (t1) > TYPE_PRECISION (t2))
     520     16214143 :     return build_type_attribute_variant (t1, attributes);
     521     88418958 :   else if (TYPE_PRECISION (t2) > TYPE_PRECISION (t1))
     522      1848274 :     return build_type_attribute_variant (t2, attributes);
     523              : 
     524              :   /* The types are the same; no need to do anything fancy.  */
     525     86570684 :   if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
     526     79417641 :     return build_type_attribute_variant (t1, attributes);
     527              : 
     528      7153043 :   if (code1 != REAL_TYPE)
     529              :     {
     530              :       /* If one is unsigned long long, then convert the other to unsigned
     531              :          long long.  */
     532      7153040 :       if (same_type_p (TYPE_MAIN_VARIANT (t1), long_long_unsigned_type_node)
     533      7153040 :           || same_type_p (TYPE_MAIN_VARIANT (t2), long_long_unsigned_type_node))
     534       160892 :         return build_type_attribute_variant (long_long_unsigned_type_node,
     535       160892 :                                              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      6992148 :       if (same_type_p (TYPE_MAIN_VARIANT (t1), long_long_integer_type_node)
     547      6992148 :           || 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      6991479 :       if (same_type_p (TYPE_MAIN_VARIANT (t1), long_unsigned_type_node)
     557      6991479 :           || same_type_p (TYPE_MAIN_VARIANT (t2), long_unsigned_type_node))
     558       891278 :         return build_type_attribute_variant (long_unsigned_type_node,
     559       891278 :                                              attributes);
     560      6100201 :       if (same_type_p (TYPE_MAIN_VARIANT (t1), long_integer_type_node)
     561      6100201 :           || same_type_p (TYPE_MAIN_VARIANT (t2), long_integer_type_node))
     562              :         {
     563        75671 :           tree t = ((TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
     564        75671 :                     ? long_unsigned_type_node : long_integer_type_node);
     565        38310 :           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     12123750 :       for (i = 0; i < NUM_INT_N_ENTS; i ++)
     573              :         {
     574      6061891 :           if (int_n_enabled_p [i]
     575      6061891 :               && (same_type_p (TYPE_MAIN_VARIANT (t1), int_n_trees[i].signed_type)
     576      5974072 :                   || same_type_p (TYPE_MAIN_VARIANT (t2), int_n_trees[i].signed_type)
     577      5974068 :                   || same_type_p (TYPE_MAIN_VARIANT (t1), int_n_trees[i].unsigned_type)
     578      5974068 :                   || 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      6061859 :       if (TYPE_UNSIGNED (t1))
     589      4893542 :         return build_type_attribute_variant (t1, attributes);
     590              :       else
     591      1168317 :         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      1159718 : type_after_usual_arithmetic_conversions (tree t1, tree t2)
     623              : {
     624      1159718 :   gcc_assert (ARITHMETIC_TYPE_P (t1)
     625              :               || VECTOR_TYPE_P (t1)
     626              :               || UNSCOPED_ENUM_P (t1));
     627      1159718 :   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      1159718 :   if (INTEGRAL_OR_ENUMERATION_TYPE_P (t1)
     633       942163 :       && INTEGRAL_OR_ENUMERATION_TYPE_P (t2))
     634              :     {
     635       941888 :       t1 = type_promotes_to (t1);
     636       941888 :       t2 = type_promotes_to (t2);
     637              :     }
     638              : 
     639      1159718 :   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      6216866 : 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      6216866 :   tree pointee1;
     683      6216866 :   tree pointee2;
     684      6216866 :   tree result_type;
     685      6216866 :   tree attributes;
     686              : 
     687              :   /* Determine the types pointed to by T1 and T2.  */
     688      6216866 :   if (TYPE_PTR_P (t1))
     689              :     {
     690      6216328 :       pointee1 = TREE_TYPE (t1);
     691      6216328 :       pointee2 = TREE_TYPE (t2);
     692              :     }
     693              :   else
     694              :     {
     695          538 :       pointee1 = TYPE_PTRMEM_POINTED_TO_TYPE (t1);
     696          538 :       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      6216866 :   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      6216789 :   const int q1 = cp_type_quals (pointee1);
     723      6216789 :   const int q2 = cp_type_quals (pointee2);
     724      6216789 :   const int quals = q1 | q2;
     725      6216789 :   result_type = cp_build_qualified_type (result_type,
     726      6216789 :                                          (quals | (*add_const
     727      6216789 :                                                    ? 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      6216789 :   if (quals != q1 || quals != q2)
     733       712524 :     *add_const = true;
     734              :   /* If the original types were pointers to members, so is the
     735              :      result.  */
     736      6216789 :   if (TYPE_PTRMEM_P (t1))
     737              :     {
     738          524 :       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          524 :       result_type = build_ptrmem_type (TYPE_PTRMEM_CLASS_TYPE (t1),
     748              :                                        result_type);
     749              :     }
     750              :   else
     751      6216265 :     result_type = build_pointer_type (result_type);
     752              : 
     753              :   /* Merge the attributes.  */
     754      6216789 :   attributes = (*targetm.merge_type_attributes) (t1, t2);
     755      6216789 :   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      6674755 : 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      6674755 :   tree class1;
     773      6674755 :   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      6674755 :   if (null_ptr_cst_p (arg1))
     780              :     return t2;
     781      6674592 :   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      6653424 :   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      6653424 :   if (TYPE_PTR_P (t1) && VOID_TYPE_P (TREE_TYPE (t1)))
     799              :     {
     800       436486 :       tree attributes;
     801       436486 :       tree result_type;
     802              : 
     803       436486 :       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       436484 :       result_type
     833       436484 :         = cp_build_qualified_type (void_type_node,
     834       436484 :                                    (cp_type_quals (TREE_TYPE (t1))
     835       436484 :                                     | cp_type_quals (TREE_TYPE (t2))));
     836       436484 :       result_type = build_pointer_type (result_type);
     837              :       /* Merge the attributes.  */
     838       436484 :       attributes = (*targetm.merge_type_attributes) (t1, t2);
     839       436484 :       return build_type_attribute_variant (result_type, attributes);
     840              :     }
     841              : 
     842      6216938 :   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      6216938 :   if (fnptr_conv_p (t1, t2))
     853              :     return t1;
     854      6216903 :   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      6216313 :   if (TYPE_PTR_P (t1) && TYPE_PTR_P (t2)
     860      6216313 :       && CLASS_TYPE_P (TREE_TYPE (t1))
     861      1285872 :       && CLASS_TYPE_P (TREE_TYPE (t2))
     862      7502741 :       && !same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (t1),
     863      1285869 :                                                      TREE_TYPE (t2)))
     864              :     {
     865        29456 :       class1 = TREE_TYPE (t1);
     866        29456 :       class2 = TREE_TYPE (t2);
     867              : 
     868        29456 :       if (DERIVED_FROM_P (class1, class2))
     869         3140 :         t2 = (build_pointer_type
     870         1570 :               (cp_build_qualified_type (class1, cp_type_quals (class2))));
     871        27886 :       else if (DERIVED_FROM_P (class2, class1))
     872        55736 :         t1 = (build_pointer_type
     873        27868 :               (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      6186996 :   else if (TYPE_PTRMEM_P (t1)
     885      6187555 :            && !same_type_p (TYPE_PTRMEM_CLASS_TYPE (t1),
     886              :                             TYPE_PTRMEM_CLASS_TYPE (t2)))
     887              :     {
     888           69 :       class1 = TYPE_PTRMEM_CLASS_TYPE (t1);
     889           69 :       class2 = TYPE_PTRMEM_CLASS_TYPE (t2);
     890              : 
     891           69 :       if (DERIVED_FROM_P (class1, class2))
     892           35 :         t1 = build_ptrmem_type (class2, TYPE_PTRMEM_POINTED_TO_TYPE (t1));
     893           34 :       else if (DERIVED_FROM_P (class2, class1))
     894           13 :         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      6216833 :   bool add_const = false;
     923      6216833 :   return composite_pointer_type_r (location, t1, t2, &add_const, operation,
     924      6216833 :                                    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     29544895 : merge_types (tree t1, tree t2)
     936              : {
     937     29544895 :   enum tree_code code1;
     938     29544895 :   enum tree_code code2;
     939     29544895 :   tree attributes;
     940              : 
     941              :   /* Save time if the two types are the same.  */
     942     29544895 :   if (t1 == t2)
     943              :     return t1;
     944     16165342 :   if (original_type (t1) == original_type (t2))
     945              :     return t1;
     946              : 
     947              :   /* If one type is nonsense, use the other.  */
     948     16045817 :   if (t1 == error_mark_node)
     949              :     return t2;
     950     16045817 :   if (t2 == error_mark_node)
     951              :     return t1;
     952              : 
     953              :   /* Handle merging an auto redeclaration with a previous deduced
     954              :      return type.  */
     955     16045817 :   if (is_auto (t1))
     956              :     return t2;
     957              : 
     958              :   /* Merge the attributes.  */
     959     16036704 :   attributes = (*targetm.merge_type_attributes) (t1, t2);
     960              : 
     961     16036704 :   if (TYPE_PTRMEMFUNC_P (t1))
     962           15 :     t1 = TYPE_PTRMEMFUNC_FN_TYPE (t1);
     963     16036704 :   if (TYPE_PTRMEMFUNC_P (t2))
     964           15 :     t2 = TYPE_PTRMEMFUNC_FN_TYPE (t2);
     965              : 
     966     16036704 :   code1 = TREE_CODE (t1);
     967     16036704 :   code2 = TREE_CODE (t2);
     968     16036704 :   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     16036704 :   switch (code1)
     984              :     {
     985      2721222 :     case POINTER_TYPE:
     986      2721222 :     case REFERENCE_TYPE:
     987              :       /* For two pointers, do this recursively on the target type.  */
     988      2721222 :       {
     989      2721222 :         tree target = merge_types (TREE_TYPE (t1), TREE_TYPE (t2));
     990      2721222 :         int quals = cp_type_quals (t1);
     991              : 
     992      2721222 :         if (code1 == POINTER_TYPE)
     993              :           {
     994       722426 :             t1 = build_pointer_type (target);
     995       722426 :             if (TREE_CODE (target) == METHOD_TYPE)
     996           15 :               t1 = build_ptrmemfunc_type (t1);
     997              :           }
     998              :         else
     999      1998796 :           t1 = cp_build_reference_type (target, TYPE_REF_IS_RVALUE (t1));
    1000      2721222 :         t1 = build_type_attribute_variant (t1, attributes);
    1001      2721222 :         t1 = cp_build_qualified_type (t1, quals);
    1002              : 
    1003      2721222 :         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        10327 :     case ARRAY_TYPE:
    1020        10327 :       {
    1021        10327 :         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        20654 :         if (elt == TREE_TYPE (t1) && TYPE_DOMAIN (t1))
    1024        10302 :           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      4281632 :     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      4281632 :       {
    1037      4281632 :         tree valtype = merge_types (TREE_TYPE (t1), TREE_TYPE (t2));
    1038      4281632 :         tree p1 = TYPE_ARG_TYPES (t1);
    1039      4281632 :         tree p2 = TYPE_ARG_TYPES (t2);
    1040      4281632 :         tree parms;
    1041              : 
    1042              :         /* Save space: see if the result is identical to one of the args.  */
    1043      4281632 :         if (valtype == TREE_TYPE (t1) && ! p2)
    1044            0 :           return cp_build_type_attribute_variant (t1, attributes);
    1045      4281632 :         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      8563264 :         if (p1 == NULL_TREE || TREE_VALUE (p1) == void_type_node)
    1050              :           parms = p2;
    1051      8273840 :         else if (p2 == NULL_TREE || TREE_VALUE (p2) == void_type_node)
    1052              :           parms = p1;
    1053              :         else
    1054      4136920 :           parms = commonparms (p1, p2);
    1055              : 
    1056      4281632 :         cp_cv_quals quals = type_memfn_quals (t1);
    1057      4281632 :         cp_ref_qualifier rqual = type_memfn_rqual (t1);
    1058      4281632 :         gcc_assert (quals == type_memfn_quals (t2));
    1059      4281632 :         gcc_assert (rqual == type_memfn_rqual (t2));
    1060              : 
    1061      4281632 :         tree rval = cp_build_function_type (valtype, parms);
    1062      4281632 :         rval = apply_memfn_quals (rval, quals);
    1063      4281632 :         tree raises = merge_exception_specifiers (TYPE_RAISES_EXCEPTIONS (t1),
    1064      4281632 :                                                   TYPE_RAISES_EXCEPTIONS (t2));
    1065      4281632 :         bool late_return_type_p = TYPE_HAS_LATE_RETURN_TYPE (t1);
    1066      4281632 :         t1 = build_cp_fntype_variant (rval, rqual, raises, late_return_type_p);
    1067      4281632 :         break;
    1068              :       }
    1069              : 
    1070      3892473 :     case METHOD_TYPE:
    1071      3892473 :       {
    1072              :         /* Get this value the long way, since TYPE_METHOD_BASETYPE
    1073              :            is just the main variant of this.  */
    1074      3892473 :         tree basetype = class_of_this_parm (t2);
    1075      3892473 :         tree raises = merge_exception_specifiers (TYPE_RAISES_EXCEPTIONS (t1),
    1076      3892473 :                                                   TYPE_RAISES_EXCEPTIONS (t2));
    1077      3892473 :         cp_ref_qualifier rqual = type_memfn_rqual (t1);
    1078      3892473 :         tree t3;
    1079      3892473 :         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      3892473 :         t1 = cp_build_function_type (TREE_TYPE (t1),
    1085      3892473 :                                      TREE_CHAIN (TYPE_ARG_TYPES (t1)));
    1086      3892473 :         t2 = cp_build_function_type (TREE_TYPE (t2),
    1087      3892473 :                                      TREE_CHAIN (TYPE_ARG_TYPES (t2)));
    1088      3892473 :         t3 = merge_types (t1, t2);
    1089      3892473 :         t3 = build_method_type_directly (basetype, TREE_TYPE (t3),
    1090      3892473 :                                          TYPE_ARG_TYPES (t3));
    1091      3892473 :         t1 = build_cp_fntype_variant (t3, rqual, raises, late_return_type_1_p);
    1092      3892473 :         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      5121101 :     default:;
    1102      5121101 :       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      8174123 :   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       619496 : common_type (tree t1, tree t2)
    1135              : {
    1136              :   /* If one type is nonsense, use the other  */
    1137       619496 :   if (t1 == error_mark_node)
    1138              :     return t2;
    1139       619496 :   if (t2 == error_mark_node)
    1140              :     return t1;
    1141              : 
    1142       619496 :   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      1470482 : common_pointer_type (tree t1, tree t2)
    1154              : {
    1155      1470482 :   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      1470482 :   return composite_pointer_type (input_location, t1, t2,
    1160              :                                  error_mark_node, error_mark_node,
    1161      1470482 :                                  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         1782 : comp_except_types (tree a, tree b, bool exact)
    1182              : {
    1183         1782 :   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   1613134199 : comp_except_specs (const_tree t1, const_tree t2, int exact)
    1218              : {
    1219   1613134199 :   const_tree probe;
    1220   1613134199 :   const_tree base;
    1221   1613134199 :   int  length = 0;
    1222              : 
    1223   1613134199 :   if (t1 == t2)
    1224              :     return true;
    1225              : 
    1226              :   /* First handle noexcept.  */
    1227    658046423 :   if (exact < ce_exact)
    1228              :     {
    1229      9236057 :       if (exact == ce_type
    1230     18429278 :           && (canonical_eh_spec (const_cast<tree> (t1))
    1231      9193221 :               == 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      9216357 :       if (t1 == noexcept_false_spec)
    1237          154 :         return t2 == NULL_TREE || exact == ce_derived;
    1238              :       /* Even a derived noexcept(false) is compatible with no
    1239              :          exception-specification.  */
    1240      9216203 :       if (t2 == noexcept_false_spec)
    1241          895 :         return t1 == NULL_TREE;
    1242              : 
    1243              :       /* Otherwise, if we aren't looking for an exact match, noexcept is
    1244              :          equivalent to throw().  */
    1245      9215308 :       if (t1 == noexcept_true_spec)
    1246       691231 :         t1 = empty_except_spec;
    1247      9215308 :       if (t2 == noexcept_true_spec)
    1248      8343455 :         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    629338052 :   if ((t1 && TREE_PURPOSE (t1))
    1255    689614802 :       || (t2 && TREE_PURPOSE (t2)))
    1256    646608099 :     return (t1 && t2
    1257    646608099 :             && (exact == ce_exact
    1258     80048591 :                 ? TREE_PURPOSE (t1) == TREE_PURPOSE (t2)
    1259       177669 :                 : cp_tree_equal (TREE_PURPOSE (t1), TREE_PURPOSE (t2))));
    1260              : 
    1261     11417575 :   if (t1 == NULL_TREE)                     /* T1 is ...  */
    1262      8577999 :     return t2 == NULL_TREE || exact == ce_derived;
    1263      2839576 :   if (!TREE_VALUE (t1))                    /* t1 is EMPTY */
    1264      2805618 :     return t2 != NULL_TREE && !TREE_VALUE (t2);
    1265        35266 :   if (t2 == NULL_TREE)                     /* T2 is ...  */
    1266              :     return false;
    1267         1660 :   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         2863 :   for (base = t1; t2 != NULL_TREE; t2 = TREE_CHAIN (t2))
    1275              :     {
    1276         2178 :       for (probe = base; probe != NULL_TREE; probe = TREE_CHAIN (probe))
    1277              :         {
    1278         1782 :           tree a = TREE_VALUE (probe);
    1279         1782 :           tree b = TREE_VALUE (t2);
    1280              : 
    1281         1782 :           if (comp_except_types (a, b, exact))
    1282              :             {
    1283         1279 :               if (probe == base && exact > ce_derived)
    1284         1244 :                 base = TREE_CHAIN (probe);
    1285         1279 :               length++;
    1286         1279 :               break;
    1287              :             }
    1288              :         }
    1289         1279 :       if (probe == NULL_TREE)
    1290              :         return false;
    1291              :     }
    1292         1188 :   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      1775041 : comp_array_types (const_tree t1, const_tree t2, compare_bounds_t cb,
    1303              :                   bool strict)
    1304              : {
    1305      1775041 :   tree d1;
    1306      1775041 :   tree d2;
    1307      1775041 :   tree max1, max2;
    1308              : 
    1309      1775041 :   if (t1 == t2)
    1310              :     return true;
    1311              : 
    1312              :   /* The type of the array elements must be the same.  */
    1313      1774557 :   if (strict
    1314      1774557 :       ? !same_type_p (TREE_TYPE (t1), TREE_TYPE (t2))
    1315         8621 :       : !similar_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
    1316              :     return false;
    1317              : 
    1318      1149002 :   d1 = TYPE_DOMAIN (t1);
    1319      1149002 :   d2 = TYPE_DOMAIN (t2);
    1320              : 
    1321      1149002 :   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       656035 :   if (!d1 && d2)
    1337         5057 :     return cb >= bounds_either;
    1338       650978 :   else if (d1 && !d2)
    1339         7976 :     return cb == bounds_either;
    1340              : 
    1341              :   /* Check that the dimensions are the same.  */
    1342              : 
    1343       643002 :   if (!cp_tree_equal (TYPE_MIN_VALUE (d1), TYPE_MIN_VALUE (d2)))
    1344              :     return false;
    1345       642981 :   max1 = TYPE_MAX_VALUE (d1);
    1346       642981 :   max2 = TYPE_MAX_VALUE (d2);
    1347              : 
    1348       642981 :   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   1639317285 : comp_template_parms_position (tree t1, tree t2)
    1361              : {
    1362   1639317285 :   tree index1, index2;
    1363   1639317285 :   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   1639317285 :   index1 = TEMPLATE_TYPE_PARM_INDEX (TYPE_MAIN_VARIANT (t1));
    1370   1639317285 :   index2 = TEMPLATE_TYPE_PARM_INDEX (TYPE_MAIN_VARIANT (t2));
    1371              : 
    1372              :   /* Then compare their relative position.  */
    1373   1639317285 :   if (TEMPLATE_PARM_IDX (index1) != TEMPLATE_PARM_IDX (index2)
    1374   1116475767 :       || TEMPLATE_PARM_LEVEL (index1) != TEMPLATE_PARM_LEVEL (index2)
    1375   2495375025 :       || (TEMPLATE_PARM_PARAMETER_PACK (index1)
    1376    856057740 :           != 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    770699089 :   if (cxx_dialect >= cxx14 && (is_auto (t1) || is_auto (t2)))
    1382    218535715 :     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          346 : cxx_safe_function_type_cast_p (tree t1, tree t2)
    1414              : {
    1415          346 :   if (TREE_TYPE (t1) == void_type_node &&
    1416          273 :       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  15852778896 : structural_comptypes (tree t1, tree t2, int strict)
    1439              : {
    1440              :   /* Both should be types that are not obviously the same.  */
    1441  15852778896 :   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  15852778896 :   if (!comparing_specializations)
    1446              :     {
    1447              :       /* TYPENAME_TYPEs should be resolved if the qualifying scope is the
    1448              :          current instantiation.  */
    1449  12736308486 :       if (TREE_CODE (t1) == TYPENAME_TYPE)
    1450     99645465 :         t1 = resolve_typename_type (t1, /*only_current_p=*/true);
    1451              : 
    1452  12736308486 :       if (TREE_CODE (t2) == TYPENAME_TYPE)
    1453    131484309 :         t2 = resolve_typename_type (t2, /*only_current_p=*/true);
    1454              :     }
    1455              : 
    1456  15852778896 :   if (TYPE_PTRMEMFUNC_P (t1))
    1457     25268992 :     t1 = TYPE_PTRMEMFUNC_FN_TYPE (t1);
    1458  15852778896 :   if (TYPE_PTRMEMFUNC_P (t2))
    1459     28443779 :     t2 = TYPE_PTRMEMFUNC_FN_TYPE (t2);
    1460              : 
    1461              :   /* Different classes of types can't be compatible.  */
    1462  15852778896 :   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  10425813405 :   if (TREE_CODE (t1) != ARRAY_TYPE
    1468  10425813405 :       && cp_type_quals (t1) != cp_type_quals (t2))
    1469              :     return false;
    1470   9767677827 :   if (TREE_CODE (t1) == FUNCTION_TYPE
    1471   9767677827 :       && 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   9767616586 :   if (FUNC_OR_METHOD_TYPE_P (t1))
    1476              :     {
    1477     36715153 :       if (type_memfn_rqual (t1) != type_memfn_rqual (t2))
    1478              :         return false;
    1479     21926023 :       if (flag_noexcept_type
    1480     43773436 :           && !comp_except_specs (TYPE_RAISES_EXCEPTIONS (t1),
    1481     21847413 :                                  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   9743792821 :   if (TREE_CODE (t1) != ARRAY_TYPE
    1490   9743792821 :       && TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
    1491    447359252 :     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   9296433569 :   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    766641077 :     case OPAQUE_TYPE:
    1504    766641077 :     case INTEGER_TYPE:
    1505    766641077 :     case FIXED_POINT_TYPE:
    1506    766641077 :     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    766641077 :       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      1727976 :     case TEMPLATE_TEMPLATE_PARM:
    1528      1727976 :     case BOUND_TEMPLATE_TEMPLATE_PARM:
    1529      1727976 :       if (!comp_template_parms_position (t1, t2))
    1530              :         return false;
    1531      1326742 :       if (!comp_template_parms
    1532      2653484 :           (DECL_TEMPLATE_PARMS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (t1)),
    1533      3700308 :            DECL_TEMPLATE_PARMS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (t2))))
    1534              :         return false;
    1535       918100 :       if (TREE_CODE (t1) == TEMPLATE_TEMPLATE_PARM)
    1536              :         break;
    1537              :       /* Don't check inheritance.  */
    1538              :       strict = COMPARE_STRICT;
    1539              :       /* Fall through.  */
    1540              : 
    1541   4441242037 :     case RECORD_TYPE:
    1542   4441242037 :     case UNION_TYPE:
    1543   7793273051 :       if (TYPE_TEMPLATE_INFO (t1) && TYPE_TEMPLATE_INFO (t2)
    1544   2755796093 :           && (TYPE_TI_TEMPLATE (t1) == TYPE_TI_TEMPLATE (t2)
    1545   1970077524 :               || TREE_CODE (t1) == BOUND_TEMPLATE_TEMPLATE_PARM)
    1546   5227082207 :           && comp_template_args (TYPE_TI_ARGS (t1), TYPE_TI_ARGS (t2)))
    1547              :         break;
    1548              : 
    1549   4379641225 :       if ((strict & COMPARE_BASE) && DERIVED_FROM_P (t1, t2))
    1550              :         break;
    1551   4379641192 :       else if ((strict & COMPARE_DERIVED) && DERIVED_FROM_P (t2, t1))
    1552              :         break;
    1553              : 
    1554              :       return false;
    1555              : 
    1556        50345 :     case OFFSET_TYPE:
    1557        50345 :       if (!comptypes (TYPE_OFFSET_BASETYPE (t1), TYPE_OFFSET_BASETYPE (t2),
    1558              :                       strict & ~COMPARE_REDECLARATION))
    1559              :         return false;
    1560        48245 :       if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
    1561              :         return false;
    1562              :       break;
    1563              : 
    1564   1375127008 :     case REFERENCE_TYPE:
    1565   1375127008 :       if (TYPE_REF_IS_RVALUE (t1) != TYPE_REF_IS_RVALUE (t2))
    1566              :         return false;
    1567              :       /* fall through to checks for pointer types */
    1568   1732777056 :       gcc_fallthrough ();
    1569              : 
    1570   1732777056 :     case POINTER_TYPE:
    1571   1732777056 :       if (TYPE_MODE (t1) != TYPE_MODE (t2)
    1572   1732777056 :           || !same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
    1573   1587715201 :         return false;
    1574              :       break;
    1575              : 
    1576      5471852 :     case FUNCTION_TYPE:
    1577      5471852 :       if (TYPE_NO_NAMED_ARGS_STDARG_P (t1) != TYPE_NO_NAMED_ARGS_STDARG_P (t2))
    1578              :         return false;
    1579              :       /* FALLTHRU */
    1580     12602407 :     case METHOD_TYPE:
    1581              :       /* Exception specs and memfn_rquals were checked above.  */
    1582     12602407 :       if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
    1583              :         return false;
    1584     11979984 :       if (!compparms (TYPE_ARG_TYPES (t1), TYPE_ARG_TYPES (t2)))
    1585              :         return false;
    1586              :       break;
    1587              : 
    1588      1765936 :     case ARRAY_TYPE:
    1589              :       /* Target types must match incl. qualifiers.  */
    1590      1765936 :       if (!comp_array_types (t1, t2, ((strict & COMPARE_REDECLARATION)
    1591      1765936 :                                       ? bounds_either : bounds_none),
    1592              :                              /*strict=*/true))
    1593              :         return false;
    1594              :       break;
    1595              : 
    1596   1637589309 :     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   1637589309 :       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   1207919810 :       if (!cp_tree_equal (CLASS_PLACEHOLDER_TEMPLATE (t1),
    1604    603959905 :                           CLASS_PLACEHOLDER_TEMPLATE (t2)))
    1605              :         return false;
    1606              :       /* Constrained 'auto's are distinct from parms that don't have the same
    1607              :          constraints.  */
    1608    586413736 :       if (!equivalent_placeholder_constraints (t1, t2))
    1609              :         return false;
    1610              :       break;
    1611              : 
    1612    266973273 :     case TYPENAME_TYPE:
    1613    533946546 :       if (!cp_tree_equal (TYPENAME_TYPE_FULLNAME (t1),
    1614    266973273 :                           TYPENAME_TYPE_FULLNAME (t2)))
    1615              :         return false;
    1616              :       /* Qualifiers don't matter on scopes.  */
    1617    234509198 :       if (!same_type_ignoring_top_level_qualifiers_p (TYPE_CONTEXT (t1),
    1618    234509198 :                                                       TYPE_CONTEXT (t2)))
    1619              :         return false;
    1620              :       break;
    1621              : 
    1622        26757 :     case UNBOUND_CLASS_TEMPLATE:
    1623        26757 :       if (!cp_tree_equal (TYPE_IDENTIFIER (t1), TYPE_IDENTIFIER (t2)))
    1624              :         return false;
    1625        26757 :       if (!same_type_p (TYPE_CONTEXT (t1), TYPE_CONTEXT (t2)))
    1626              :         return false;
    1627              :       break;
    1628              : 
    1629      2105865 :     case COMPLEX_TYPE:
    1630      2105865 :       if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
    1631              :         return false;
    1632              :       break;
    1633              : 
    1634     12722661 :     case VECTOR_TYPE:
    1635     12722661 :       if (gnu_vector_type_p (t1) != gnu_vector_type_p (t2)
    1636     23755495 :           || maybe_ne (TYPE_VECTOR_SUBPARTS (t1), TYPE_VECTOR_SUBPARTS (t2))
    1637     23811885 :           || !same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
    1638      1689827 :         return false;
    1639              :       break;
    1640              : 
    1641      7363649 :     case TYPE_PACK_EXPANSION:
    1642      7363649 :       return (same_type_p (PACK_EXPANSION_PATTERN (t1),
    1643              :                            PACK_EXPANSION_PATTERN (t2))
    1644     14571587 :               && comp_template_args (PACK_EXPANSION_EXTRA_ARGS (t1),
    1645      7207938 :                                      PACK_EXPANSION_EXTRA_ARGS (t2)));
    1646              : 
    1647           17 :     case PACK_INDEX_TYPE:
    1648           17 :       return (cp_tree_equal (PACK_INDEX_PACK (t1),
    1649           17 :                              PACK_INDEX_PACK (t2))
    1650           20 :               && cp_tree_equal (PACK_INDEX_INDEX (t1),
    1651            3 :                                 PACK_INDEX_INDEX (t2)));
    1652              : 
    1653     29147136 :     case DECLTYPE_TYPE:
    1654     58294272 :       if (DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t1)
    1655     29147136 :           != DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t2))
    1656              :         return false;
    1657     29132176 :       if (DECLTYPE_FOR_LAMBDA_CAPTURE (t1) != DECLTYPE_FOR_LAMBDA_CAPTURE (t2))
    1658              :         return false;
    1659     29132176 :       if (DECLTYPE_FOR_LAMBDA_PROXY (t1) != DECLTYPE_FOR_LAMBDA_PROXY (t2))
    1660              :         return false;
    1661     29132176 :       if (!cp_tree_equal (DECLTYPE_TYPE_EXPR (t1), DECLTYPE_TYPE_EXPR (t2)))
    1662              :         return false;
    1663              :       break;
    1664              : 
    1665       714293 :     case TRAIT_TYPE:
    1666       714293 :       if (TRAIT_TYPE_KIND (t1) != TRAIT_TYPE_KIND (t2))
    1667              :         return false;
    1668         1439 :       if (!cp_tree_equal (TRAIT_TYPE_TYPE1 (t1), TRAIT_TYPE_TYPE1 (t2))
    1669         2878 :           || !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    818662517 :   if (!comp_type_attributes (t1, t2))
    1686              :     return false;
    1687              : 
    1688    818661330 :  check_alias:
    1689   1266029899 :   if (comparing_dependent_aliases
    1690   1266029899 :       && (typedef_variant_p (t1) || typedef_variant_p (t2)))
    1691              :     {
    1692      4297244 :       tree dep1 = dependent_opaque_alias_p (t1) ? t1 : NULL_TREE;
    1693      4297244 :       tree dep2 = dependent_opaque_alias_p (t2) ? t2 : NULL_TREE;
    1694      4297244 :       if ((dep1 || dep2)
    1695      4297244 :           && (!(dep1 && dep2)
    1696            0 :               || !comp_type_attributes (DECL_ATTRIBUTES (TYPE_NAME (dep1)),
    1697            0 :                                         DECL_ATTRIBUTES (TYPE_NAME (dep2)))))
    1698           28 :         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      4297216 :       ++processing_template_decl;
    1707      4297216 :       dep1 = dependent_alias_template_spec_p (t1, nt_transparent);
    1708      4297216 :       dep2 = dependent_alias_template_spec_p (t2, nt_transparent);
    1709      4297216 :       --processing_template_decl;
    1710      4297216 :       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         1605 : compatible_types_for_indirection_note_p (tree type1, tree type2)
    1721              : {
    1722         1605 :   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  24007939984 : comptypes (tree t1, tree t2, int strict)
    1730              : {
    1731  24007939984 :   gcc_checking_assert (t1 && t2);
    1732              : 
    1733              :   /* TYPE_ARGUMENT_PACKS are not really types.  */
    1734  24007939984 :   gcc_checking_assert (TREE_CODE (t1) != TYPE_ARGUMENT_PACK
    1735              :                        && TREE_CODE (t2) != TYPE_ARGUMENT_PACK);
    1736              : 
    1737  24007939984 :   if (t1 == t2)
    1738              :     return true;
    1739              : 
    1740              :   /* Suppress errors caused by previously reported errors.  */
    1741  15852780060 :   if (t1 == error_mark_node || t2 == error_mark_node)
    1742              :     return false;
    1743              : 
    1744  15852779899 :   if (strict == COMPARE_STRICT)
    1745              :     {
    1746  14415212832 :       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   1635299447 :         return structural_comptypes (t1, t2, strict);
    1750              : 
    1751  12779913385 :       if (flag_checking && param_use_canonical_types)
    1752              :         {
    1753  12779912382 :           bool result = structural_comptypes (t1, t2, strict);
    1754              : 
    1755  12779912382 :           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  12779912382 :           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   1437567067 :   else if (strict == COMPARE_STRUCTURAL)
    1778   1368138607 :     return structural_comptypes (t1, t2, COMPARE_STRICT);
    1779              :   else
    1780     69428460 :     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   3947503304 : same_type_ignoring_top_level_qualifiers_p (tree type1, tree type2)
    1788              : {
    1789   3947503304 :   if (type1 == error_mark_node || type2 == error_mark_node)
    1790              :     return false;
    1791   3947502588 :   if (type1 == type2)
    1792              :     return true;
    1793              : 
    1794   2240773746 :   type1 = cp_build_qualified_type (type1, TYPE_UNQUALIFIED);
    1795   2240773746 :   type2 = cp_build_qualified_type (type2, TYPE_UNQUALIFIED);
    1796   2240773746 :   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    336292557 : similar_type_p (tree type1, tree type2)
    1803              : {
    1804    336292557 :   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    336292557 :   if (same_type_ignoring_top_level_qualifiers_p (type1, type2))
    1816              :     return true;
    1817              : 
    1818    154685467 :   if ((TYPE_PTR_P (type1) && TYPE_PTR_P (type2))
    1819    154409520 :       || (TYPE_PTRDATAMEM_P (type1) && TYPE_PTRDATAMEM_P (type2))
    1820    154408587 :       || (TREE_CODE (type1) == ARRAY_TYPE && TREE_CODE (type2) == ARRAY_TYPE))
    1821       278747 :     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         2204 : next_common_initial_sequence (tree &memb1, tree &memb2)
    1833              : {
    1834         2723 :   while (memb1)
    1835              :     {
    1836         2762 :       if (TREE_CODE (memb1) != FIELD_DECL
    1837         2306 :           || (DECL_FIELD_IS_BASE (memb1) && is_empty_field (memb1)))
    1838              :         {
    1839          456 :           memb1 = DECL_CHAIN (memb1);
    1840          456 :           continue;
    1841              :         }
    1842         1850 :       if (DECL_FIELD_IS_BASE (memb1))
    1843              :         {
    1844           63 :           memb1 = TYPE_FIELDS (TREE_TYPE (memb1));
    1845           63 :           continue;
    1846              :         }
    1847              :       break;
    1848              :     }
    1849         2684 :   while (memb2)
    1850              :     {
    1851         2720 :       if (TREE_CODE (memb2) != FIELD_DECL
    1852         2267 :           || (DECL_FIELD_IS_BASE (memb2) && is_empty_field (memb2)))
    1853              :         {
    1854          453 :           memb2 = DECL_CHAIN (memb2);
    1855          453 :           continue;
    1856              :         }
    1857         1814 :       if (DECL_FIELD_IS_BASE (memb2))
    1858              :         {
    1859           27 :           memb2 = TYPE_FIELDS (TREE_TYPE (memb2));
    1860           27 :           continue;
    1861              :         }
    1862              :       break;
    1863              :     }
    1864         2204 :   if (memb1 == NULL_TREE && memb2 == NULL_TREE)
    1865              :     return true;
    1866         1787 :   if (memb1 == NULL_TREE || memb2 == NULL_TREE)
    1867              :     return false;
    1868         1787 :   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         1622 :   else if (DECL_BIT_FIELD_TYPE (memb2))
    1880              :     return false;
    1881         1595 :   else if (!layout_compatible_type_p (TREE_TYPE (memb1), TREE_TYPE (memb2)))
    1882              :     return false;
    1883         1595 :   if ((!lookup_attribute ("no_unique_address", DECL_ATTRIBUTES (memb1)))
    1884         1595 :       != !lookup_attribute ("no_unique_address", DECL_ATTRIBUTES (memb2)))
    1885              :     return false;
    1886         1568 :   if (DECL_ALIGN (memb1) != DECL_ALIGN (memb2))
    1887              :     return false;
    1888         1509 :   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         2744 : layout_compatible_type_p (tree type1, tree type2, bool explain/*=false*/)
    1897              : {
    1898         2744 :   if (type1 == error_mark_node || type2 == error_mark_node)
    1899              :     return false;
    1900         2744 :   if (type1 == type2)
    1901              :     return true;
    1902              : 
    1903         1335 :   type1 = cp_build_qualified_type (type1, TYPE_UNQUALIFIED);
    1904         1335 :   type2 = cp_build_qualified_type (type2, TYPE_UNQUALIFIED);
    1905         1335 :   if (same_type_p (type1, type2))
    1906              :     return true;
    1907              : 
    1908          633 :   if (TREE_CODE (type1) != TREE_CODE (type2)
    1909          591 :       || (TREE_CODE (type1) != ENUMERAL_TYPE
    1910          558 :           && !CLASS_TYPE_P (type1))
    1911         1077 :       || (TREE_CODE (type2) != ENUMERAL_TYPE
    1912          411 :           && !CLASS_TYPE_P (type2)))
    1913              :     {
    1914          189 :       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          189 :       return false;
    1920              :     }
    1921              : 
    1922          444 :   if (!std_layout_type_p (type1))
    1923              :     {
    1924           15 :       if (explain)
    1925            3 :         inform (location_of (type1),
    1926              :                 "%qT is not a standard-layout type", type1);
    1927           15 :       return false;
    1928              :     }
    1929          429 :   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          429 :   if (TREE_CODE (type1) == ENUMERAL_TYPE)
    1938              :     {
    1939           33 :       tree underlying1 = finish_underlying_type (type1);
    1940           33 :       tree underlying2 = finish_underlying_type (type2);
    1941           33 :       if (!same_type_p (underlying1, underlying2))
    1942              :         {
    1943           21 :           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           21 :           return false;
    1953              :         }
    1954              :     }
    1955          396 :   else if (TREE_CODE (type1) == RECORD_TYPE)
    1956              :     {
    1957          312 :       tree field1 = TYPE_FIELDS (type1);
    1958          312 :       tree field2 = TYPE_FIELDS (type2);
    1959         1170 :       while (1)
    1960              :         {
    1961          741 :           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          714 :           if (field1 == NULL_TREE)
    1985              :             break;
    1986          429 :           field1 = DECL_CHAIN (field1);
    1987          429 :           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    253979609 : at_least_as_qualified_p (const_tree type1, const_tree type2)
    2086              : {
    2087    253979609 :   int q1 = cp_type_quals (type1);
    2088    253979609 :   int q2 = cp_type_quals (type2);
    2089              : 
    2090              :   /* All qualifiers for TYPE2 must also appear in TYPE1.  */
    2091    253979609 :   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     16136178 : comp_cv_qualification (int q1, int q2)
    2099              : {
    2100     16136178 :   if (q1 == q2)
    2101              :     return 0;
    2102              : 
    2103      3530014 :   if ((q1 & q2) == q2)
    2104              :     return 1;
    2105       348980 :   else if ((q1 & q2) == q1)
    2106       348395 :     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   1056610952 : compparms (const_tree parms1, const_tree parms2)
    2143              : {
    2144   1056610952 :   const_tree t1, t2;
    2145              : 
    2146              :   /* An unspecified parmlist matches any specified parmlist
    2147              :      whose argument types don't need default promotions.  */
    2148              : 
    2149   1056610952 :   for (t1 = parms1, t2 = parms2;
    2150   1689852491 :        t1 || t2;
    2151    633241539 :        t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2))
    2152              :     {
    2153              :       /* If one parmlist is shorter than the other,
    2154              :          they fail to match.  */
    2155   1579027917 :       if (!t1 || !t2)
    2156              :         return false;
    2157   1578454852 :       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     27196655 : cxx_sizeof_or_alignof_type (location_t loc, tree type, enum tree_code op,
    2171              :                             bool std_alignof, bool complain)
    2172              : {
    2173     27196655 :   gcc_assert (op == SIZEOF_EXPR || op == ALIGNOF_EXPR);
    2174     27196655 :   if (type == error_mark_node)
    2175              :     return error_mark_node;
    2176              : 
    2177     27196653 :   type = non_reference (type);
    2178     27196653 :   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     27196653 :   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     27196641 :   bool dependent_p = dependent_type_p (type);
    2199     27196641 :   if (!dependent_p)
    2200              :     {
    2201     22435676 :       complete_type (type);
    2202     22435676 :       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     22435676 :   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     22435676 :       || (processing_template_decl
    2216      2027124 :           && COMPLETE_TYPE_P (type)
    2217      2027118 :           && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST))
    2218              :     {
    2219      4760965 :       tree value = build_min (op, size_type_node, type);
    2220      4760965 :       TREE_READONLY (value) = 1;
    2221      4760965 :       if (op == ALIGNOF_EXPR && std_alignof)
    2222       558555 :         ALIGNOF_EXPR_STD_P (value) = true;
    2223      4760965 :       SET_EXPR_LOCATION (value, loc);
    2224      4760965 :       return value;
    2225              :     }
    2226              : 
    2227     22435676 :   return c_sizeof_or_alignof_type (loc, complete_type (type),
    2228              :                                    op == SIZEOF_EXPR, std_alignof,
    2229     22435676 :                                    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      2728085 : cxx_sizeof_nowarn (tree type)
    2238              : {
    2239      2728085 :   if (TREE_CODE (type) == FUNCTION_TYPE
    2240      2728085 :       || VOID_TYPE_P (type)
    2241      2728003 :       || TREE_CODE (type) == ERROR_MARK)
    2242           82 :     return size_one_node;
    2243      2728003 :   else if (!COMPLETE_TYPE_P (type))
    2244           19 :     return size_zero_node;
    2245              :   else
    2246      2727984 :     return cxx_sizeof_or_alignof_type (input_location, type,
    2247      2727984 :                                        SIZEOF_EXPR, false, false);
    2248              : }
    2249              : 
    2250              : /* Process a sizeof expression where the operand is an expression.  */
    2251              : 
    2252              : static tree
    2253      1212885 : cxx_sizeof_expr (location_t loc, tree e, tsubst_flags_t complain)
    2254              : {
    2255      1212885 :   if (e == error_mark_node)
    2256              :     return error_mark_node;
    2257              : 
    2258      1212151 :   if (instantiation_dependent_uneval_expression_p (e))
    2259              :     {
    2260       344363 :       e = build_min (SIZEOF_EXPR, size_type_node, e);
    2261       344363 :       TREE_SIDE_EFFECTS (e) = 0;
    2262       344363 :       TREE_READONLY (e) = 1;
    2263       344363 :       SET_EXPR_LOCATION (e, loc);
    2264              : 
    2265       344363 :       return e;
    2266              :     }
    2267              : 
    2268       867788 :   location_t e_loc = cp_expr_loc_or_loc (e, loc);
    2269       867788 :   STRIP_ANY_LOCATION_WRAPPER (e);
    2270              : 
    2271       867788 :   if (TREE_CODE (e) == PARM_DECL
    2272        25343 :       && DECL_ARRAY_PARAMETER_P (e)
    2273       868165 :       && (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       867788 :   e = mark_type_use (e);
    2283              : 
    2284       867788 :   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       867776 :   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       867743 :   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       867743 :     e = TREE_TYPE (e);
    2312              : 
    2313       867761 :   return cxx_sizeof_or_alignof_type (loc, e, SIZEOF_EXPR, false,
    2314       867761 :                                      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       100321 : cxx_alignof_expr (location_t loc, tree e, bool std_alignof,
    2325              :                   tsubst_flags_t complain)
    2326              : {
    2327       100321 :   tree t;
    2328              : 
    2329       100321 :   if (e == error_mark_node)
    2330              :     return error_mark_node;
    2331              : 
    2332       100313 :   if (processing_template_decl)
    2333              :     {
    2334        18608 :       e = build_min (ALIGNOF_EXPR, size_type_node, e);
    2335        18608 :       TREE_SIDE_EFFECTS (e) = 0;
    2336        18608 :       TREE_READONLY (e) = 1;
    2337        18608 :       SET_EXPR_LOCATION (e, loc);
    2338        18608 :       ALIGNOF_EXPR_STD_P (e) = std_alignof;
    2339              : 
    2340        18608 :       return e;
    2341              :     }
    2342              : 
    2343        81705 :   location_t e_loc = cp_expr_loc_or_loc (e, loc);
    2344        81705 :   STRIP_ANY_LOCATION_WRAPPER (e);
    2345              : 
    2346        81705 :   e = mark_type_use (e);
    2347              : 
    2348        81705 :   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        81705 :   else if (VAR_P (e))
    2356        12270 :     t = size_int (DECL_ALIGN_UNIT (e));
    2357        69435 :   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        69429 :   else if (TREE_CODE (e) == COMPONENT_REF
    2367        69429 :            && TREE_CODE (TREE_OPERAND (e, 1)) == FIELD_DECL)
    2368        37792 :     t = size_int (DECL_ALIGN_UNIT (TREE_OPERAND (e, 1)));
    2369        31637 :   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        31631 :   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        31631 :     return cxx_sizeof_or_alignof_type (loc, TREE_TYPE (e),
    2391              :                                        ALIGNOF_EXPR, std_alignof,
    2392        31631 :                                        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      1313206 : cxx_sizeof_or_alignof_expr (location_t loc, tree e, enum tree_code op,
    2402              :                             bool std_alignof, bool complain)
    2403              : {
    2404      1313206 :   gcc_assert (op == SIZEOF_EXPR || op == ALIGNOF_EXPR);
    2405      1313206 :   if (op == SIZEOF_EXPR)
    2406      1770861 :     return cxx_sizeof_expr (loc, e, complain? tf_warning_or_error : tf_none);
    2407              :   else
    2408       100348 :     return cxx_alignof_expr (loc, e, std_alignof,
    2409       100321 :                              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       268177 : cxx_alignas_expr (tree e)
    2421              : {
    2422       268177 :   if (e == NULL_TREE || e == error_mark_node
    2423       536354 :       || (!TYPE_P (e) && !require_potential_rvalue_constant_expression (e)))
    2424            0 :     return e;
    2425              : 
    2426       268177 :   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       140904 :     return cxx_sizeof_or_alignof_type (input_location,
    2434              :                                        e, ALIGNOF_EXPR,
    2435              :                                        /*std_alignof=*/true,
    2436       140904 :                                        /*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       127273 :   if (value_dependent_expression_p (e))
    2443              :     /* Leave value-dependent expression alone for now. */
    2444              :     return e;
    2445              : 
    2446        65614 :   e = instantiate_non_dependent_expr (e);
    2447        65614 :   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        65614 :   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        65596 :   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   1451650700 : invalid_nonstatic_memfn_p (location_t loc, tree expr, tsubst_flags_t complain)
    2482              : {
    2483   1451650700 :   if (expr == NULL_TREE)
    2484              :     return false;
    2485              :   /* Don't enforce this in MS mode.  */
    2486   1451649260 :   if (flag_ms_extensions)
    2487              :     return false;
    2488   1451641199 :   if (is_overloaded_fn (expr) && !really_overloaded_fn (expr))
    2489    115682656 :     expr = get_first_fn (expr);
    2490   1451641199 :   if (TREE_TYPE (expr)
    2491   1451641199 :       && 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   3511661485 : is_bitfield_expr_with_lowered_type (const_tree exp)
    2517              : {
    2518   4781092921 :   switch (TREE_CODE (exp))
    2519              :     {
    2520      8473172 :     case COND_EXPR:
    2521     16946344 :       if (!is_bitfield_expr_with_lowered_type (TREE_OPERAND (exp, 1)
    2522      8473146 :                                                ? 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       880550 :     case COMPOUND_EXPR:
    2528       880550 :       return is_bitfield_expr_with_lowered_type (TREE_OPERAND (exp, 1));
    2529              : 
    2530    403962441 :     case MODIFY_EXPR:
    2531    403962441 :     case SAVE_EXPR:
    2532    403962441 :     case UNARY_PLUS_EXPR:
    2533    403962441 :     case PREDECREMENT_EXPR:
    2534    403962441 :     case PREINCREMENT_EXPR:
    2535    403962441 :     case POSTDECREMENT_EXPR:
    2536    403962441 :     case POSTINCREMENT_EXPR:
    2537    403962441 :     case NEGATE_EXPR:
    2538    403962441 :     case NON_LVALUE_EXPR:
    2539    403962441 :     case BIT_NOT_EXPR:
    2540    403962441 :     case CLEANUP_POINT_EXPR:
    2541    403962441 :       return is_bitfield_expr_with_lowered_type (TREE_OPERAND (exp, 0));
    2542              : 
    2543    247240408 :     case COMPONENT_REF:
    2544    247240408 :       {
    2545    247240408 :         tree field;
    2546              : 
    2547    247240408 :         field = TREE_OPERAND (exp, 1);
    2548    247240408 :         if (TREE_CODE (field) != FIELD_DECL || !DECL_BIT_FIELD_TYPE (field))
    2549              :           return NULL_TREE;
    2550     17285843 :         if (same_type_ignoring_top_level_qualifiers_p
    2551     17285843 :             (TREE_TYPE (exp), DECL_BIT_FIELD_TYPE (field)))
    2552              :           return NULL_TREE;
    2553     17118023 :         return DECL_BIT_FIELD_TYPE (field);
    2554              :       }
    2555              : 
    2556    659024914 :     case VAR_DECL:
    2557    659024914 :       if (DECL_HAS_VALUE_EXPR_P (exp))
    2558      1501638 :         return is_bitfield_expr_with_lowered_type (DECL_VALUE_EXPR
    2559      1501638 :                                                    (const_cast<tree> (exp)));
    2560              :       return NULL_TREE;
    2561              : 
    2562    870041038 :     case VIEW_CONVERT_EXPR:
    2563    870041038 :       if (location_wrapper_p (exp))
    2564    863086666 :         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   1683797599 : unlowered_expr_type (const_tree exp)
    2579              : {
    2580   1683797599 :   tree type;
    2581   1683797599 :   tree etype = TREE_TYPE (exp);
    2582              : 
    2583   1683797599 :   type = is_bitfield_expr_with_lowered_type (exp);
    2584   1683797599 :   if (type)
    2585     13614406 :     type = cp_build_qualified_type (type, cp_type_quals (etype));
    2586              :   else
    2587              :     type = etype;
    2588              : 
    2589   1683797599 :   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   1151785064 : decay_conversion (tree exp,
    2606              :                   tsubst_flags_t complain,
    2607              :                   bool reject_builtin /* = true */)
    2608              : {
    2609   1151785064 :   tree type;
    2610   1151785064 :   enum tree_code code;
    2611   1151785064 :   location_t loc = cp_expr_loc_or_input_loc (exp);
    2612              : 
    2613   1151785064 :   type = TREE_TYPE (exp);
    2614   1151785064 :   if (type == error_mark_node)
    2615              :     return error_mark_node;
    2616              : 
    2617   1151784854 :   exp = resolve_nondeduced_context_or_error (exp, complain);
    2618              : 
    2619   1151784854 :   code = TREE_CODE (type);
    2620              : 
    2621   1151784854 :   if (error_operand_p (exp))
    2622           90 :     return error_mark_node;
    2623              : 
    2624   1151784764 :   if (NULLPTR_TYPE_P (type) && !TREE_SIDE_EFFECTS (exp))
    2625              :     {
    2626      1694679 :       mark_rvalue_use (exp, loc, reject_builtin);
    2627      1694679 :       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   1150090085 :   if (code == VOID_TYPE)
    2633              :     {
    2634         5762 :       if (complain & tf_error)
    2635            3 :         error_at (loc, "void value not ignored as it ought to be");
    2636         5762 :       return error_mark_node;
    2637              :     }
    2638   1150084323 :   if (invalid_nonstatic_memfn_p (loc, exp, complain))
    2639            6 :     return error_mark_node;
    2640   1150084317 :   if (code == FUNCTION_TYPE || is_overloaded_fn (exp))
    2641              :     {
    2642    121266805 :       exp = mark_lvalue_use (exp);
    2643    121266805 :       if (reject_builtin && reject_gcc_builtin (exp, loc))
    2644          109 :         return error_mark_node;
    2645    121266696 :       return cp_build_addr_expr (exp, complain);
    2646              :     }
    2647   1028817512 :   if (code == ARRAY_TYPE)
    2648              :     {
    2649      6120276 :       tree adr;
    2650      6120276 :       tree ptrtype;
    2651              : 
    2652      6120276 :       exp = mark_lvalue_use (exp);
    2653              : 
    2654      6120276 :       if (INDIRECT_REF_P (exp))
    2655       159800 :         return build_nop (build_pointer_type (TREE_TYPE (type)),
    2656       319600 :                           TREE_OPERAND (exp, 0));
    2657              : 
    2658      5960476 :       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      5960473 :       if (!obvalue_p (exp)
    2668      5960473 :           && ! (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      5960473 :       ptrtype = build_pointer_type (TREE_TYPE (type));
    2676              : 
    2677      5960473 :       if (VAR_P (exp))
    2678              :         {
    2679       551981 :           if (!cxx_mark_addressable (exp))
    2680            0 :             return error_mark_node;
    2681       551981 :           adr = build_nop (ptrtype, build_address (exp));
    2682       551981 :           return adr;
    2683              :         }
    2684              :       /* This way is better for a COMPONENT_REF since it can
    2685              :          simplify the offset for a component.  */
    2686      5408492 :       adr = cp_build_addr_expr (exp, complain);
    2687      5408492 :       return cp_convert (ptrtype, adr, complain);
    2688              :     }
    2689              : 
    2690              :   /* Otherwise, it's the lvalue-to-rvalue conversion.  */
    2691   1022697236 :   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   1022697236 :   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   1022697236 :   type = TREE_TYPE (exp);
    2709   1022697236 :   if (!CLASS_TYPE_P (type) && cv_qualified_p (type))
    2710    319772173 :     exp = build_nop (cv_unqualified (type), exp);
    2711              : 
    2712   1022697236 :   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    303980958 : cp_default_conversion (tree exp, tsubst_flags_t complain)
    2733              : {
    2734              :   /* Check for target-specific promotions.  */
    2735    303980958 :   tree promoted_type = targetm.promoted_type (TREE_TYPE (exp));
    2736    303980958 :   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    303980958 :   else if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (exp)))
    2742    209761797 :     exp = cp_perform_integral_promotions (exp, complain);
    2743              :   /* Perform the other conversions.  */
    2744    303980958 :   exp = decay_conversion (exp, complain);
    2745              : 
    2746    303980958 :   return exp;
    2747              : }
    2748              : 
    2749              : /* C version.  */
    2750              : 
    2751              : tree
    2752     40699325 : default_conversion (tree exp)
    2753              : {
    2754     40699325 :   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    215494254 : cp_perform_integral_promotions (tree expr, tsubst_flags_t complain)
    2763              : {
    2764    215494254 :   tree type;
    2765    215494254 :   tree promoted_type;
    2766              : 
    2767    215494254 :   expr = mark_rvalue_use (expr);
    2768    215494254 :   if (error_operand_p (expr))
    2769            6 :     return error_mark_node;
    2770              : 
    2771    215494248 :   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    215494248 :   tree bitfield_type = is_bitfield_expr_with_lowered_type (expr);
    2783    215494248 :   if (bitfield_type
    2784    215494248 :       && (TREE_CODE (bitfield_type) == ENUMERAL_TYPE
    2785       506761 :           || TYPE_PRECISION (type) > TYPE_PRECISION (integer_type_node)))
    2786              :     type = bitfield_type;
    2787              : 
    2788    215494248 :   gcc_assert (INTEGRAL_OR_ENUMERATION_TYPE_P (type));
    2789              :   /* Scoped enums don't promote.  */
    2790    215494248 :   if (SCOPED_ENUM_P (type))
    2791              :     return expr;
    2792    215073398 :   promoted_type = type_promotes_to (type);
    2793    215073398 :   if (type != promoted_type)
    2794     64345359 :     expr = cp_convert (promoted_type, expr, complain);
    2795    150728039 :   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      1487859 : perform_integral_promotions (tree expr)
    2805              : {
    2806      1487859 :   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      3653570 : string_conv_p (const_tree totype, const_tree exp, int warn)
    2814              : {
    2815      3653570 :   tree t;
    2816              : 
    2817      3653570 :   if (!TYPE_PTR_P (totype))
    2818              :     return 0;
    2819              : 
    2820      3653099 :   t = TREE_TYPE (totype);
    2821      3653099 :   if (!same_type_p (t, char_type_node)
    2822      3509604 :       && !same_type_p (t, char8_type_node)
    2823      3451492 :       && !same_type_p (t, char16_type_node)
    2824      3404420 :       && !same_type_p (t, char32_type_node)
    2825      7010448 :       && !same_type_p (t, wchar_type_node))
    2826              :     return 0;
    2827              : 
    2828       332682 :   location_t loc = EXPR_LOC_OR_LOC (exp, input_location);
    2829              : 
    2830       332682 :   STRIP_ANY_LOCATION_WRAPPER (exp);
    2831              : 
    2832       332682 :   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       332574 :       t = build_pointer_type (cp_build_qualified_type (t, TYPE_QUAL_CONST));
    2842       332574 :       if (!same_type_p (TREE_TYPE (exp), t))
    2843              :         return 0;
    2844        13895 :       STRIP_NOPS (exp);
    2845        13895 :       if (TREE_CODE (exp) != ADDR_EXPR
    2846        13895 :           || 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        75698 : rationalize_conditional_expr (enum tree_code code, tree t,
    2874              :                               tsubst_flags_t complain)
    2875              : {
    2876        75698 :   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        75698 :   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        75698 :   tree op1 = TREE_OPERAND (t, 1);
    2905        75698 :   if (TREE_CODE (op1) != THROW_EXPR)
    2906        75695 :     op1 = cp_build_unary_op (code, op1, false, complain);
    2907        75698 :   tree op2 = TREE_OPERAND (t, 2);
    2908        75698 :   if (TREE_CODE (op2) != THROW_EXPR)
    2909        75692 :     op2 = cp_build_unary_op (code, op2, false, complain);
    2910              : 
    2911        75698 :   return
    2912        75698 :     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      1412747 : lookup_anon_field (tree, tree type)
    2922              : {
    2923      1412747 :   tree field;
    2924              : 
    2925      1412747 :   type = TYPE_MAIN_VARIANT (type);
    2926      1412747 :   field = ANON_AGGR_TYPE_FIELD (type);
    2927      1412747 :   gcc_assert (field);
    2928      1412747 :   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    116508541 : build_class_member_access_expr (cp_expr object, tree member,
    2945              :                                 tree access_path, bool preserve_reference,
    2946              :                                 tsubst_flags_t complain)
    2947              : {
    2948    116508541 :   tree object_type;
    2949    116508541 :   tree member_scope;
    2950    116508541 :   tree result = NULL_TREE;
    2951    116508541 :   tree using_decl = NULL_TREE;
    2952              : 
    2953    116508541 :   if (error_operand_p (object) || error_operand_p (member))
    2954           58 :     return error_mark_node;
    2955              : 
    2956    116508483 :   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    116508483 :   object_type = TREE_TYPE (object);
    2963    116508483 :   if (!currently_open_class (object_type)
    2964    116508483 :       && !complete_type_or_maybe_complain (object_type, object, complain))
    2965            0 :     return error_mark_node;
    2966    116508483 :   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    116508483 :   if (DECL_P (member))
    2986              :     {
    2987     49493809 :       member_scope = DECL_CLASS_CONTEXT (member);
    2988     49493809 :       if (!mark_used (member, complain) && !(complain & tf_error))
    2989            0 :         return error_mark_node;
    2990              : 
    2991     49493809 :       if (TREE_UNAVAILABLE (member))
    2992           30 :         error_unavailable_use (member, NULL_TREE);
    2993     49493779 :       else if (TREE_DEPRECATED (member))
    2994           30 :         warn_deprecated_use (member, NULL_TREE);
    2995              :     }
    2996              :   else
    2997     67014674 :     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    117924826 :   while ((ANON_AGGR_TYPE_P (member_scope) || UNSCOPED_ENUM_P (member_scope))
    3002    119341652 :          && !same_type_ignoring_top_level_qualifiers_p (member_scope,
    3003              :                                                         object_type))
    3004      1416343 :     member_scope = TYPE_CONTEXT (member_scope);
    3005    116508483 :   if (!member_scope || !DERIVED_FROM_P (member_scope, object_type))
    3006              :     {
    3007           11 :       if (complain & tf_error)
    3008              :         {
    3009           11 :           if (TREE_CODE (member) == FIELD_DECL)
    3010            2 :             error ("invalid use of non-static data member %qE", member);
    3011              :           else
    3012            9 :             error ("%qD is not a member of %qT", member, object_type);
    3013              :         }
    3014           11 :       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    116508472 :   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    116508472 :   if (VAR_P (member))
    3032              :     {
    3033              :       /* A static data member.  */
    3034        72431 :       result = member;
    3035        72431 :       mark_exp_read (object);
    3036              : 
    3037        72431 :       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        72431 :       if (TREE_SIDE_EFFECTS (object))
    3044         2558 :         result = build2 (COMPOUND_EXPR, TREE_TYPE (result), object, result);
    3045              :     }
    3046    116436041 :   else if (TREE_CODE (member) == FIELD_DECL)
    3047              :     {
    3048              :       /* A non-static data member.  */
    3049     49421163 :       bool null_object_p;
    3050     49421163 :       int type_quals;
    3051     49421163 :       tree member_type;
    3052              : 
    3053     49421163 :       if (INDIRECT_REF_P (object))
    3054     38504579 :         null_object_p =
    3055     38504579 :           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     49421163 :       if (!same_type_p (TYPE_MAIN_VARIANT (object_type),
    3061              :                         TYPE_MAIN_VARIANT (member_scope)))
    3062              :         {
    3063      1971254 :           tree binfo;
    3064      1971254 :           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      1971254 :           if (!cp_unevaluated_operand
    3070      1970791 :               && !dependent_type_p (object_type)
    3071      3663001 :               && !complete_type_or_maybe_complain (object_type, object,
    3072              :                                                    complain))
    3073           13 :             return error_mark_node;
    3074              : 
    3075      2667808 :           binfo = lookup_base (access_path ? access_path : object_type,
    3076              :                                member_scope, ba_unique, &kind, complain);
    3077      1971251 :           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      1971247 :           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      1971241 :           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      1971241 :           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     98842300 :       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     50834241 :           && (!same_type_ignoring_top_level_qualifiers_p
    3113      1413091 :               (TREE_TYPE (object), DECL_CONTEXT (member))))
    3114              :         {
    3115      1412614 :           tree anonymous_union;
    3116              : 
    3117      1412614 :           anonymous_union = lookup_anon_field (TREE_TYPE (object),
    3118      1412614 :                                                DECL_CONTEXT (member));
    3119      1412614 :           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     49421150 :       type_quals = TYPE_UNQUALIFIED;
    3128     49421150 :       member_type = TREE_TYPE (member);
    3129     49421150 :       if (!TYPE_REF_P (member_type))
    3130              :         {
    3131     48630464 :           type_quals = (cp_type_quals (member_type)
    3132     48630464 :                         | 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     48630464 :           if (DECL_MUTABLE_P (member))
    3138       317576 :             type_quals &= ~TYPE_QUAL_CONST;
    3139     48630464 :           member_type = cp_build_qualified_type (member_type, type_quals);
    3140              :         }
    3141              : 
    3142     49421150 :       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     49421150 :       if (type_quals & TYPE_QUAL_CONST)
    3149     15843099 :         TREE_READONLY (result) = 1;
    3150     49421150 :       if (type_quals & TYPE_QUAL_VOLATILE)
    3151       181021 :         TREE_THIS_VOLATILE (result) = 1;
    3152              :     }
    3153     67014878 :   else if (BASELINK_P (member))
    3154              :     {
    3155              :       /* The member is a (possibly overloaded) member function.  */
    3156     67014665 :       tree functions;
    3157     67014665 :       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     67014665 :       functions = BASELINK_FUNCTIONS (member);
    3163     67014665 :       if (TREE_CODE (functions) == OVERLOAD && OVL_SINGLE_P (functions))
    3164     67014665 :         functions = OVL_FIRST (functions);
    3165     67014665 :       if (TREE_CODE (functions) == FUNCTION_DECL
    3166     67014665 :           && DECL_STATIC_FUNCTION_P (functions))
    3167       597685 :         type = TREE_TYPE (functions);
    3168              :       else
    3169     66416980 :         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     67014665 :       result = build3_loc (input_location, COMPONENT_REF, type, object, member,
    3173              :                            NULL_TREE);
    3174              :     }
    3175          213 :   else if (TREE_CODE (member) == CONST_DECL)
    3176              :     {
    3177              :       /* The member is an enumerator.  */
    3178          201 :       result = member;
    3179              :       /* If OBJECT has side-effects, they are supposed to occur.  */
    3180          201 :       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    116508447 :   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    109909356 :     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       209526 : lookup_destructor (tree object, tree scope, tree dtor_name,
    3211              :                    tsubst_flags_t complain)
    3212              : {
    3213       209526 :   tree object_type = TREE_TYPE (object);
    3214       209526 :   tree dtor_type = TREE_OPERAND (dtor_name, 0);
    3215       209526 :   tree expr;
    3216              : 
    3217              :   /* We've already complained about this destructor.  */
    3218       209526 :   if (dtor_type == error_mark_node)
    3219              :     return error_mark_node;
    3220              : 
    3221       209520 :   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       209517 :   if (is_auto (dtor_type))
    3229              :     dtor_type = object_type;
    3230       209514 :   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       209491 :   else if (!DERIVED_FROM_P (dtor_type, TYPE_MAIN_VARIANT (object_type)))
    3246              :     {
    3247            7 :       if (complain & tf_error)
    3248            7 :         error ("the type being destroyed is %qT, but the destructor "
    3249            7 :                "refers to %qT", TYPE_MAIN_VARIANT (object_type), dtor_type);
    3250            7 :       return error_mark_node;
    3251              :     }
    3252       209507 :   expr = lookup_member (dtor_type, complete_dtor_identifier,
    3253              :                         /*protect=*/1, /*want_type=*/false,
    3254              :                         tf_warning_or_error);
    3255       209507 :   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       209501 :   expr = (adjust_result_of_qualified_name_lookup
    3262       209501 :           (expr, dtor_type, object_type));
    3263       209501 :   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       209358 :     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       250599 : 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       250599 :   if (TREE_CODE (decl) != TEMPLATE_DECL
    3296       250599 :       && TREE_CODE (decl) != TEMPLATE_ID_EXPR)
    3297              :     {
    3298        59301 :       if (VAR_P (decl))
    3299              :         {
    3300         9727 :           if (DECL_USE_TEMPLATE (decl)
    3301         9727 :               && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (decl)))
    3302              :             ;
    3303              :           else
    3304            0 :             permerror (input_location, "%qD is not a template", decl);
    3305              :         }
    3306        49574 :       else if (!is_overloaded_fn (decl))
    3307            0 :         permerror (input_location, "%qD is not a template", decl);
    3308              :       else
    3309              :         {
    3310        49574 :           bool found = false;
    3311              : 
    3312        99148 :           for (lkp_iterator iter (MAYBE_BASELINK_FUNCTIONS (decl));
    3313        99150 :                !found && iter; ++iter)
    3314              :             {
    3315        49576 :               tree fn = *iter;
    3316        49576 :               if (TREE_CODE (fn) == TEMPLATE_DECL
    3317        49180 :                   || TREE_CODE (fn) == TEMPLATE_ID_EXPR
    3318        49590 :                   || (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        49574 :           if (!found)
    3324           12 :             permerror (input_location, "%qD is not a template", decl);
    3325              :         }
    3326              :     }
    3327       250599 : }
    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     94402137 : access_failure_info::get_any_accessor (bool const_p) const
    3348              : {
    3349     94402137 :   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     94402067 : access_failure_info::maybe_suggest_accessor (bool const_p) const
    3384              : {
    3385     94402067 :   tree accessor = get_any_accessor (const_p);
    3386     94402067 :   if (accessor == NULL_TREE)
    3387     94401969 :     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          315 : complain_about_unrecognized_member (tree access_path, tree name,
    3401              :                                     tree object_type)
    3402              : {
    3403              :   /* Attempt to provide a hint about misspelled names.  */
    3404          315 :   tree guessed_id = lookup_member_fuzzy (access_path, name,
    3405              :                                          /*want_type=*/false);
    3406          315 :   if (guessed_id == NULL_TREE)
    3407              :     {
    3408              :       /* No hint.  */
    3409          208 :       error ("%q#T has no member named %qE",
    3410          208 :              TREE_CODE (access_path) == TREE_BINFO
    3411            6 :              ? TREE_TYPE (access_path) : object_type, name);
    3412          208 :       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    189288734 : 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    189288734 :   tree expr;
    3483    189288734 :   tree object_type;
    3484    189288734 :   tree member;
    3485    189288734 :   tree access_path = NULL_TREE;
    3486    189288734 :   tree orig_object = object;
    3487    189288734 :   tree orig_name = name;
    3488              : 
    3489    189288734 :   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    189288238 :   if (!objc_is_public (object, name))
    3494            0 :     return error_mark_node;
    3495              : 
    3496    189288238 :   object_type = TREE_TYPE (object);
    3497              : 
    3498    189288238 :   if (processing_template_decl)
    3499              :     {
    3500    157135690 :       if (/* If OBJECT is dependent, so is OBJECT.NAME.  */
    3501    157135690 :           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     74050988 :           || (TREE_CODE (name) == TEMPLATE_ID_EXPR
    3505       578855 :               && dependent_template_id_p (TREE_OPERAND (name, 0),
    3506       578855 :                                           TREE_OPERAND (name, 1)))
    3507              :           /* If NAME is "T::X" where "T" is dependent, then the
    3508              :              expression is dependent.  */
    3509     73766037 :           || (TREE_CODE (name) == SCOPE_REF
    3510       104011 :               && TYPE_P (TREE_OPERAND (name, 0))
    3511       104011 :               && 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     73662246 :           || (TREE_CODE (name) == IDENTIFIER_NODE
    3515     73037035 :               && IDENTIFIER_CONV_OP_P (name)
    3516           57 :               && dependent_type_p (TREE_TYPE (name)))
    3517              :           /* This is OBJECT.[:R:], which is dependent.  */
    3518     73662195 :           || dependent_splice_p (name)
    3519              :           /* This is OBJECT.[:T::R:], which is dependent.  */
    3520    230797682 :           || (TREE_CODE (name) == SCOPE_REF
    3521          220 :               && dependent_splice_p (TREE_OPERAND (name, 1))))
    3522              :         {
    3523     97924912 :         dependent:
    3524     97924912 :           expr = build_min_nt_loc (UNKNOWN_LOCATION, COMPONENT_REF,
    3525              :                                    orig_object, orig_name, NULL_TREE);
    3526     97924912 :           COMPONENT_REF_SPLICE_P (expr) = splice_p;
    3527     97924912 :           return expr;
    3528              :         }
    3529              :     }
    3530     32152548 :   else if (c_dialect_objc ()
    3531    105814540 :            && identifier_p (name)
    3532     32152548 :            && (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    105814540 :   if (!currently_open_class (object_type)
    3540    105814540 :       && !complete_type_or_maybe_complain (object_type, object, complain))
    3541           68 :     return error_mark_node;
    3542    105814472 :   if (!CLASS_TYPE_P (object_type))
    3543              :     {
    3544       260485 :       if (complain & tf_error)
    3545              :         {
    3546          126 :           if (INDIRECT_TYPE_P (object_type)
    3547          126 :               && CLASS_TYPE_P (TREE_TYPE (object_type)))
    3548           22 :             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          104 :             error ("request for member %qD in %qE, which is of non-class "
    3553              :                    "type %qT", name, object.get_value (), object_type);
    3554              :         }
    3555       260485 :       return error_mark_node;
    3556              :     }
    3557              : 
    3558    105553987 :   if (BASELINK_P (name))
    3559              :     /* A member function that has already been looked up.  */
    3560              :     member = name;
    3561     94658916 :   else if (TREE_CODE (name) == TREE_BINFO)
    3562              :     {
    3563              :       /* Splicing a base class subobject.  We can only get here via
    3564              :          e1.[:e2:].  */
    3565           46 :       expr = build_base_path (PLUS_EXPR, object, name, /*nonnull=*/true,
    3566              :                               complain);
    3567           46 :       if (expr == error_mark_node && (complain & tf_error))
    3568            2 :         error_not_base_type (BINFO_TYPE (name), object_type);
    3569           46 :       return expr;
    3570              :     }
    3571              :   else
    3572              :     {
    3573     94658870 :       bool is_template_id = false;
    3574     94658870 :       tree template_args = NULL_TREE;
    3575     94658870 :       tree scope = NULL_TREE;
    3576              : 
    3577     94658870 :       access_path = object_type;
    3578              : 
    3579     94658870 :       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         1774 :           scope = TREE_OPERAND (name, 0);
    3585         1774 :           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         1774 :           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     94657096 :       else if (splice_p && valid_splice_for_member_access_p (name))
    3598              :         {
    3599          666 :           scope = context_for_name_lookup (OVL_FIRST (name));
    3600          666 :           if (!CLASS_TYPE_P (scope))
    3601              :             {
    3602            5 :               if (complain & tf_error)
    3603              :                 {
    3604            5 :                   auto_diagnostic_group d;
    3605            5 :                   error ("%q#D is not a member of %qT", name, object_type);
    3606           10 :                   inform (DECL_SOURCE_LOCATION (OVL_FIRST (name)), "declared here");
    3607            5 :                 }
    3608            5 :               return error_mark_node;
    3609              :             }
    3610              :         }
    3611              : 
    3612     94658865 :       if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
    3613              :         {
    3614       430391 :           is_template_id = true;
    3615       430391 :           template_args = TREE_OPERAND (name, 1);
    3616       430391 :           name = TREE_OPERAND (name, 0);
    3617              : 
    3618       430391 :           if (splice_p
    3619       431084 :               && (DECL_FUNCTION_TEMPLATE_P (OVL_FIRST (name))
    3620           69 :                   || variable_template_p (name)))
    3621          231 :             scope = DECL_CONTEXT (OVL_FIRST (name));
    3622       840184 :           else if (!identifier_p (name))
    3623       410074 :             name = OVL_NAME (name);
    3624              :         }
    3625              : 
    3626     94658865 :       if (scope)
    3627              :         {
    3628         2666 :           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         2654 :           gcc_assert (CLASS_TYPE_P (scope));
    3659         2654 :           gcc_assert (identifier_p (name)
    3660              :                       || TREE_CODE (name) == BIT_NOT_EXPR
    3661              :                       || (splice_p && valid_splice_for_member_access_p (name)));
    3662              : 
    3663         2654 :           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         7953 :           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         2651 :               if (splice_p)
    3681              :                 return ba_unique;
    3682         1759 :               if (identifier_p (name))
    3683              :                 {
    3684         1622 :                   tree m = lookup_member (scope, name, /*protect=*/0,
    3685              :                                           /*want_type=*/false, tf_none);
    3686         1622 :                   if (!m || shared_member_p (m))
    3687           32 :                     return ba_any;
    3688              :                 }
    3689              :               return ba_check;
    3690         2651 :             } ();
    3691              : 
    3692              :           /* Find the base of OBJECT_TYPE corresponding to SCOPE.  */
    3693         2651 :           access_path = lookup_base (object_type, scope, ba, NULL, complain);
    3694         2651 :           if (access_path == error_mark_node)
    3695              :             return error_mark_node;
    3696         2630 :           if (!access_path)
    3697              :             {
    3698           24 :               if (any_dependent_bases_p (object_type))
    3699            6 :                 goto dependent;
    3700           18 :               if (complain & tf_error)
    3701           18 :                 error ("%qT is not a base of %qT", scope, object_type);
    3702           18 :               return error_mark_node;
    3703              :             }
    3704              :         }
    3705              : 
    3706     94658805 :       if (TREE_CODE (name) == BIT_NOT_EXPR)
    3707              :         {
    3708       255867 :           if (dependent_type_p (object_type))
    3709              :             /* The destructor isn't declared yet.  */
    3710        46356 :             goto dependent;
    3711       209511 :           member = lookup_destructor (object, scope, name, complain);
    3712              :         }
    3713     94402938 :       else if (splice_p && valid_splice_for_member_access_p (name))
    3714              :         {
    3715         1303 :           member = name;
    3716          871 :           name = OVL_FIRST (name);
    3717          871 :           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          871 :           if (is_overloaded_fn (name))
    3722          707 :             member
    3723          707 :               = build_baselink (access_path, TYPE_BINFO (object_type), member,
    3724          707 :                                 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     94402067 :           {
    3731     94402067 :             auto_diagnostic_group d;
    3732     94402067 :             access_failure_info afi;
    3733     94402067 :             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     73331011 :               push_deferring_access_checks (dk_no_check);
    3741     94402067 :             member = lookup_member (access_path, name, /*protect=*/1,
    3742              :                                     /*want_type=*/false, complain,
    3743              :                                     &afi);
    3744     94402067 :             if (processing_template_decl)
    3745     73331011 :               pop_deferring_access_checks ();
    3746     94402067 :             afi.maybe_suggest_accessor (TYPE_READONLY (object_type));
    3747     94402067 :           }
    3748     94402067 :           if (member == NULL_TREE)
    3749              :             {
    3750      9040199 :               if (dependentish_scope_p (object_type))
    3751              :                 /* Try again at instantiation time.  */
    3752      9023913 :                 goto dependent;
    3753        16286 :               if (complain & tf_error)
    3754          315 :                 complain_about_unrecognized_member (access_path, name,
    3755              :                                                     object_type);
    3756        16286 :               return error_mark_node;
    3757              :             }
    3758     85361868 :           if (member == error_mark_node)
    3759              :             return error_mark_node;
    3760     85361823 :           if (DECL_P (member)
    3761     85361823 :               && 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     85361817 :           if (TREE_CODE (member) == USING_DECL && DECL_DEPENDENT_P (member))
    3766      5380933 :             goto dependent;
    3767              :         }
    3768              : 
    3769     80191266 :       if (is_template_id)
    3770              :         {
    3771       430283 :           tree templ = member;
    3772              : 
    3773       430283 :           if (BASELINK_P (templ))
    3774       430150 :             member = lookup_template_function (templ, template_args);
    3775          133 :           else if (variable_template_p (templ))
    3776          133 :             member = (lookup_and_finish_template_variable
    3777          133 :                       (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     91086337 :   if (TREE_UNAVAILABLE (member))
    3788           30 :     error_unavailable_use (member, NULL_TREE);
    3789     91086307 :   else if (TREE_DEPRECATED (member))
    3790           30 :     warn_deprecated_use (member, NULL_TREE);
    3791              : 
    3792     91086337 :   if (template_p)
    3793         9282 :     check_template_keyword (member);
    3794              : 
    3795     91086337 :   expr = build_class_member_access_expr (object, member, access_path,
    3796              :                                          /*preserve_reference=*/false,
    3797              :                                          complain);
    3798     91086337 :   if (processing_template_decl && expr != error_mark_node)
    3799              :     {
    3800     59210696 :       if (BASELINK_P (member))
    3801              :         {
    3802     44117485 :           if (TREE_CODE (orig_name) == SCOPE_REF)
    3803          172 :             BASELINK_QUALIFIED_P (member) = 1;
    3804              :           orig_name = member;
    3805              :         }
    3806     59210696 :       expr = build_min_non_dep (COMPONENT_REF, expr,
    3807              :                                 orig_object, orig_name,
    3808              :                                 NULL_TREE);
    3809    118421392 :       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       168502 : build_simple_component_ref (tree object, tree member)
    3820              : {
    3821       168502 :   tree type = cp_build_qualified_type (TREE_TYPE (member),
    3822       168502 :                                        cp_type_quals (TREE_TYPE (object)));
    3823       168502 :   return build3_loc (input_location,
    3824              :                      COMPONENT_REF, type,
    3825       168502 :                      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       168412 : build_ptrmemfunc_access_expr (tree ptrmem, tree member_name)
    3837              : {
    3838       168412 :   tree ptrmem_type;
    3839       168412 :   tree member;
    3840              : 
    3841       168412 :   if (TREE_CODE (ptrmem) == CONSTRUCTOR)
    3842              :     {
    3843          216 :       for (auto &e: CONSTRUCTOR_ELTS (ptrmem))
    3844           84 :         if (e.index && DECL_P (e.index) && DECL_NAME (e.index) == member_name)
    3845           66 :           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       168346 :   ptrmem_type = TREE_TYPE (ptrmem);
    3854       168346 :   gcc_assert (TYPE_PTRMEMFUNC_P (ptrmem_type));
    3855       252416 :   for (member = TYPE_FIELDS (ptrmem_type); member;
    3856        84070 :        member = DECL_CHAIN (member))
    3857       252416 :     if (DECL_NAME (member) == member_name)
    3858              :       break;
    3859       168346 :   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    136762656 : op_unqualified_lookup (tree_code code, bool is_assign)
    3867              : {
    3868    136762656 :   tree lookups = NULL_TREE;
    3869              : 
    3870    136762656 :   if (cxx_dialect >= cxx20 && !is_assign)
    3871              :     {
    3872    129179037 :       if (code == NE_EXPR)
    3873              :         {
    3874              :           /* != can get rewritten in terms of ==.  */
    3875      8320729 :           tree fnname = ovl_op_identifier (false, EQ_EXPR);
    3876      8320729 :           if (tree fns = lookup_name (fnname, LOOK_where::BLOCK_NAMESPACE))
    3877      8223537 :             lookups = tree_cons (fnname, fns, lookups);
    3878              :         }
    3879    120858308 :       else if (code == GT_EXPR || code == LE_EXPR
    3880    120858308 :                || code == LT_EXPR || code == GE_EXPR)
    3881              :         {
    3882              :           /* These can get rewritten in terms of <=>.  */
    3883     11214091 :           tree fnname = ovl_op_identifier (false, SPACESHIP_EXPR);
    3884     11214091 :           if (tree fns = lookup_name (fnname, LOOK_where::BLOCK_NAMESPACE))
    3885     10614949 :             lookups = tree_cons (fnname, fns, lookups);
    3886              :         }
    3887              :     }
    3888              : 
    3889    136762656 :   tree fnname = ovl_op_identifier (is_assign, code);
    3890    136762656 :   if (tree fns = lookup_name (fnname, LOOK_where::BLOCK_NAMESPACE))
    3891     74509439 :     lookups = tree_cons (fnname, fns, lookups);
    3892              : 
    3893    136762656 :   if (lookups)
    3894              :     return lookups;
    3895              :   else
    3896     62027529 :     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    142886922 : build_dependent_operator_type (tree lookups, tree_code code, bool is_assign)
    3905              : {
    3906    142886922 :   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      6124266 :     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    136762656 :   lookups = op_unqualified_lookup (code, is_assign);
    3916              : 
    3917    136762656 :   tree type = cxx_make_type (DEPENDENT_OPERATOR_TYPE);
    3918    136762656 :   DEPENDENT_OPERATOR_TYPE_SAVED_LOOKUPS (type) = lookups;
    3919    136762656 :   TREE_TYPE (lookups) = type;
    3920    136762656 :   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     49404337 : build_x_indirect_ref (location_t loc, tree expr, ref_operator errorstring,
    3932              :                       tree lookups, tsubst_flags_t complain)
    3933              : {
    3934     49404337 :   tree orig_expr = expr;
    3935     49404337 :   tree rval;
    3936     49404337 :   tree overload = NULL_TREE;
    3937              : 
    3938     49404337 :   if (processing_template_decl)
    3939              :     {
    3940              :       /* Retain the type if we know the operand is a pointer.  */
    3941     28786526 :       if (TREE_TYPE (expr) && INDIRECT_TYPE_P (TREE_TYPE (expr)))
    3942              :         {
    3943     14122108 :           if (expr == current_class_ptr
    3944     14122108 :               || (TREE_CODE (expr) == NOP_EXPR
    3945      9240637 :                   && TREE_OPERAND (expr, 0) == current_class_ptr
    3946      9231387 :                   && (same_type_ignoring_top_level_qualifiers_p
    3947      9231387 :                         (TREE_TYPE (expr), TREE_TYPE (current_class_ptr)))))
    3948      9231386 :             return current_class_ref;
    3949      4890722 :           return build_min (INDIRECT_REF, TREE_TYPE (TREE_TYPE (expr)), expr);
    3950              :         }
    3951     14664418 :       if (type_dependent_expression_p (expr))
    3952              :         {
    3953     14511229 :           expr = build_min_nt_loc (loc, INDIRECT_REF, expr);
    3954     14511229 :           TREE_TYPE (expr)
    3955     14511229 :             = build_dependent_operator_type (lookups, INDIRECT_REF, false);
    3956     14511229 :           return expr;
    3957              :         }
    3958              :     }
    3959              : 
    3960     20771000 :   rval = build_new_op (loc, INDIRECT_REF, LOOKUP_NORMAL, expr,
    3961              :                        NULL_TREE, NULL_TREE, lookups,
    3962              :                        &overload, complain);
    3963     20771000 :   if (!rval)
    3964            0 :     rval = cp_build_indirect_ref (loc, expr, errorstring, complain);
    3965              : 
    3966     20771000 :   if (processing_template_decl && rval != error_mark_node)
    3967              :     {
    3968       151356 :       if (overload != NULL_TREE)
    3969       151325 :         return (build_min_non_dep_op_overload
    3970       151325 :                 (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       641997 : cp_strict_aliasing_warning (location_t loc, tree type, tree expr)
    3983              : {
    3984       641997 :   if (processing_template_decl)
    3985              :     {
    3986        45509 :       tree e = expr;
    3987        45509 :       STRIP_NOPS (e);
    3988        45509 :       if (dependent_type_p (type) || type_dependent_expression_p (e))
    3989         7102 :         return false;
    3990              :     }
    3991       634895 :   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    353549866 : cp_build_indirect_ref_1 (location_t loc, tree ptr, ref_operator errorstring,
    3999              :                          tsubst_flags_t complain, bool do_fold)
    4000              : {
    4001    353549866 :   tree pointer, type;
    4002              : 
    4003              :   /* RO_NULL should only be used with the folding entry points below, not
    4004              :      cp_build_indirect_ref.  */
    4005    353549866 :   gcc_checking_assert (errorstring != RO_NULL || do_fold);
    4006              : 
    4007    353549866 :   if (ptr == current_class_ptr
    4008    353549866 :       || (TREE_CODE (ptr) == NOP_EXPR
    4009     37548569 :           && TREE_OPERAND (ptr, 0) == current_class_ptr
    4010     20021469 :           && (same_type_ignoring_top_level_qualifiers_p
    4011     20021469 :               (TREE_TYPE (ptr), TREE_TYPE (current_class_ptr)))))
    4012     21405572 :     return current_class_ref;
    4013              : 
    4014    332144294 :   pointer = (TYPE_REF_P (TREE_TYPE (ptr))
    4015    332144294 :              ? ptr : decay_conversion (ptr, complain));
    4016    332144294 :   if (pointer == error_mark_node)
    4017              :     return error_mark_node;
    4018              : 
    4019    332138471 :   type = TREE_TYPE (pointer);
    4020              : 
    4021    332138471 :   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    332137941 :       tree t = TREE_TYPE (type);
    4028              : 
    4029    313320184 :       if ((CONVERT_EXPR_P (ptr)
    4030    227035388 :            || TREE_CODE (ptr) == VIEW_CONVERT_EXPR)
    4031    420740106 :           && (!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     84019216 :           if (warn_strict_aliasing > 2
    4037     84561458 :               && cp_strict_aliasing_warning (EXPR_LOCATION (ptr),
    4038       542242 :                                              type, TREE_OPERAND (ptr, 0)))
    4039            6 :             suppress_warning (ptr, OPT_Wstrict_aliasing);
    4040              :         }
    4041              : 
    4042    332137941 :       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           47 :           if (complain & tf_error)
    4047           19 :             error_at (loc, "%qT is not a pointer-to-object type", type);
    4048           47 :           return error_mark_node;
    4049              :         }
    4050    321657486 :       else if (do_fold && TREE_CODE (pointer) == ADDR_EXPR
    4051    339391385 :                && 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      7253452 :         return TREE_OPERAND (pointer, 0);
    4057              :       else
    4058              :         {
    4059    324884442 :           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    324884442 :           TREE_READONLY (ref) = CP_TYPE_CONST_P (t);
    4065    324884442 :           TREE_THIS_VOLATILE (ref) = CP_TYPE_VOLATILE_P (t);
    4066    324884442 :           TREE_SIDE_EFFECTS (ref)
    4067    324884442 :             = (TREE_THIS_VOLATILE (ref) || TREE_SIDE_EFFECTS (pointer));
    4068    324884442 :           return ref;
    4069              :         }
    4070              :     }
    4071          530 :   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           40 :   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           25 :   else if (pointer != error_mark_node)
    4098           25 :     invalid_indirection_error (loc, type, errorstring);
    4099              : 
    4100          530 :   return error_mark_node;
    4101              : }
    4102              : 
    4103              : /* Entry point used by c-common, which expects folding.  */
    4104              : 
    4105              : tree
    4106        67927 : build_indirect_ref (location_t loc, tree ptr, ref_operator errorstring)
    4107              : {
    4108        67927 :   return cp_build_indirect_ref_1 (loc, ptr, errorstring,
    4109        67927 :                                   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    325269800 : cp_build_fold_indirect_ref (tree pointer)
    4117              : {
    4118    325269800 :   return cp_build_indirect_ref_1 (input_location, pointer, RO_NULL,
    4119    325269800 :                                   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     28212139 : cp_build_indirect_ref (location_t loc, tree ptr, ref_operator errorstring,
    4127              :                        tsubst_flags_t complain)
    4128              : {
    4129     28212139 :   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      5909918 : cp_build_array_ref (location_t loc, tree array, tree idx,
    4149              :                     tsubst_flags_t complain)
    4150              : {
    4151      5909918 :   tree ret;
    4152              : 
    4153      5909918 :   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      5909918 :   if (TREE_TYPE (array) == error_mark_node
    4161      5909918 :       || TREE_TYPE (idx) == error_mark_node)
    4162              :     return error_mark_node;
    4163              : 
    4164              :   /* 0[array] */
    4165      5909918 :   if (TREE_CODE (TREE_TYPE (idx)) == ARRAY_TYPE)
    4166              :     {
    4167           10 :       std::swap (array, idx);
    4168              : 
    4169           10 :       tree first = NULL_TREE;
    4170           10 :       if (flag_strong_eval_order == 2 && TREE_SIDE_EFFECTS (array))
    4171            9 :         idx = first = save_expr (idx);
    4172           10 :       ret = cp_build_array_ref (loc, array, idx, complain);
    4173              : 
    4174           10 :       if (first)
    4175            9 :         ret = build2 (COMPOUND_EXPR, TREE_TYPE (ret), first, ret);
    4176           10 :       return ret;
    4177              :     }
    4178              : 
    4179              :   /* If ARRAY is a COMPOUND_EXPR or COND_EXPR, move our reference
    4180              :      inside it.  */
    4181      5909908 :   switch (TREE_CODE (array))
    4182              :     {
    4183           28 :     case COMPOUND_EXPR:
    4184           28 :       {
    4185           28 :         tree value = cp_build_array_ref (loc, TREE_OPERAND (array, 1), idx,
    4186              :                                          complain);
    4187           28 :         ret = build2 (COMPOUND_EXPR, TREE_TYPE (value),
    4188           28 :                       TREE_OPERAND (array, 0), value);
    4189           28 :         SET_EXPR_LOCATION (ret, loc);
    4190           28 :         return ret;
    4191              :       }
    4192              : 
    4193           73 :     case COND_EXPR:
    4194           73 :       tree op0, op1, op2;
    4195           73 :       op0 = TREE_OPERAND (array, 0);
    4196           73 :       op1 = TREE_OPERAND (array, 1);
    4197           73 :       op2 = TREE_OPERAND (array, 2);
    4198           73 :       if (TREE_SIDE_EFFECTS (idx) || !tree_invariant_p (idx))
    4199              :         {
    4200              :           /* If idx could possibly have some SAVE_EXPRs, turning
    4201              :              (op0 ? op1 : op2)[idx] into
    4202              :              op0 ? op1[idx] : op2[idx] can lead into temporaries
    4203              :              initialized in one conditional path and uninitialized
    4204              :              uses of them in the other path.
    4205              :              And if idx is a really large expression, evaluating it
    4206              :              twice is also not optimal.
    4207              :              On the other side, op0 must be sequenced before evaluation
    4208              :              of op1 and op2 and for C++17 op0, op1 and op2 must be
    4209              :              sequenced before idx.
    4210              :              If idx is INTEGER_CST, we can just do the optimization
    4211              :              without any SAVE_EXPRs, if op1 and op2 are both ARRAY_TYPE
    4212              :              VAR_DECLs or COMPONENT_REFs thereof (so their address
    4213              :              is constant or relative to frame), optimize into
    4214              :              (SAVE_EXPR <op0>, SAVE_EXPR <idx>, SAVE_EXPR <op0>)
    4215              :              ? op1[SAVE_EXPR <idx>] : op2[SAVE_EXPR <idx>]
    4216              :              Otherwise avoid this optimization.  */
    4217           58 :           if (flag_strong_eval_order == 2)
    4218              :             {
    4219           39 :               if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE)
    4220              :                 {
    4221           30 :                   if (!address_invariant_p (op1) || !address_invariant_p (op2))
    4222              :                     {
    4223              :                       /* Force default conversion on array if
    4224              :                          we can't optimize this and array is ARRAY_TYPE
    4225              :                          COND_EXPR, we can't leave COND_EXPRs with
    4226              :                          ARRAY_TYPE in the IL.  */
    4227            8 :                       array = cp_default_conversion (array, complain);
    4228            8 :                       if (error_operand_p (array))
    4229            0 :                         return error_mark_node;
    4230              :                       break;
    4231              :                     }
    4232              :                 }
    4233           16 :               else if (!POINTER_TYPE_P (TREE_TYPE (array))
    4234            2 :                        || !tree_invariant_p (op1)
    4235           11 :                        || !tree_invariant_p (op2))
    4236              :                 break;
    4237              :             }
    4238           43 :           if (TREE_SIDE_EFFECTS (idx))
    4239              :             {
    4240           18 :               idx = save_expr (idx);
    4241           18 :               op0 = save_expr (op0);
    4242           18 :               warning_sentinel w (warn_unused_value);
    4243           18 :               tree tem = build_compound_expr (loc, op0, idx);
    4244           18 :               op0 = build_compound_expr (loc, tem, op0);
    4245           18 :             }
    4246              :         }
    4247           58 :       op1 = cp_build_array_ref (loc, op1, idx, complain);
    4248           58 :       op2 = cp_build_array_ref (loc, op2, idx, complain);
    4249           58 :       ret = build_conditional_expr (loc, op0, op1, op2, complain);
    4250           58 :       protected_set_expr_location (ret, loc);
    4251           58 :       return ret;
    4252              : 
    4253              :     default:
    4254              :       break;
    4255              :     }
    4256              : 
    4257      5909822 :   bool non_lvalue = convert_vector_to_array_for_subscript (loc, &array, idx);
    4258              : 
    4259      5909822 :   if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE)
    4260              :     {
    4261      1800196 :       tree rval, type;
    4262              : 
    4263      1800196 :       warn_array_subscript_with_type_char (loc, idx);
    4264              : 
    4265      1800196 :       if (!INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (idx)))
    4266              :         {
    4267            3 :           if (complain & tf_error)
    4268            3 :             error_at (loc, "array subscript is not an integer");
    4269            3 :           return error_mark_node;
    4270              :         }
    4271              : 
    4272              :       /* Apply integral promotions *after* noticing character types.
    4273              :          (It is unclear why we do these promotions -- the standard
    4274              :          does not say that we should.  In fact, the natural thing would
    4275              :          seem to be to convert IDX to ptrdiff_t; we're performing
    4276              :          pointer arithmetic.)  */
    4277      1800193 :       idx = cp_perform_integral_promotions (idx, complain);
    4278              : 
    4279      1800193 :       idx = maybe_fold_non_dependent_expr (idx, complain);
    4280              : 
    4281              :       /* An array that is indexed by a non-constant
    4282              :          cannot be stored in a register; we must be able to do
    4283              :          address arithmetic on its address.
    4284              :          Likewise an array of elements of variable size.  */
    4285      1800193 :       if (TREE_CODE (idx) != INTEGER_CST
    4286      1800193 :           || (COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (array)))
    4287       854876 :               && (TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))))
    4288              :                   != INTEGER_CST)))
    4289              :         {
    4290       946577 :           if (!cxx_mark_addressable (array, true))
    4291            0 :             return error_mark_node;
    4292              :         }
    4293              : 
    4294              :       /* An array that is indexed by a constant value which is not within
    4295              :          the array bounds cannot be stored in a register either; because we
    4296              :          would get a crash in store_bit_field/extract_bit_field when trying
    4297              :          to access a non-existent part of the register.  */
    4298      1800193 :       if (TREE_CODE (idx) == INTEGER_CST
    4299       854879 :           && TYPE_DOMAIN (TREE_TYPE (array))
    4300      2653683 :           && ! int_fits_type_p (idx, TYPE_DOMAIN (TREE_TYPE (array))))
    4301              :         {
    4302         3007 :           if (!cxx_mark_addressable (array))
    4303            0 :             return error_mark_node;
    4304              :         }
    4305              : 
    4306              :       /* Note in C++ it is valid to subscript a `register' array, since
    4307              :          it is valid to take the address of something with that
    4308              :          storage specification.  */
    4309      1800193 :       if (extra_warnings)
    4310              :         {
    4311        38852 :           tree foo = array;
    4312        59540 :           while (TREE_CODE (foo) == COMPONENT_REF)
    4313        20688 :             foo = TREE_OPERAND (foo, 0);
    4314            8 :           if (VAR_P (foo) && DECL_REGISTER (foo)
    4315        38852 :               && (complain & tf_warning))
    4316            0 :             warning_at (loc, OPT_Wextra,
    4317              :                         "subscripting array declared %<register%>");
    4318              :         }
    4319              : 
    4320      1800193 :       type = TREE_TYPE (TREE_TYPE (array));
    4321      1800193 :       rval = build4 (ARRAY_REF, type, array, idx, NULL_TREE, NULL_TREE);
    4322              :       /* Array ref is const/volatile if the array elements are
    4323              :          or if the array is..  */
    4324      5400579 :       TREE_READONLY (rval)
    4325      1800193 :         |= (CP_TYPE_CONST_P (type) | TREE_READONLY (array));
    4326      5400579 :       TREE_SIDE_EFFECTS (rval)
    4327      1800193 :         |= (CP_TYPE_VOLATILE_P (type) | TREE_SIDE_EFFECTS (array));
    4328      3600386 :       TREE_THIS_VOLATILE (rval)
    4329      1800193 :         |= (CP_TYPE_VOLATILE_P (type) | TREE_THIS_VOLATILE (array));
    4330      1800193 :       ret = require_complete_type (rval, complain);
    4331      1800193 :       protected_set_expr_location (ret, loc);
    4332      1800193 :       if (non_lvalue)
    4333        19994 :         ret = non_lvalue_loc (loc, ret);
    4334      1800193 :       return ret;
    4335              :     }
    4336              : 
    4337      4109626 :   {
    4338      4109626 :     tree ar = cp_default_conversion (array, complain);
    4339      4109626 :     tree ind = cp_default_conversion (idx, complain);
    4340      4109626 :     tree first = NULL_TREE;
    4341              : 
    4342      2638433 :     if (!processing_template_decl && flag_strong_eval_order == 2
    4343      6706473 :         && TREE_SIDE_EFFECTS (ind))
    4344        81231 :       ar = first = save_expr (ar);
    4345              : 
    4346              :     /* Put the integer in IND to simplify error checking.  */
    4347      4109626 :     if (TREE_CODE (TREE_TYPE (ar)) == INTEGER_TYPE)
    4348           57 :       std::swap (ar, ind);
    4349              : 
    4350      4109626 :     if (ar == error_mark_node || ind == error_mark_node)
    4351              :       return error_mark_node;
    4352              : 
    4353      4109626 :     if (!TYPE_PTR_P (TREE_TYPE (ar)))
    4354              :       {
    4355           33 :         if (complain & tf_error)
    4356            3 :           error_at (loc, "subscripted value is neither array nor pointer");
    4357           33 :         return error_mark_node;
    4358              :       }
    4359      4109593 :     if (TREE_CODE (TREE_TYPE (ind)) != INTEGER_TYPE)
    4360              :       {
    4361            0 :         if (complain & tf_error)
    4362            0 :           error_at (loc, "array subscript is not an integer");
    4363            0 :         return error_mark_node;
    4364              :       }
    4365              : 
    4366      4109593 :     warn_array_subscript_with_type_char (loc, idx);
    4367              : 
    4368      4109593 :     ret = cp_build_binary_op (input_location, PLUS_EXPR, ar, ind, complain);
    4369      4109593 :     if (first)
    4370        81231 :       ret = build2_loc (loc, COMPOUND_EXPR, TREE_TYPE (ret), first, ret);
    4371      4109593 :     ret = cp_build_indirect_ref (loc, ret, RO_ARRAY_INDEXING, complain);
    4372      4109593 :     protected_set_expr_location (ret, loc);
    4373      4109593 :     if (non_lvalue)
    4374            0 :       ret = non_lvalue_loc (loc, ret);
    4375              :     return ret;
    4376              :   }
    4377              : }
    4378              : 
    4379              : /* Entry point for Obj-C++.  */
    4380              : 
    4381              : tree
    4382      3636661 : build_array_ref (location_t loc, tree array, tree idx)
    4383              : {
    4384      3636661 :   return cp_build_array_ref (loc, array, idx, tf_warning_or_error);
    4385              : }
    4386              : 
    4387              : /* Resolve a pointer to member function.  INSTANCE is the object
    4388              :    instance to use, if the member points to a virtual member.
    4389              : 
    4390              :    This used to avoid checking for virtual functions if basetype
    4391              :    has no virtual functions, according to an earlier ANSI draft.
    4392              :    With the final ISO C++ rules, such an optimization is
    4393              :    incorrect: A pointer to a derived member can be static_cast
    4394              :    to pointer-to-base-member, as long as the dynamic object
    4395              :    later has the right member.  So now we only do this optimization
    4396              :    when we know the dynamic type of the object.  */
    4397              : 
    4398              : tree
    4399        83935 : get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function,
    4400              :                                   tsubst_flags_t complain)
    4401              : {
    4402        83935 :   if (TREE_CODE (function) == OFFSET_REF)
    4403            0 :     function = TREE_OPERAND (function, 1);
    4404              : 
    4405        83935 :   if (TYPE_PTRMEMFUNC_P (TREE_TYPE (function)))
    4406              :     {
    4407        83935 :       tree idx, delta, e1, e2, e3, vtbl;
    4408        83935 :       bool nonvirtual;
    4409        83935 :       tree fntype = TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (function));
    4410        83935 :       tree basetype = TYPE_METHOD_BASETYPE (TREE_TYPE (fntype));
    4411              : 
    4412        83935 :       tree instance_ptr = *instance_ptrptr;
    4413        83935 :       tree instance_save_expr = 0;
    4414        83935 :       if (instance_ptr == error_mark_node)
    4415              :         {
    4416            0 :           if (TREE_CODE (function) == PTRMEM_CST)
    4417              :             {
    4418              :               /* Extracting the function address from a pmf is only
    4419              :                  allowed with -Wno-pmf-conversions. It only works for
    4420              :                  pmf constants.  */
    4421            0 :               e1 = build_addr_func (PTRMEM_CST_MEMBER (function), complain);
    4422            0 :               e1 = convert (fntype, e1);
    4423            0 :               return e1;
    4424              :             }
    4425              :           else
    4426              :             {
    4427            0 :               if (complain & tf_error)
    4428            0 :                 error ("object missing in use of %qE", function);
    4429            0 :               return error_mark_node;
    4430              :             }
    4431              :         }
    4432              : 
    4433              :       /* True if we know that the dynamic type of the object doesn't have
    4434              :          virtual functions, so we can assume the PFN field is a pointer.  */
    4435        83935 :       nonvirtual = (COMPLETE_TYPE_P (basetype)
    4436        83899 :                     && !TYPE_POLYMORPHIC_P (basetype)
    4437       112809 :                     && resolves_to_fixed_type_p (instance_ptr, 0));
    4438              : 
    4439              :       /* If we don't really have an object (i.e. in an ill-formed
    4440              :          conversion from PMF to pointer), we can't resolve virtual
    4441              :          functions anyway.  */
    4442        83683 :       if (!nonvirtual && is_dummy_object (instance_ptr))
    4443              :         nonvirtual = true;
    4444              : 
    4445              :       /* Use force_target_expr even when instance_ptr doesn't have
    4446              :          side-effects, unless it is a simple decl or constant, so
    4447              :          that we don't ubsan instrument the expression multiple times.
    4448              :          Don't use save_expr, as save_expr can avoid building a SAVE_EXPR
    4449              :          and building a SAVE_EXPR manually can be optimized away during
    4450              :          cp_fold.  See PR116449 and PR117259.  */
    4451        83935 :       if (TREE_SIDE_EFFECTS (instance_ptr)
    4452        83935 :           || (!nonvirtual
    4453        46833 :               && !DECL_P (instance_ptr)
    4454        46833 :               && !TREE_CONSTANT (instance_ptr)))
    4455        83401 :         instance_ptr = instance_save_expr
    4456        83401 :           = get_internal_target_expr (instance_ptr);
    4457              : 
    4458              :       /* See above comment.  */
    4459        83935 :       if (TREE_SIDE_EFFECTS (function)
    4460        83935 :           || (!nonvirtual
    4461        65093 :               && !DECL_P (function)
    4462        65081 :               && !TREE_CONSTANT (function)))
    4463        83486 :         function = get_internal_target_expr (function);
    4464              : 
    4465              :       /* Start by extracting all the information from the PMF itself.  */
    4466        83935 :       e3 = pfn_from_ptrmemfunc (function);
    4467        83935 :       delta = delta_from_ptrmemfunc (function);
    4468        83935 :       idx = build1 (NOP_EXPR, vtable_index_type, e3);
    4469        83935 :       switch (TARGET_PTRMEMFUNC_VBIT_LOCATION)
    4470              :         {
    4471        83935 :           sanitize_code_type flag_sanitize_save;
    4472        83935 :         case ptrmemfunc_vbit_in_pfn:
    4473        83935 :           e1 = cp_build_binary_op (input_location,
    4474              :                                    BIT_AND_EXPR, idx, integer_one_node,
    4475              :                                    complain);
    4476        83935 :           idx = cp_build_binary_op (input_location,
    4477              :                                     MINUS_EXPR, idx, integer_one_node,
    4478              :                                     complain);
    4479        83935 :           if (idx == error_mark_node)
    4480              :             return error_mark_node;
    4481        83935 :           break;
    4482              : 
    4483              :         case ptrmemfunc_vbit_in_delta:
    4484              :           e1 = cp_build_binary_op (input_location,
    4485              :                                    BIT_AND_EXPR, delta, integer_one_node,
    4486              :                                    complain);
    4487              :           /* Don't instrument the RSHIFT_EXPR we're about to create because
    4488              :              we're going to use DELTA number of times, and that wouldn't play
    4489              :              well with SAVE_EXPRs therein.  */
    4490              :           flag_sanitize_save = flag_sanitize;
    4491              :           flag_sanitize = 0;
    4492              :           delta = cp_build_binary_op (input_location,
    4493              :                                       RSHIFT_EXPR, delta, integer_one_node,
    4494              :                                       complain);
    4495              :           flag_sanitize = flag_sanitize_save;
    4496              :           if (delta == error_mark_node)
    4497              :             return error_mark_node;
    4498              :           break;
    4499              : 
    4500              :         default:
    4501              :           gcc_unreachable ();
    4502              :         }
    4503              : 
    4504        83935 :       if (e1 == error_mark_node)
    4505              :         return error_mark_node;
    4506              : 
    4507              :       /* Convert down to the right base before using the instance.  A
    4508              :          special case is that in a pointer to member of class C, C may
    4509              :          be incomplete.  In that case, the function will of course be
    4510              :          a member of C, and no conversion is required.  In fact,
    4511              :          lookup_base will fail in that case, because incomplete
    4512              :          classes do not have BINFOs.  */
    4513        83935 :       if (!same_type_ignoring_top_level_qualifiers_p
    4514        83935 :           (basetype, TREE_TYPE (TREE_TYPE (instance_ptr))))
    4515              :         {
    4516           81 :           basetype = lookup_base (TREE_TYPE (TREE_TYPE (instance_ptr)),
    4517              :                                   basetype, ba_check, NULL, complain);
    4518           81 :           instance_ptr = build_base_path (PLUS_EXPR, instance_ptr, basetype,
    4519              :                                           1, complain);
    4520           81 :           if (instance_ptr == error_mark_node)
    4521              :             return error_mark_node;
    4522              :         }
    4523              :       /* ...and then the delta in the PMF.  */
    4524        83935 :       instance_ptr = fold_build_pointer_plus (instance_ptr, delta);
    4525              : 
    4526              :       /* Hand back the adjusted 'this' argument to our caller.  */
    4527        83935 :       *instance_ptrptr = instance_ptr;
    4528              : 
    4529        83935 :       if (nonvirtual)
    4530              :         /* Now just return the pointer.  */
    4531              :         return e3;
    4532              : 
    4533              :       /* Next extract the vtable pointer from the object.  */
    4534        83665 :       vtbl = build1 (NOP_EXPR, build_pointer_type (vtbl_ptr_type_node),
    4535              :                      instance_ptr);
    4536        83665 :       vtbl = cp_build_fold_indirect_ref (vtbl);
    4537        83665 :       if (vtbl == error_mark_node)
    4538              :         return error_mark_node;
    4539              : 
    4540              :       /* Finally, extract the function pointer from the vtable.  */
    4541        83665 :       e2 = fold_build_pointer_plus_loc (input_location, vtbl, idx);
    4542        83665 :       e2 = cp_build_fold_indirect_ref (e2);
    4543        83665 :       if (e2 == error_mark_node)
    4544              :         return error_mark_node;
    4545        83665 :       TREE_CONSTANT (e2) = 1;
    4546              : 
    4547              :       /* When using function descriptors, the address of the
    4548              :          vtable entry is treated as a function pointer.  */
    4549        83665 :       if (TARGET_VTABLE_USES_DESCRIPTORS)
    4550              :         e2 = build1 (NOP_EXPR, TREE_TYPE (e2),
    4551              :                      cp_build_addr_expr (e2, complain));
    4552              : 
    4553        83665 :       e2 = fold_convert (TREE_TYPE (e3), e2);
    4554        83665 :       e1 = build_conditional_expr (input_location, e1, e2, e3, complain);
    4555        83665 :       if (e1 == error_mark_node)
    4556              :         return error_mark_node;
    4557              : 
    4558              :       /* Make sure this doesn't get evaluated first inside one of the
    4559              :          branches of the COND_EXPR.  */
    4560        83665 :       if (instance_save_expr)
    4561        83353 :         e1 = build2 (COMPOUND_EXPR, TREE_TYPE (e1),
    4562              :                      instance_save_expr, e1);
    4563              : 
    4564              :       function = e1;
    4565              :     }
    4566              :   return function;
    4567              : }
    4568              : 
    4569              : /* Used by the C-common bits.  */
    4570              : tree
    4571            0 : build_function_call (location_t /*loc*/,
    4572              :                      tree function, tree params)
    4573              : {
    4574            0 :   return cp_build_function_call (function, params, tf_warning_or_error);
    4575              : }
    4576              : 
    4577              : /* Used by the C-common bits.  */
    4578              : tree
    4579       331285 : build_function_call_vec (location_t /*loc*/, vec<location_t> /*arg_loc*/,
    4580              :                          tree function, vec<tree, va_gc> *params,
    4581              :                          vec<tree, va_gc> * /*origtypes*/, tree orig_function)
    4582              : {
    4583       331285 :   vec<tree, va_gc> *orig_params = params;
    4584       331285 :   tree ret = cp_build_function_call_vec (function, &params,
    4585              :                                          tf_warning_or_error, orig_function);
    4586              : 
    4587              :   /* cp_build_function_call_vec can reallocate PARAMS by adding
    4588              :      default arguments.  That should never happen here.  Verify
    4589              :      that.  */
    4590       331285 :   gcc_assert (params == orig_params);
    4591              : 
    4592       331285 :   return ret;
    4593              : }
    4594              : 
    4595              : /* Build a function call using a tree list of arguments.  */
    4596              : 
    4597              : static tree
    4598            0 : cp_build_function_call (tree function, tree params, tsubst_flags_t complain)
    4599              : {
    4600            0 :   tree ret;
    4601              : 
    4602            0 :   releasing_vec vec;
    4603            0 :   for (; params != NULL_TREE; params = TREE_CHAIN (params))
    4604            0 :     vec_safe_push (vec, TREE_VALUE (params));
    4605            0 :   ret = cp_build_function_call_vec (function, &vec, complain);
    4606            0 :   return ret;
    4607            0 : }
    4608              : 
    4609              : /* Build a function call using varargs.  */
    4610              : 
    4611              : tree
    4612       556673 : cp_build_function_call_nary (tree function, tsubst_flags_t complain, ...)
    4613              : {
    4614       556673 :   va_list args;
    4615       556673 :   tree ret, t;
    4616              : 
    4617       556673 :   releasing_vec vec;
    4618       556673 :   va_start (args, complain);
    4619      1387024 :   for (t = va_arg (args, tree); t != NULL_TREE; t = va_arg (args, tree))
    4620       830351 :     vec_safe_push (vec, t);
    4621       556673 :   va_end (args);
    4622       556673 :   ret = cp_build_function_call_vec (function, &vec, complain);
    4623       556673 :   return ret;
    4624       556673 : }
    4625              : 
    4626              : /* C++ implementation of callback for use when checking param types.  */
    4627              : 
    4628              : bool
    4629           18 : cp_comp_parm_types (tree wanted_type, tree actual_type)
    4630              : {
    4631           18 :   if (TREE_CODE (wanted_type) == POINTER_TYPE
    4632           18 :       && TREE_CODE (actual_type) == POINTER_TYPE)
    4633           15 :     return same_or_base_type_p (TREE_TYPE (wanted_type),
    4634              :                                 TREE_TYPE (actual_type));
    4635              :   return false;
    4636              : }
    4637              : 
    4638              : /* Build a function call using a vector of arguments.
    4639              :    If FUNCTION is the result of resolving an overloaded target built-in,
    4640              :    ORIG_FNDECL is the original function decl, otherwise it is null.
    4641              :    PARAMS may be NULL if there are no parameters.  This changes the
    4642              :    contents of PARAMS.  */
    4643              : 
    4644              : tree
    4645      7643693 : cp_build_function_call_vec (tree function, vec<tree, va_gc> **params,
    4646              :                             tsubst_flags_t complain, tree orig_fndecl)
    4647              : {
    4648      7643693 :   tree fntype, fndecl;
    4649      7643693 :   int is_method;
    4650      7643693 :   tree original = function;
    4651      7643693 :   int nargs;
    4652      7643693 :   tree *argarray;
    4653      7643693 :   tree parm_types;
    4654      7643693 :   vec<tree, va_gc> *allocated = NULL;
    4655      7643693 :   tree ret;
    4656              : 
    4657              :   /* For Objective-C, convert any calls via a cast to OBJC_TYPE_REF
    4658              :      expressions, like those used for ObjC messenger dispatches.  */
    4659      7643693 :   if (params != NULL && !vec_safe_is_empty (*params))
    4660      2101603 :     function = objc_rewrite_function_call (function, (**params)[0]);
    4661              : 
    4662              :   /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
    4663              :      Strip such NOP_EXPRs, since FUNCTION is used in non-lvalue context.  */
    4664      7643693 :   if (TREE_CODE (function) == NOP_EXPR
    4665      7643693 :       && TREE_TYPE (function) == TREE_TYPE (TREE_OPERAND (function, 0)))
    4666           15 :     function = TREE_OPERAND (function, 0);
    4667              : 
    4668      7643693 :   if (TREE_CODE (function) == FUNCTION_DECL)
    4669              :     {
    4670      1576790 :       if (!mark_used (function, complain))
    4671           24 :         return error_mark_node;
    4672      1576766 :       fndecl = function;
    4673              : 
    4674              :       /* For target_version semantics, the function set cannot be called
    4675              :          if there is no default version in scope.  */
    4676      1576766 :       if (!TARGET_HAS_FMV_TARGET_ATTRIBUTE
    4677              :            && !is_function_default_version (fndecl))
    4678              :          {
    4679              :            if (complain & tf_error)
    4680              :             error ("no default version in scope");
    4681              :            return error_mark_node;
    4682              :          }
    4683              : 
    4684              :       /* Convert anything with function type to a pointer-to-function.  */
    4685      1576766 :       if (DECL_MAIN_P (function))
    4686              :         {
    4687            0 :           if (complain & tf_error)
    4688            0 :             pedwarn (input_location, OPT_Wpedantic,
    4689              :                      "ISO C++ forbids calling %<::main%> from within program");
    4690              :           else
    4691            0 :             return error_mark_node;
    4692              :         }
    4693      1576766 :       function = build_addr_func (function, complain);
    4694              :     }
    4695              :   else
    4696              :     {
    4697      6066903 :       fndecl = NULL_TREE;
    4698              : 
    4699      6066903 :       function = build_addr_func (function, complain);
    4700              :     }
    4701              : 
    4702      7643669 :   if (function == error_mark_node)
    4703              :     return error_mark_node;
    4704              : 
    4705      7643567 :   fntype = TREE_TYPE (function);
    4706              : 
    4707      7643567 :   if (TYPE_PTRMEMFUNC_P (fntype))
    4708              :     {
    4709           15 :       if (complain & tf_error)
    4710           15 :         error ("must use %<.*%> or %<->*%> to call pointer-to-member "
    4711              :                "function in %<%E (...)%>, e.g. %<(... ->* %E) (...)%>",
    4712              :                original, original);
    4713           15 :       return error_mark_node;
    4714              :     }
    4715              : 
    4716     15287104 :   is_method = (TYPE_PTR_P (fntype)
    4717      7643552 :                && TREE_CODE (TREE_TYPE (fntype)) == METHOD_TYPE);
    4718              : 
    4719      7643552 :   if (!(TYPE_PTRFN_P (fntype)
    4720        85682 :         || is_method
    4721         1803 :         || TREE_CODE (function) == TEMPLATE_ID_EXPR))
    4722              :     {
    4723         1803 :       if (complain & tf_error)
    4724              :         {
    4725          176 :           if (is_stub_object (original))
    4726            3 :             error_at (input_location,
    4727              :                       "%qT cannot be used as a function",
    4728            3 :                       TREE_TYPE (original));
    4729          173 :           else if (!flag_diagnostics_show_caret)
    4730          173 :             error_at (input_location,
    4731              :                       "%qE cannot be used as a function", original);
    4732            0 :           else if (DECL_P (original))
    4733            0 :             error_at (input_location,
    4734              :                       "%qD cannot be used as a function", original);
    4735              :           else
    4736            0 :             error_at (input_location,
    4737              :                       "expression cannot be used as a function");
    4738              :         }
    4739              : 
    4740         1803 :       return error_mark_node;
    4741              :     }
    4742              : 
    4743              :   /* fntype now gets the type of function pointed to.  */
    4744      7641749 :   fntype = TREE_TYPE (fntype);
    4745      7641749 :   parm_types = TYPE_ARG_TYPES (fntype);
    4746              : 
    4747      7641749 :   if (params == NULL)
    4748              :     {
    4749       151259 :       allocated = make_tree_vector ();
    4750       151259 :       params = &allocated;
    4751              :     }
    4752              : 
    4753      7641749 :     nargs = convert_arguments (parm_types, params, fndecl, LOOKUP_NORMAL,
    4754              :                                complain);
    4755      7641749 :   if (nargs < 0)
    4756         1880 :     return error_mark_node;
    4757              : 
    4758      7639869 :   argarray = (*params)->address ();
    4759              : 
    4760              :   /* Check for errors in format strings and inappropriately
    4761              :      null parameters.  */
    4762      7639869 :   bool warned_p
    4763      7639869 :     = ((complain & tf_warning)
    4764      7639869 :        && check_function_arguments (input_location, fndecl, fntype,
    4765              :                                     nargs, argarray, NULL,
    4766      7639869 :                                     cp_comp_parm_types));
    4767              : 
    4768      7639869 :   ret = build_cxx_call (function, nargs, argarray, complain, orig_fndecl);
    4769              : 
    4770      7639869 :   if (warned_p)
    4771              :     {
    4772           27 :       tree c = extract_call_expr (ret);
    4773           27 :       if (TREE_CODE (c) == CALL_EXPR)
    4774           27 :         suppress_warning (c, OPT_Wnonnull);
    4775              :     }
    4776              : 
    4777      7639869 :   if (allocated != NULL)
    4778       151259 :     release_tree_vector (allocated);
    4779              : 
    4780              :   return ret;
    4781              : }
    4782              : 
    4783              : /* Subroutine of convert_arguments.
    4784              :    Print an error message about a wrong number of arguments.  */
    4785              : 
    4786              : static void
    4787          162 : error_args_num (location_t loc, tree fndecl, bool too_many_p)
    4788              : {
    4789          162 :   if (fndecl)
    4790              :     {
    4791          126 :       auto_diagnostic_group d;
    4792          126 :       if (TREE_CODE (TREE_TYPE (fndecl)) == METHOD_TYPE)
    4793              :         {
    4794            0 :           if (DECL_NAME (fndecl) == NULL_TREE
    4795            0 :               || (DECL_NAME (fndecl)
    4796            0 :                   == DECL_NAME (TYPE_NAME (DECL_CONTEXT (fndecl)))))
    4797            0 :             error_at (loc,
    4798              :                       too_many_p
    4799              :                       ? G_("too many arguments to constructor %q#D")
    4800              :                       : G_("too few arguments to constructor %q#D"),
    4801              :                       fndecl);
    4802              :           else
    4803            0 :             error_at (loc,
    4804              :                       too_many_p
    4805              :                       ? G_("too many arguments to member function %q#D")
    4806              :                       : G_("too few arguments to member function %q#D"),
    4807              :                       fndecl);
    4808              :         }
    4809              :       else
    4810          189 :         error_at (loc,
    4811              :                   too_many_p
    4812              :                   ? G_("too many arguments to function %q#D")
    4813              :                   : G_("too few arguments to function %q#D"),
    4814              :                   fndecl);
    4815          126 :       if (!DECL_IS_UNDECLARED_BUILTIN (fndecl))
    4816           87 :         inform (DECL_SOURCE_LOCATION (fndecl), "declared here");
    4817          126 :     }
    4818              :   else
    4819              :     {
    4820           36 :       if (c_dialect_objc ()  &&  objc_message_selector ())
    4821            0 :         error_at (loc,
    4822              :                   too_many_p
    4823              :                   ? G_("too many arguments to method %q#D")
    4824              :                   : G_("too few arguments to method %q#D"),
    4825              :                   objc_message_selector ());
    4826              :       else
    4827           57 :         error_at (loc, too_many_p ? G_("too many arguments to function")
    4828              :                                   : G_("too few arguments to function"));
    4829              :     }
    4830          162 : }
    4831              : 
    4832              : /* Convert the actual parameter expressions in the list VALUES to the
    4833              :    types in the list TYPELIST.  The converted expressions are stored
    4834              :    back in the VALUES vector.
    4835              :    If parmdecls is exhausted, or when an element has NULL as its type,
    4836              :    perform the default conversions.
    4837              : 
    4838              :    NAME is an IDENTIFIER_NODE or 0.  It is used only for error messages.
    4839              : 
    4840              :    This is also where warnings about wrong number of args are generated.
    4841              : 
    4842              :    Returns the actual number of arguments processed (which might be less
    4843              :    than the length of the vector), or -1 on error.
    4844              : 
    4845              :    In C++, unspecified trailing parameters can be filled in with their
    4846              :    default arguments, if such were specified.  Do so here.  */
    4847              : 
    4848              : static int
    4849      7641749 : convert_arguments (tree typelist, vec<tree, va_gc> **values, tree fndecl,
    4850              :                    int flags, tsubst_flags_t complain)
    4851              : {
    4852      7641749 :   tree typetail;
    4853      7641749 :   unsigned int i;
    4854              : 
    4855              :   /* Argument passing is always copy-initialization.  */
    4856      7641749 :   flags |= LOOKUP_ONLYCONVERTING;
    4857              : 
    4858     12225199 :   for (i = 0, typetail = typelist;
    4859     12225199 :        i < vec_safe_length (*values);
    4860              :        i++)
    4861              :     {
    4862      9169890 :       tree type = typetail ? TREE_VALUE (typetail) : 0;
    4863      4585168 :       tree val = (**values)[i];
    4864              : 
    4865      4585168 :       if (val == error_mark_node || type == error_mark_node)
    4866              :         return -1;
    4867              : 
    4868      4585162 :       if (type == void_type_node)
    4869              :         {
    4870          205 :           if (complain & tf_error)
    4871           78 :             error_args_num (input_location, fndecl, /*too_many_p=*/true);
    4872          205 :           return -1;
    4873              :         }
    4874              : 
    4875              :       /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
    4876              :          Strip such NOP_EXPRs, since VAL is used in non-lvalue context.  */
    4877      4584957 :       if (TREE_CODE (val) == NOP_EXPR
    4878      1198734 :           && TREE_TYPE (val) == TREE_TYPE (TREE_OPERAND (val, 0))
    4879      4584975 :           && (type == 0 || !TYPE_REF_P (type)))
    4880           18 :         val = TREE_OPERAND (val, 0);
    4881              : 
    4882      4584957 :       if (type == 0 || !TYPE_REF_P (type))
    4883              :         {
    4884      4388177 :           if (TREE_CODE (TREE_TYPE (val)) == ARRAY_TYPE
    4885      4388177 :               || FUNC_OR_METHOD_TYPE_P (TREE_TYPE (val)))
    4886        11356 :             val = decay_conversion (val, complain);
    4887              :         }
    4888              : 
    4889      4584957 :       if (val == error_mark_node)
    4890              :         return -1;
    4891              : 
    4892      4584957 :       if (type != 0)
    4893              :         {
    4894              :           /* Formal parm type is specified by a function prototype.  */
    4895      4584511 :           tree parmval;
    4896              : 
    4897      4584511 :           if (!COMPLETE_TYPE_P (complete_type (type)))
    4898              :             {
    4899           18 :               if (complain & tf_error)
    4900              :                 {
    4901           12 :                   location_t loc = EXPR_LOC_OR_LOC (val, input_location);
    4902           12 :                   if (fndecl)
    4903              :                     {
    4904           12 :                       auto_diagnostic_group d;
    4905           12 :                       error_at (loc,
    4906              :                                 "parameter %P of %qD has incomplete type %qT",
    4907              :                                 i, fndecl, type);
    4908           12 :                       inform (get_fndecl_argument_location (fndecl, i),
    4909              :                               "  declared here");
    4910           12 :                     }
    4911              :                   else
    4912            0 :                     error_at (loc, "parameter %P has incomplete type %qT", i,
    4913              :                               type);
    4914              :                 }
    4915           18 :               parmval = error_mark_node;
    4916              :             }
    4917              :           else
    4918              :             {
    4919      4584493 :               parmval = convert_for_initialization
    4920      4584493 :                 (NULL_TREE, type, val, flags,
    4921              :                  ICR_ARGPASS, fndecl, i, complain);
    4922      4584493 :               parmval = convert_for_arg_passing (type, parmval, complain);
    4923              :             }
    4924              : 
    4925      4584511 :           if (parmval == error_mark_node)
    4926              :             return -1;
    4927              : 
    4928      4583004 :           (**values)[i] = parmval;
    4929              :         }
    4930              :       else
    4931              :         {
    4932          446 :           int magic = fndecl ? magic_varargs_p (fndecl) : 0;
    4933           21 :           if (magic)
    4934              :             {
    4935              :               /* Don't truncate excess precision to the semantic type.  */
    4936            0 :               if (magic == 1 && TREE_CODE (val) == EXCESS_PRECISION_EXPR)
    4937            0 :                 val = TREE_OPERAND (val, 0);
    4938              :               /* Don't do ellipsis conversion for __built_in_constant_p
    4939              :                  as this will result in spurious errors for non-trivial
    4940              :                  types.  */
    4941            0 :               val = require_complete_type (val, complain);
    4942              :             }
    4943              :           else
    4944          446 :             val = convert_arg_to_ellipsis (val, complain);
    4945              : 
    4946          446 :           (**values)[i] = val;
    4947              :         }
    4948              : 
    4949      4583450 :       if (typetail)
    4950      4583004 :         typetail = TREE_CHAIN (typetail);
    4951              :     }
    4952              : 
    4953      7640031 :   if (typetail != 0 && typetail != void_list_node)
    4954              :     {
    4955              :       /* See if there are default arguments that can be used.  Because
    4956              :          we hold default arguments in the FUNCTION_TYPE (which is so
    4957              :          wrong), we can see default parameters here from deduced
    4958              :          contexts (and via typeof) for indirect function calls.
    4959              :          Fortunately we know whether we have a function decl to
    4960              :          provide default arguments in a language conformant
    4961              :          manner.  */
    4962           63 :       if (fndecl && TREE_PURPOSE (typetail)
    4963          165 :           && TREE_CODE (TREE_PURPOSE (typetail)) != DEFERRED_PARSE)
    4964              :         {
    4965            6 :           for (; typetail != void_list_node; ++i)
    4966              :             {
    4967              :               /* After DR777, with explicit template args we can end up with a
    4968              :                  default argument followed by no default argument.  */
    4969            6 :               if (!TREE_PURPOSE (typetail))
    4970              :                 break;
    4971            3 :               tree parmval
    4972            3 :                 = convert_default_arg (TREE_VALUE (typetail),
    4973            3 :                                        TREE_PURPOSE (typetail),
    4974            3 :                                        fndecl, i, complain);
    4975              : 
    4976            3 :               if (parmval == error_mark_node)
    4977            0 :                 return -1;
    4978              : 
    4979            3 :               vec_safe_push (*values, parmval);
    4980            3 :               typetail = TREE_CHAIN (typetail);
    4981              :               /* ends with `...'.  */
    4982            3 :               if (typetail == NULL_TREE)
    4983              :                 break;
    4984              :             }
    4985              :         }
    4986              : 
    4987          162 :       if (typetail && typetail != void_list_node)
    4988              :         {
    4989          162 :           if (complain & tf_error)
    4990           84 :             error_args_num (input_location, fndecl, /*too_many_p=*/false);
    4991          162 :           return -1;
    4992              :         }
    4993              :     }
    4994              : 
    4995      7639869 :   return (int) i;
    4996              : }
    4997              : 
    4998              : /* Build a binary-operation expression, after performing default
    4999              :    conversions on the operands.  CODE is the kind of expression to
    5000              :    build.  ARG1 and ARG2 are the arguments.  ARG1_CODE and ARG2_CODE
    5001              :    are the tree codes which correspond to ARG1 and ARG2 when issuing
    5002              :    warnings about possibly misplaced parentheses.  They may differ
    5003              :    from the TREE_CODE of ARG1 and ARG2 if the parser has done constant
    5004              :    folding (e.g., if the parser sees "a | 1 + 1", it may call this
    5005              :    routine with ARG2 being an INTEGER_CST and ARG2_CODE == PLUS_EXPR).
    5006              :    To avoid issuing any parentheses warnings, pass ARG1_CODE and/or
    5007              :    ARG2_CODE as ERROR_MARK.  */
    5008              : 
    5009              : tree
    5010    225955212 : build_x_binary_op (const op_location_t &loc, enum tree_code code, tree arg1,
    5011              :                    enum tree_code arg1_code, tree arg2,
    5012              :                    enum tree_code arg2_code, tree lookups,
    5013              :                    tree *overload_p, tsubst_flags_t complain)
    5014              : {
    5015    225955212 :   tree orig_arg1;
    5016    225955212 :   tree orig_arg2;
    5017    225955212 :   tree expr;
    5018    225955212 :   tree overload = NULL_TREE;
    5019              : 
    5020    225955212 :   orig_arg1 = arg1;
    5021    225955212 :   orig_arg2 = arg2;
    5022              : 
    5023    225955212 :   if (processing_template_decl)
    5024              :     {
    5025    131487082 :       if (type_dependent_expression_p (arg1)
    5026    131487082 :           || type_dependent_expression_p (arg2))
    5027              :         {
    5028     90900355 :           expr = build_min_nt_loc (loc, code, arg1, arg2);
    5029     90900355 :           TREE_TYPE (expr)
    5030     90900355 :             = build_dependent_operator_type (lookups, code, false);
    5031     90900355 :           return expr;
    5032              :         }
    5033              :     }
    5034              : 
    5035    135054857 :   if (code == DOTSTAR_EXPR)
    5036        84072 :     expr = build_m_component_ref (arg1, arg2, complain);
    5037              :   else
    5038    134970785 :     expr = build_new_op (loc, code, LOOKUP_NORMAL, arg1, arg2, NULL_TREE,
    5039              :                          lookups, &overload, complain);
    5040              : 
    5041    135054824 :   if (overload_p != NULL)
    5042     59347385 :     *overload_p = overload;
    5043              : 
    5044              :   /* Check for cases such as x+y<<z which users are likely to
    5045              :      misinterpret.  But don't warn about obj << x + y, since that is a
    5046              :      common idiom for I/O.  */
    5047    135054824 :   if (warn_parentheses
    5048      1234874 :       && (complain & tf_warning)
    5049      1177594 :       && !processing_template_decl
    5050       813370 :       && !error_operand_p (arg1)
    5051       813364 :       && !error_operand_p (arg2)
    5052    135868176 :       && (code != LSHIFT_EXPR
    5053        71309 :           || !CLASS_TYPE_P (TREE_TYPE (arg1))))
    5054       812305 :     warn_about_parentheses (loc, code, arg1_code, orig_arg1,
    5055              :                             arg2_code, orig_arg2);
    5056              : 
    5057    135054824 :   if (processing_template_decl && expr != error_mark_node)
    5058              :     {
    5059     40586526 :       if (overload != NULL_TREE)
    5060      3834843 :         return (build_min_non_dep_op_overload
    5061      3834843 :                 (code, expr, overload, orig_arg1, orig_arg2));
    5062              : 
    5063     36751683 :       return build_min_non_dep (code, expr, orig_arg1, orig_arg2);
    5064              :     }
    5065              : 
    5066              :   return expr;
    5067              : }
    5068              : 
    5069              : /* Build and return an ARRAY_REF expression.  */
    5070              : 
    5071              : tree
    5072      2433052 : build_x_array_ref (location_t loc, tree arg1, tree arg2,
    5073              :                    tsubst_flags_t complain)
    5074              : {
    5075      2433052 :   tree orig_arg1 = arg1;
    5076      2433052 :   tree orig_arg2 = arg2;
    5077      2433052 :   tree expr;
    5078      2433052 :   tree overload = NULL_TREE;
    5079              : 
    5080      2433052 :   if (processing_template_decl)
    5081              :     {
    5082         4755 :       if (type_dependent_expression_p (arg1)
    5083         4755 :           || type_dependent_expression_p (arg2))
    5084         2561 :         return build_min_nt_loc (loc, ARRAY_REF, arg1, arg2,
    5085         2561 :                                  NULL_TREE, NULL_TREE);
    5086              :     }
    5087              : 
    5088      2430491 :   expr = build_new_op (loc, ARRAY_REF, LOOKUP_NORMAL, arg1, arg2,
    5089              :                        NULL_TREE, NULL_TREE, &overload, complain);
    5090              : 
    5091      2430491 :   if (processing_template_decl && expr != error_mark_node)
    5092              :     {
    5093         2191 :       if (overload != NULL_TREE)
    5094         2183 :         return (build_min_non_dep_op_overload
    5095         2183 :                 (ARRAY_REF, expr, overload, orig_arg1, orig_arg2));
    5096              : 
    5097            8 :       return build_min_non_dep (ARRAY_REF, expr, orig_arg1, orig_arg2,
    5098            8 :                                 NULL_TREE, NULL_TREE);
    5099              :     }
    5100              :   return expr;
    5101              : }
    5102              : 
    5103              : /* Build an OpenMP array section reference, creating an exact type for the
    5104              :    resulting expression based on the element type and bounds if possible.  If
    5105              :    we have variable bounds, create an incomplete array type for the result
    5106              :    instead.  */
    5107              : 
    5108              : tree
    5109        10480 : build_omp_array_section (location_t loc, tree array_expr, tree index,
    5110              :                          tree length)
    5111              : {
    5112        10480 :   if (TREE_CODE (array_expr) == TYPE_DECL
    5113        10480 :       || type_dependent_expression_p (array_expr))
    5114          258 :     return build3_loc (loc, OMP_ARRAY_SECTION, NULL_TREE, array_expr, index,
    5115          258 :                        length);
    5116              : 
    5117        10222 :   tree type = TREE_TYPE (array_expr);
    5118        10222 :   gcc_assert (type);
    5119        10222 :   type = non_reference (type);
    5120              : 
    5121        10222 :   tree sectype, eltype = TREE_TYPE (type);
    5122              : 
    5123              :   /* It's not an array or pointer type.  Just reuse the type of the
    5124              :      original expression as the type of the array section (an error will be
    5125              :      raised anyway, later).  */
    5126        10222 :   if (eltype == NULL_TREE)
    5127           39 :     sectype = TREE_TYPE (array_expr);
    5128              :   else
    5129              :     {
    5130        10183 :       tree idxtype = NULL_TREE;
    5131              : 
    5132              :       /* If we know the integer bounds, create an index type with exact
    5133              :          low/high (or zero/length) bounds.  Otherwise, create an incomplete
    5134              :          array type.  (This mostly only affects diagnostics.)  */
    5135        10183 :       if (index != NULL_TREE
    5136        10183 :           && length != NULL_TREE
    5137         7383 :           && TREE_CODE (index) == INTEGER_CST
    5138         6589 :           && TREE_CODE (length) == INTEGER_CST)
    5139              :         {
    5140         5094 :           tree low = fold_convert (sizetype, index);
    5141         5094 :           tree high = fold_convert (sizetype, length);
    5142         5094 :           high = size_binop (PLUS_EXPR, low, high);
    5143         5094 :           high = size_binop (MINUS_EXPR, high, size_one_node);
    5144         5094 :           idxtype = build_range_type (sizetype, low, high);
    5145         5094 :         }
    5146         2897 :       else if ((index == NULL_TREE || integer_zerop (index))
    5147         3503 :                && length != NULL_TREE
    5148         7187 :                && TREE_CODE (length) == INTEGER_CST)
    5149         1387 :         idxtype = build_index_type (length);
    5150              : 
    5151        10183 :       sectype = build_array_type (eltype, idxtype);
    5152              :     }
    5153              : 
    5154        10222 :   return build3_loc (loc, OMP_ARRAY_SECTION, sectype, array_expr, index,
    5155        10222 :                      length);
    5156              : }
    5157              : 
    5158              : /* Return whether OP is an expression of enum type cast to integer
    5159              :    type.  In C++ even unsigned enum types are cast to signed integer
    5160              :    types.  We do not want to issue warnings about comparisons between
    5161              :    signed and unsigned types when one of the types is an enum type.
    5162              :    Those warnings are always false positives in practice.  */
    5163              : 
    5164              : static bool
    5165       636800 : enum_cast_to_int (tree op)
    5166              : {
    5167       623836 :   if (CONVERT_EXPR_P (op)
    5168        13991 :       && TREE_TYPE (op) == integer_type_node
    5169          919 :       && TREE_CODE (TREE_TYPE (TREE_OPERAND (op, 0))) == ENUMERAL_TYPE
    5170       636815 :       && TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op, 0))))
    5171              :     return true;
    5172              : 
    5173              :   /* The cast may have been pushed into a COND_EXPR.  */
    5174       636793 :   if (TREE_CODE (op) == COND_EXPR)
    5175          765 :     return (enum_cast_to_int (TREE_OPERAND (op, 1))
    5176          765 :             || enum_cast_to_int (TREE_OPERAND (op, 2)));
    5177              : 
    5178              :   return false;
    5179              : }
    5180              : 
    5181              : /* For the c-common bits.  */
    5182              : tree
    5183      4660722 : build_binary_op (location_t location, enum tree_code code, tree op0, tree op1,
    5184              :                  bool /*convert_p*/)
    5185              : {
    5186      4660722 :   return cp_build_binary_op (location, code, op0, op1, tf_warning_or_error);
    5187              : }
    5188              : 
    5189              : /* Build a vector comparison of ARG0 and ARG1 using CODE opcode
    5190              :    into a value of TYPE type.  Comparison is done via VEC_COND_EXPR.  */
    5191              : 
    5192              : static tree
    5193         7683 : build_vec_cmp (tree_code code, tree type,
    5194              :                tree arg0, tree arg1)
    5195              : {
    5196         7683 :   tree zero_vec = build_zero_cst (type);
    5197         7683 :   tree minus_one_vec = build_minus_one_cst (type);
    5198         7683 :   tree cmp_type = truth_type_for (TREE_TYPE (arg0));
    5199         7683 :   tree cmp = build2 (code, cmp_type, arg0, arg1);
    5200         7683 :   return build3 (VEC_COND_EXPR, type, cmp, minus_one_vec, zero_vec);
    5201              : }
    5202              : 
    5203              : /* Possibly warn about an address never being NULL.  */
    5204              : 
    5205              : static void
    5206      1745309 : warn_for_null_address (location_t location, tree op, tsubst_flags_t complain)
    5207              : {
    5208              :   /* Prevent warnings issued for macro expansion.  */
    5209      1745309 :   if (!warn_address
    5210        41621 :       || (complain & tf_warning) == 0
    5211        24888 :       || c_inhibit_evaluation_warnings != 0
    5212        24872 :       || from_macro_expansion_at (location)
    5213      1763450 :       || warning_suppressed_p (op, OPT_Waddress))
    5214      1727491 :     return;
    5215              : 
    5216        18108 :   tree cop = fold_for_warn (op);
    5217              : 
    5218        18108 :   if (TREE_CODE (cop) == NON_LVALUE_EXPR)
    5219              :     /* Unwrap the expression for C++ 98.  */
    5220            1 :     cop = TREE_OPERAND (cop, 0);
    5221              : 
    5222        18108 :   if (TREE_CODE (cop) == PTRMEM_CST)
    5223              :     {
    5224              :       /* The address of a nonstatic data member is never null.  */
    5225           30 :       warning_at (location, OPT_Waddress,
    5226              :                   "the address %qE will never be NULL",
    5227              :                   cop);
    5228           30 :       return;
    5229              :     }
    5230              : 
    5231        18078 :   if (TREE_CODE (cop) == NOP_EXPR)
    5232              :     {
    5233              :       /* Allow casts to intptr_t to suppress the warning.  */
    5234         1243 :       tree type = TREE_TYPE (cop);
    5235         1243 :       if (TREE_CODE (type) == INTEGER_TYPE)
    5236              :         return;
    5237              : 
    5238         1243 :       STRIP_NOPS (cop);
    5239              :     }
    5240              : 
    5241        18078 :   auto_diagnostic_group d;
    5242        18078 :   bool warned = false;
    5243        18078 :   if (TREE_CODE (cop) == ADDR_EXPR)
    5244              :     {
    5245          789 :       cop = TREE_OPERAND (cop, 0);
    5246              : 
    5247              :       /* Set to true in the loop below if OP dereferences its operand.
    5248              :          In such a case the ultimate target need not be a decl for
    5249              :          the null [in]equality test to be necessarily constant.  */
    5250          789 :       bool deref = false;
    5251              : 
    5252              :       /* Get the outermost array or object, or member.  */
    5253          960 :       while (handled_component_p (cop))
    5254              :         {
    5255          270 :           if (TREE_CODE (cop) == COMPONENT_REF)
    5256              :             {
    5257              :               /* Get the member (its address is never null).  */
    5258           99 :               cop = TREE_OPERAND (cop, 1);
    5259           99 :               break;
    5260              :             }
    5261              : 
    5262              :           /* Get the outer array/object to refer to in the warning.  */
    5263          171 :           cop = TREE_OPERAND (cop, 0);
    5264          171 :           deref = true;
    5265              :         }
    5266              : 
    5267          639 :       if ((!deref && !decl_with_nonnull_addr_p (cop))
    5268          631 :           || from_macro_expansion_at (location)
    5269         1420 :           || warning_suppressed_p (cop, OPT_Waddress))
    5270          158 :         return;
    5271              : 
    5272          631 :       warned = warning_at (location, OPT_Waddress,
    5273              :                            "the address of %qD will never be NULL", cop);
    5274          631 :       op = cop;
    5275              :     }
    5276        17289 :   else if (TREE_CODE (cop) == POINTER_PLUS_EXPR)
    5277              :     {
    5278              :       /* Adding zero to the null pointer is well-defined in C++.  When
    5279              :          the offset is unknown (i.e., not a constant) warn anyway since
    5280              :          it's less likely that the pointer operand is null than not.  */
    5281          102 :       tree off = TREE_OPERAND (cop, 1);
    5282          102 :       if (!integer_zerop (off)
    5283          102 :           && !warning_suppressed_p (cop, OPT_Waddress))
    5284              :         {
    5285          102 :           tree base = TREE_OPERAND (cop, 0);
    5286          102 :           STRIP_NOPS (base);
    5287          102 :           if (TYPE_REF_P (TREE_TYPE (base)))
    5288           12 :             warning_at (location, OPT_Waddress, "the compiler can assume that "
    5289              :                         "the address of %qE will never be NULL", base);
    5290              :           else
    5291           90 :             warning_at (location, OPT_Waddress, "comparing the result of "
    5292              :                         "pointer addition %qE and NULL", cop);
    5293              :         }
    5294          102 :       return;
    5295              :     }
    5296        16225 :   else if (CONVERT_EXPR_P (op)
    5297        17249 :            && TYPE_REF_P (TREE_TYPE (TREE_OPERAND (op, 0))))
    5298              :     {
    5299           62 :       STRIP_NOPS (op);
    5300              : 
    5301           62 :       if (TREE_CODE (op) == COMPONENT_REF)
    5302           24 :         op = TREE_OPERAND (op, 1);
    5303              : 
    5304           62 :       if (DECL_P (op))
    5305           62 :         warned = warning_at (location, OPT_Waddress,
    5306              :                              "the compiler can assume that the address of "
    5307              :                              "%qD will never be NULL", op);
    5308              :     }
    5309              : 
    5310          693 :   if (warned && DECL_P (op))
    5311          657 :     inform (DECL_SOURCE_LOCATION (op), "%qD declared here", op);
    5312        18078 : }
    5313              : 
    5314              : /* Warn about [expr.arith.conv]/2: If one operand is of enumeration type and
    5315              :    the other operand is of a different enumeration type or a floating-point
    5316              :    type, this behavior is deprecated ([depr.arith.conv.enum]).  CODE is the
    5317              :    code of the binary operation, TYPE0 and TYPE1 are the types of the operands,
    5318              :    and LOC is the location for the whole binary expression.
    5319              :    For C++26 this is ill-formed rather than deprecated.
    5320              :    Return true for SFINAE errors.
    5321              :    TODO: Consider combining this with -Wenum-compare in build_new_op_1.  */
    5322              : 
    5323              : static bool
    5324    107332952 : do_warn_enum_conversions (location_t loc, enum tree_code code, tree type0,
    5325              :                           tree type1, tsubst_flags_t complain)
    5326              : {
    5327    107332952 :   if (TREE_CODE (type0) == ENUMERAL_TYPE
    5328      3168555 :       && TREE_CODE (type1) == ENUMERAL_TYPE
    5329    109987257 :       && TYPE_MAIN_VARIANT (type0) != TYPE_MAIN_VARIANT (type1))
    5330              :     {
    5331          198 :       if (cxx_dialect >= cxx26)
    5332              :         {
    5333           60 :           if ((complain & tf_warning_or_error) == 0)
    5334              :             return true;
    5335              :         }
    5336          138 :       else if ((complain & tf_warning) == 0)
    5337              :         return false;
    5338              :       /* In C++20, -Wdeprecated-enum-enum-conversion is on by default.
    5339              :          Otherwise, warn if -Wenum-conversion is on.  */
    5340          190 :       enum opt_code opt;
    5341          190 :       if (warn_deprecated_enum_enum_conv)
    5342              :         opt = OPT_Wdeprecated_enum_enum_conversion;
    5343           93 :       else if (warn_enum_conversion)
    5344              :         opt = OPT_Wenum_conversion;
    5345              :       else
    5346              :         return false;
    5347              : 
    5348          119 :       switch (code)
    5349              :         {
    5350              :         case GT_EXPR:
    5351              :         case LT_EXPR:
    5352              :         case GE_EXPR:
    5353              :         case LE_EXPR:
    5354              :         case EQ_EXPR:
    5355              :         case NE_EXPR:
    5356              :           /* Comparisons are handled by -Wenum-compare.  */
    5357              :           return false;
    5358              :         case SPACESHIP_EXPR:
    5359              :           /* This is invalid, don't warn.  */
    5360              :           return false;
    5361           17 :         case BIT_AND_EXPR:
    5362           17 :         case BIT_IOR_EXPR:
    5363           17 :         case BIT_XOR_EXPR:
    5364           17 :           if (cxx_dialect >= cxx26)
    5365            5 :             pedwarn (loc, opt, "bitwise operation between different "
    5366              :                      "enumeration types %qT and %qT", type0, type1);
    5367              :           else
    5368           12 :             warning_at (loc, opt, "bitwise operation between different "
    5369              :                         "enumeration types %qT and %qT is deprecated",
    5370              :                         type0, type1);
    5371           17 :           return false;
    5372           41 :         default:
    5373           41 :           if (cxx_dialect >= cxx26)
    5374           12 :             pedwarn (loc, opt, "arithmetic between different enumeration "
    5375              :                      "types %qT and %qT", type0, type1);
    5376              :           else
    5377           29 :             warning_at (loc, opt, "arithmetic between different enumeration "
    5378              :                         "types %qT and %qT is deprecated", type0, type1);
    5379           41 :           return false;
    5380              :         }
    5381              :     }
    5382    107332754 :   else if ((TREE_CODE (type0) == ENUMERAL_TYPE
    5383      3168357 :             && SCALAR_FLOAT_TYPE_P (type1))
    5384    107332684 :            || (SCALAR_FLOAT_TYPE_P (type0)
    5385     30811120 :                && TREE_CODE (type1) == ENUMERAL_TYPE))
    5386              :     {
    5387          147 :       if (cxx_dialect >= cxx26)
    5388              :         {
    5389           46 :           if ((complain & tf_warning_or_error) == 0)
    5390              :             return true;
    5391              :         }
    5392          101 :       else if ((complain & tf_warning) == 0)
    5393              :         return false;
    5394          135 :       const bool enum_first_p = TREE_CODE (type0) == ENUMERAL_TYPE;
    5395              :       /* In C++20, -Wdeprecated-enum-float-conversion is on by default.
    5396              :          Otherwise, warn if -Wenum-conversion is on.  */
    5397          135 :       enum opt_code opt;
    5398          135 :       if (warn_deprecated_enum_float_conv)
    5399              :         opt = OPT_Wdeprecated_enum_float_conversion;
    5400           68 :       else if (warn_enum_conversion)
    5401              :         opt = OPT_Wenum_conversion;
    5402              :       else
    5403              :         return false;
    5404              : 
    5405           84 :       switch (code)
    5406              :         {
    5407           34 :         case GT_EXPR:
    5408           34 :         case LT_EXPR:
    5409           34 :         case GE_EXPR:
    5410           34 :         case LE_EXPR:
    5411           34 :         case EQ_EXPR:
    5412           34 :         case NE_EXPR:
    5413           34 :           if (enum_first_p && cxx_dialect >= cxx26)
    5414            5 :             pedwarn (loc, opt, "comparison of enumeration type %qT with "
    5415              :                      "floating-point type %qT", type0, type1);
    5416           29 :           else if (cxx_dialect >= cxx26)
    5417            5 :             pedwarn (loc, opt, "comparison of floating-point type %qT "
    5418              :                       "with enumeration type %qT", type0, type1);
    5419           24 :           else if (enum_first_p)
    5420           12 :             warning_at (loc, opt, "comparison of enumeration type %qT with "
    5421              :                         "floating-point type %qT is deprecated",
    5422              :                         type0, type1);
    5423              :           else
    5424           12 :             warning_at (loc, opt, "comparison of floating-point type %qT "
    5425              :                         "with enumeration type %qT is deprecated",
    5426              :                         type0, type1);
    5427           34 :           return false;
    5428              :         case SPACESHIP_EXPR:
    5429              :           /* This is invalid, don't warn.  */
    5430              :           return false;
    5431           38 :         default:
    5432           38 :           if (enum_first_p && cxx_dialect >= cxx26)
    5433            5 :             pedwarn (loc, opt, "arithmetic between enumeration type %qT "
    5434              :                      "and floating-point type %qT", type0, type1);
    5435           33 :           else if (cxx_dialect >= cxx26)
    5436            6 :             pedwarn (loc, opt, "arithmetic between floating-point type %qT "
    5437              :                      "and enumeration type %qT", type0, type1);
    5438           27 :           else if (enum_first_p)
    5439           12 :             warning_at (loc, opt, "arithmetic between enumeration type %qT "
    5440              :                         "and floating-point type %qT is deprecated",
    5441              :                         type0, type1);
    5442              :           else
    5443           15 :             warning_at (loc, opt, "arithmetic between floating-point type %qT "
    5444              :                         "and enumeration type %qT is deprecated",
    5445              :                         type0, type1);
    5446           38 :           return false;
    5447              :         }
    5448              :     }
    5449              :   return false;
    5450              : }
    5451              : 
    5452              : /* Build a binary-operation expression without default conversions.
    5453              :    CODE is the kind of expression to build.
    5454              :    LOCATION is the location_t of the operator in the source code.
    5455              :    This function differs from `build' in several ways:
    5456              :    the data type of the result is computed and recorded in it,
    5457              :    warnings are generated if arg data types are invalid,
    5458              :    special handling for addition and subtraction of pointers is known,
    5459              :    and some optimization is done (operations on narrow ints
    5460              :    are done in the narrower type when that gives the same result).
    5461              :    Constant folding is also done before the result is returned.
    5462              : 
    5463              :    Note that the operands will never have enumeral types
    5464              :    because either they have just had the default conversions performed
    5465              :    or they have both just been converted to some other type in which
    5466              :    the arithmetic is to be done.
    5467              : 
    5468              :    C++: must do special pointer arithmetic when implementing
    5469              :    multiple inheritance, and deal with pointer to member functions.  */
    5470              : 
    5471              : tree
    5472    143582917 : cp_build_binary_op (const op_location_t &location,
    5473              :                     enum tree_code code, tree orig_op0, tree orig_op1,
    5474              :                     tsubst_flags_t complain)
    5475              : {
    5476    143582917 :   tree op0, op1;
    5477    143582917 :   enum tree_code code0, code1;
    5478    143582917 :   tree type0, type1, orig_type0, orig_type1;
    5479    143582917 :   const char *invalid_op_diag;
    5480              : 
    5481              :   /* Expression code to give to the expression when it is built.
    5482              :      Normally this is CODE, which is what the caller asked for,
    5483              :      but in some special cases we change it.  */
    5484    143582917 :   enum tree_code resultcode = code;
    5485              : 
    5486              :   /* Data type in which the computation is to be performed.
    5487              :      In the simplest cases this is the common type of the arguments.  */
    5488    143582917 :   tree result_type = NULL_TREE;
    5489              : 
    5490              :   /* When the computation is in excess precision, the type of the
    5491              :      final EXCESS_PRECISION_EXPR.  */
    5492    143582917 :   tree semantic_result_type = NULL;
    5493              : 
    5494              :   /* Nonzero means operands have already been type-converted
    5495              :      in whatever way is necessary.
    5496              :      Zero means they need to be converted to RESULT_TYPE.  */
    5497    143582917 :   int converted = 0;
    5498              : 
    5499              :   /* Nonzero means create the expression with this type, rather than
    5500              :      RESULT_TYPE.  */
    5501    143582917 :   tree build_type = 0;
    5502              : 
    5503              :   /* Nonzero means after finally constructing the expression
    5504              :      convert it to this type.  */
    5505    143582917 :   tree final_type = 0;
    5506              : 
    5507    143582917 :   tree result;
    5508              : 
    5509              :   /* Nonzero if this is an operation like MIN or MAX which can
    5510              :      safely be computed in short if both args are promoted shorts.
    5511              :      Also implies COMMON.
    5512              :      -1 indicates a bitwise operation; this makes a difference
    5513              :      in the exact conditions for when it is safe to do the operation
    5514              :      in a narrower mode.  */
    5515    143582917 :   int shorten = 0;
    5516              : 
    5517              :   /* Nonzero if this is a comparison operation;
    5518              :      if both args are promoted shorts, compare the original shorts.
    5519              :      Also implies COMMON.  */
    5520    143582917 :   int short_compare = 0;
    5521              : 
    5522              :   /* Nonzero if this is a right-shift operation, which can be computed on the
    5523              :      original short and then promoted if the operand is a promoted short.  */
    5524    143582917 :   int short_shift = 0;
    5525              : 
    5526              :   /* Nonzero means set RESULT_TYPE to the common type of the args.  */
    5527    143582917 :   int common = 0;
    5528              : 
    5529              :   /* True if both operands have arithmetic type.  */
    5530    143582917 :   bool arithmetic_types_p;
    5531              : 
    5532              :   /* Remember whether we're doing / or %.  */
    5533    143582917 :   bool doing_div_or_mod = false;
    5534              : 
    5535              :   /* Remember whether we're doing << or >>.  */
    5536    143582917 :   bool doing_shift = false;
    5537              : 
    5538              :   /* Tree holding instrumentation expression.  */
    5539    143582917 :   tree instrument_expr = NULL_TREE;
    5540              : 
    5541              :   /* True means this is an arithmetic operation that may need excess
    5542              :      precision.  */
    5543    143582917 :   bool may_need_excess_precision;
    5544              : 
    5545              :   /* Apply default conversions.  */
    5546    143582917 :   op0 = resolve_nondeduced_context (orig_op0, complain);
    5547    143582917 :   op1 = resolve_nondeduced_context (orig_op1, complain);
    5548              : 
    5549    143582917 :   if (code == TRUTH_AND_EXPR || code == TRUTH_ANDIF_EXPR
    5550    130791960 :       || code == TRUTH_OR_EXPR || code == TRUTH_ORIF_EXPR
    5551    127531210 :       || code == TRUTH_XOR_EXPR)
    5552              :     {
    5553     16051707 :       if (!really_overloaded_fn (op0) && !VOID_TYPE_P (TREE_TYPE (op0)))
    5554     16051689 :         op0 = decay_conversion (op0, complain);
    5555     16051707 :       if (!really_overloaded_fn (op1) && !VOID_TYPE_P (TREE_TYPE (op1)))
    5556     16051707 :         op1 = decay_conversion (op1, complain);
    5557              :     }
    5558              :   else
    5559              :     {
    5560    127531210 :       if (!really_overloaded_fn (op0) && !VOID_TYPE_P (TREE_TYPE (op0)))
    5561    127531167 :         op0 = cp_default_conversion (op0, complain);
    5562    127531210 :       if (!really_overloaded_fn (op1) && !VOID_TYPE_P (TREE_TYPE (op1)))
    5563    127531191 :         op1 = cp_default_conversion (op1, complain);
    5564              :     }
    5565              : 
    5566              :   /* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue.  */
    5567    151901090 :   STRIP_TYPE_NOPS (op0);
    5568    176315586 :   STRIP_TYPE_NOPS (op1);
    5569              : 
    5570              :   /* DTRT if one side is an overloaded function, but complain about it.  */
    5571    143582917 :   if (type_unknown_p (op0))
    5572              :     {
    5573            9 :       tree t = instantiate_type (TREE_TYPE (op1), op0, tf_none);
    5574            9 :       if (t != error_mark_node)
    5575              :         {
    5576            0 :           if (complain & tf_error)
    5577            0 :             permerror (location,
    5578              :                        "assuming cast to type %qT from overloaded function",
    5579            0 :                        TREE_TYPE (t));
    5580              :           op0 = t;
    5581              :         }
    5582              :     }
    5583    143582917 :   if (type_unknown_p (op1))
    5584              :     {
    5585            3 :       tree t = instantiate_type (TREE_TYPE (op0), op1, tf_none);
    5586            3 :       if (t != error_mark_node)
    5587              :         {
    5588            3 :           if (complain & tf_error)
    5589            3 :             permerror (location,
    5590              :                        "assuming cast to type %qT from overloaded function",
    5591            3 :                        TREE_TYPE (t));
    5592              :           op1 = t;
    5593              :         }
    5594              :     }
    5595              : 
    5596    143582917 :   orig_type0 = type0 = TREE_TYPE (op0);
    5597    143582917 :   orig_type1 = type1 = TREE_TYPE (op1);
    5598    143582917 :   tree non_ep_op0 = op0;
    5599    143582917 :   tree non_ep_op1 = op1;
    5600              : 
    5601              :   /* The expression codes of the data types of the arguments tell us
    5602              :      whether the arguments are integers, floating, pointers, etc.  */
    5603    143582917 :   code0 = TREE_CODE (type0);
    5604    143582917 :   code1 = TREE_CODE (type1);
    5605              : 
    5606              :   /* If an error was already reported for one of the arguments,
    5607              :      avoid reporting another error.  */
    5608    143582917 :   if (code0 == ERROR_MARK || code1 == ERROR_MARK)
    5609           99 :     return error_mark_node;
    5610              : 
    5611    287165636 :   if ((invalid_op_diag
    5612    143582818 :        = targetm.invalid_binary_op (code, type0, type1)))
    5613              :     {
    5614            0 :       if (complain & tf_error)
    5615              :         {
    5616            0 :           if (code0 == REAL_TYPE
    5617            0 :               && code1 == REAL_TYPE
    5618            0 :               && (extended_float_type_p (type0)
    5619            0 :                   || extended_float_type_p (type1))
    5620            0 :               && cp_compare_floating_point_conversion_ranks (type0,
    5621              :                                                              type1) == 3)
    5622              :             {
    5623            0 :               rich_location richloc (line_table, location);
    5624            0 :               binary_op_error (&richloc, code, type0, type1);
    5625            0 :             }
    5626              :           else
    5627            0 :             error (invalid_op_diag);
    5628              :         }
    5629            0 :       return error_mark_node;
    5630              :     }
    5631              : 
    5632    143582818 :   switch (code)
    5633              :     {
    5634              :     case PLUS_EXPR:
    5635              :     case MINUS_EXPR:
    5636              :     case MULT_EXPR:
    5637              :     case TRUNC_DIV_EXPR:
    5638              :     case CEIL_DIV_EXPR:
    5639              :     case FLOOR_DIV_EXPR:
    5640              :     case ROUND_DIV_EXPR:
    5641              :     case EXACT_DIV_EXPR:
    5642              :       may_need_excess_precision = true;
    5643              :       break;
    5644     51132524 :     case EQ_EXPR:
    5645     51132524 :     case NE_EXPR:
    5646     51132524 :     case LE_EXPR:
    5647     51132524 :     case GE_EXPR:
    5648     51132524 :     case LT_EXPR:
    5649     51132524 :     case GT_EXPR:
    5650     51132524 :     case SPACESHIP_EXPR:
    5651              :       /* Excess precision for implicit conversions of integers to
    5652              :          floating point.  */
    5653     11385051 :       may_need_excess_precision = (ANY_INTEGRAL_TYPE_P (type0)
    5654     62510511 :                                    || ANY_INTEGRAL_TYPE_P (type1));
    5655              :       break;
    5656              :     default:
    5657    143582818 :       may_need_excess_precision = false;
    5658              :       break;
    5659              :     }
    5660    143582818 :   if (TREE_CODE (op0) == EXCESS_PRECISION_EXPR)
    5661              :     {
    5662        11018 :       op0 = TREE_OPERAND (op0, 0);
    5663        11018 :       type0 = TREE_TYPE (op0);
    5664              :     }
    5665    143571800 :   else if (may_need_excess_precision
    5666    108122845 :            && (code0 == REAL_TYPE || code0 == COMPLEX_TYPE))
    5667     26886504 :     if (tree eptype = excess_precision_type (type0))
    5668              :       {
    5669        29197 :         type0 = eptype;
    5670        29197 :         op0 = convert (eptype, op0);
    5671              :       }
    5672    143582818 :   if (TREE_CODE (op1) == EXCESS_PRECISION_EXPR)
    5673              :     {
    5674        13760 :       op1 = TREE_OPERAND (op1, 0);
    5675        13760 :       type1 = TREE_TYPE (op1);
    5676              :     }
    5677    143569058 :   else if (may_need_excess_precision
    5678    108121700 :            && (code1 == REAL_TYPE || code1 == COMPLEX_TYPE))
    5679     26745279 :     if (tree eptype = excess_precision_type (type1))
    5680              :       {
    5681        19779 :         type1 = eptype;
    5682        19779 :         op1 = convert (eptype, op1);
    5683              :       }
    5684              : 
    5685              :   /* Issue warnings about peculiar, but valid, uses of NULL.  */
    5686    287165551 :   if ((null_node_p (orig_op0) || null_node_p (orig_op1))
    5687              :       /* It's reasonable to use pointer values as operands of &&
    5688              :          and ||, so NULL is no exception.  */
    5689        12094 :       && code != TRUTH_ANDIF_EXPR && code != TRUTH_ORIF_EXPR
    5690        12079 :       && ( /* Both are NULL (or 0) and the operation was not a
    5691              :               comparison or a pointer subtraction.  */
    5692        12152 :           (null_ptr_cst_p (orig_op0) && null_ptr_cst_p (orig_op1)
    5693           27 :            && code != EQ_EXPR && code != NE_EXPR && code != MINUS_EXPR)
    5694              :           /* Or if one of OP0 or OP1 is neither a pointer nor NULL.  */
    5695        12067 :           || (!null_ptr_cst_p (orig_op0)
    5696        12006 :               && !TYPE_PTR_OR_PTRMEM_P (type0))
    5697        12055 :           || (!null_ptr_cst_p (orig_op1)
    5698           46 :               && !TYPE_PTR_OR_PTRMEM_P (type1)))
    5699    143582857 :       && (complain & tf_warning))
    5700              :     {
    5701           39 :       location_t loc =
    5702           39 :         expansion_point_location_if_in_system_header (input_location);
    5703              : 
    5704           39 :       warning_at (loc, OPT_Wpointer_arith, "NULL used in arithmetic");
    5705              :     }
    5706              : 
    5707              :   /* In case when one of the operands of the binary operation is
    5708              :      a vector and another is a scalar -- convert scalar to vector.  */
    5709    143650887 :   if ((gnu_vector_type_p (type0) && code1 != VECTOR_TYPE)
    5710    143649916 :       || (gnu_vector_type_p (type1) && code0 != VECTOR_TYPE))
    5711              :     {
    5712         1056 :       enum stv_conv convert_flag
    5713         1056 :         = scalar_to_vector (location, code, non_ep_op0, non_ep_op1,
    5714              :                             complain & tf_error);
    5715              : 
    5716         1056 :       switch (convert_flag)
    5717              :         {
    5718           21 :           case stv_error:
    5719           21 :             return error_mark_node;
    5720           55 :           case stv_firstarg:
    5721           55 :             {
    5722           55 :               op0 = convert (TREE_TYPE (type1), op0);
    5723           55 :               op0 = cp_save_expr (op0);
    5724           55 :               op0 = build_vector_from_val (type1, op0);
    5725           55 :               orig_type0 = type0 = TREE_TYPE (op0);
    5726           55 :               code0 = TREE_CODE (type0);
    5727           55 :               converted = 1;
    5728           55 :               break;
    5729              :             }
    5730          859 :           case stv_secondarg:
    5731          859 :             {
    5732          859 :               op1 = convert (TREE_TYPE (type0), op1);
    5733          859 :               op1 = cp_save_expr (op1);
    5734          859 :               op1 = build_vector_from_val (type0, op1);
    5735          859 :               orig_type1 = type1 = TREE_TYPE (op1);
    5736          859 :               code1 = TREE_CODE (type1);
    5737          859 :               converted = 1;
    5738          859 :               break;
    5739              :             }
    5740              :           default:
    5741              :             break;
    5742              :         }
    5743              :     }
    5744              : 
    5745    143582797 :   switch (code)
    5746              :     {
    5747     15715715 :     case MINUS_EXPR:
    5748              :       /* Subtraction of two similar pointers.
    5749              :          We must subtract them as integers, then divide by object size.  */
    5750     15715715 :       if (code0 == POINTER_TYPE && code1 == POINTER_TYPE
    5751     17186199 :           && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (type0),
    5752      1470484 :                                                         TREE_TYPE (type1)))
    5753              :         {
    5754      1470482 :           result = pointer_diff (location, op0, op1,
    5755              :                                  common_pointer_type (type0, type1), complain,
    5756              :                                  &instrument_expr);
    5757      1470482 :           if (instrument_expr != NULL)
    5758           84 :             result = build2 (COMPOUND_EXPR, TREE_TYPE (result),
    5759              :                              instrument_expr, result);
    5760              : 
    5761      1470482 :           return result;
    5762              :         }
    5763              :       /* In all other cases except pointer - int, the usual arithmetic
    5764              :          rules apply.  */
    5765     14245233 :       else if (!(code0 == POINTER_TYPE && code1 == INTEGER_TYPE))
    5766              :         {
    5767              :           common = 1;
    5768              :           break;
    5769              :         }
    5770              :       /* The pointer - int case is just like pointer + int; fall
    5771              :          through.  */
    5772     20826217 :       gcc_fallthrough ();
    5773     20826217 :     case PLUS_EXPR:
    5774     20826217 :       if ((code0 == POINTER_TYPE || code1 == POINTER_TYPE)
    5775      7587148 :           && (code0 == INTEGER_TYPE || code1 == INTEGER_TYPE))
    5776              :         {
    5777      7587139 :           tree ptr_operand;
    5778      7587139 :           tree int_operand;
    5779      7587139 :           ptr_operand = ((code0 == POINTER_TYPE) ? op0 : op1);
    5780       121739 :           int_operand = ((code0 == INTEGER_TYPE) ? op0 : op1);
    5781      7587139 :           if (processing_template_decl)
    5782              :             {
    5783      2175829 :               result_type = TREE_TYPE (ptr_operand);
    5784      2175829 :               break;
    5785              :             }
    5786      5411310 :           return cp_pointer_int_sum (location, code,
    5787              :                                      ptr_operand,
    5788              :                                      int_operand,
    5789      5411310 :                                      complain);
    5790              :         }
    5791              :       common = 1;
    5792              :       break;
    5793              : 
    5794              :     case MULT_EXPR:
    5795    136658330 :       common = 1;
    5796              :       break;
    5797              : 
    5798     12045469 :     case TRUNC_DIV_EXPR:
    5799     12045469 :     case CEIL_DIV_EXPR:
    5800     12045469 :     case FLOOR_DIV_EXPR:
    5801     12045469 :     case ROUND_DIV_EXPR:
    5802     12045469 :     case EXACT_DIV_EXPR:
    5803     12045469 :       if (TREE_CODE (op0) == SIZEOF_EXPR && TREE_CODE (op1) == SIZEOF_EXPR)
    5804              :         {
    5805       120166 :           tree type0 = TREE_OPERAND (op0, 0);
    5806       120166 :           tree type1 = TREE_OPERAND (op1, 0);
    5807       120166 :           tree first_arg = tree_strip_any_location_wrapper (type0);
    5808       120166 :           if (!TYPE_P (type0))
    5809        79512 :             type0 = TREE_TYPE (type0);
    5810       120166 :           if (!TYPE_P (type1))
    5811        44939 :             type1 = TREE_TYPE (type1);
    5812       120166 :           if (type0
    5813       120166 :               && type1
    5814       101037 :               && INDIRECT_TYPE_P (type0)
    5815       120241 :               && same_type_p (TREE_TYPE (type0), type1))
    5816              :             {
    5817           27 :               if (!(TREE_CODE (first_arg) == PARM_DECL
    5818           21 :                     && DECL_ARRAY_PARAMETER_P (first_arg)
    5819            3 :                     && warn_sizeof_array_argument)
    5820           42 :                   && (complain & tf_warning))
    5821              :                 {
    5822           21 :                   auto_diagnostic_group d;
    5823           21 :                   if (warning_at (location, OPT_Wsizeof_pointer_div,
    5824              :                                   "division %<sizeof (%T) / sizeof (%T)%> does "
    5825              :                                   "not compute the number of array elements",
    5826              :                                   type0, type1))
    5827           18 :                     if (DECL_P (first_arg))
    5828           18 :                       inform (DECL_SOURCE_LOCATION (first_arg),
    5829              :                               "first %<sizeof%> operand was declared here");
    5830           21 :                 }
    5831              :             }
    5832       120142 :           else if (!dependent_type_p (type0)
    5833        25911 :                    && !dependent_type_p (type1)
    5834        25813 :                    && TREE_CODE (type0) == ARRAY_TYPE
    5835        21024 :                    && !char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type0)))
    5836              :                    /* Set by finish_parenthesized_expr.  */
    5837        20375 :                    && !warning_suppressed_p (op1, OPT_Wsizeof_array_div)
    5838       140499 :                    && (complain & tf_warning))
    5839        20357 :             maybe_warn_sizeof_array_div (location, first_arg, type0,
    5840              :                                          op1, non_reference (type1));
    5841              :         }
    5842              : 
    5843     12045469 :       if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
    5844              :            || code0 == COMPLEX_TYPE || code0 == VECTOR_TYPE)
    5845     12045451 :           && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
    5846              :               || code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE))
    5847              :         {
    5848     12045442 :           enum tree_code tcode0 = code0, tcode1 = code1;
    5849     12045442 :           doing_div_or_mod = true;
    5850     12045442 :           warn_for_div_by_zero (location, fold_for_warn (op1));
    5851              : 
    5852     12045442 :           if (tcode0 == COMPLEX_TYPE || tcode0 == VECTOR_TYPE)
    5853        57127 :             tcode0 = TREE_CODE (TREE_TYPE (TREE_TYPE (op0)));
    5854     12045442 :           if (tcode1 == COMPLEX_TYPE || tcode1 == VECTOR_TYPE)
    5855        29427 :             tcode1 = TREE_CODE (TREE_TYPE (TREE_TYPE (op1)));
    5856              : 
    5857     12045445 :           if (!((tcode0 == INTEGER_TYPE
    5858      5268799 :                  || (tcode0 == ENUMERAL_TYPE && code0 == VECTOR_TYPE))
    5859              :                 && (tcode1 == INTEGER_TYPE
    5860        94372 :                     || (tcode1 == ENUMERAL_TYPE && code1 == VECTOR_TYPE))))
    5861              :             resultcode = RDIV_EXPR;
    5862              :           else
    5863              :             {
    5864              :               /* When dividing two signed integers, we have to promote to int.
    5865              :                  unless we divide by a constant != -1.  Note that default
    5866              :                  conversion will have been performed on the operands at this
    5867              :                  point, so we have to dig out the original type to find out if
    5868              :                  it was unsigned.  */
    5869      6682277 :               tree stripped_op1 = tree_strip_any_location_wrapper (op1);
    5870      6682277 :               shorten = may_shorten_divmod (op0, stripped_op1);
    5871              :             }
    5872              : 
    5873              :           common = 1;
    5874              :         }
    5875              :       break;
    5876              : 
    5877      2794724 :     case BIT_AND_EXPR:
    5878      2794724 :     case BIT_IOR_EXPR:
    5879      2794724 :     case BIT_XOR_EXPR:
    5880      2794724 :       if ((code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
    5881      2794724 :           || (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE
    5882        21080 :               && !VECTOR_FLOAT_TYPE_P (type0)
    5883        21062 :               && !VECTOR_FLOAT_TYPE_P (type1)))
    5884              :         shorten = -1;
    5885              :       break;
    5886              : 
    5887      1515770 :     case TRUNC_MOD_EXPR:
    5888      1515770 :     case FLOOR_MOD_EXPR:
    5889      1515770 :       doing_div_or_mod = true;
    5890      1515770 :       warn_for_div_by_zero (location, fold_for_warn (op1));
    5891              : 
    5892      1515770 :       if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE
    5893           28 :           && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE
    5894      1515798 :           && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE)
    5895              :         common = 1;
    5896      1515742 :       else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
    5897              :         {
    5898              :           /* Although it would be tempting to shorten always here, that loses
    5899              :              on some targets, since the modulo instruction is undefined if the
    5900              :              quotient can't be represented in the computation mode.  We shorten
    5901              :              only if unsigned or if dividing by something we know != -1.  */
    5902      1515718 :           tree stripped_op1 = tree_strip_any_location_wrapper (op1);
    5903      1515718 :           shorten = may_shorten_divmod (op0, stripped_op1);
    5904      1515718 :           common = 1;
    5905              :         }
    5906              :       break;
    5907              : 
    5908     16051692 :     case TRUTH_ANDIF_EXPR:
    5909     16051692 :     case TRUTH_ORIF_EXPR:
    5910     16051692 :     case TRUTH_AND_EXPR:
    5911     16051692 :     case TRUTH_OR_EXPR:
    5912     16051692 :       if (!VECTOR_TYPE_P (type0) && gnu_vector_type_p (type1))
    5913              :         {
    5914            3 :           if (!COMPARISON_CLASS_P (op1))
    5915            3 :             op1 = cp_build_binary_op (EXPR_LOCATION (op1), NE_EXPR, op1,
    5916              :                                       build_zero_cst (type1), complain);
    5917            3 :           if (code == TRUTH_ANDIF_EXPR)
    5918              :             {
    5919            0 :               tree z = build_zero_cst (TREE_TYPE (op1));
    5920            0 :               return build_conditional_expr (location, op0, op1, z, complain);
    5921              :             }
    5922            3 :           else if (code == TRUTH_ORIF_EXPR)
    5923              :             {
    5924            3 :               tree m1 = build_all_ones_cst (TREE_TYPE (op1));
    5925            3 :               return build_conditional_expr (location, op0, m1, op1, complain);
    5926              :             }
    5927              :           else
    5928            0 :             gcc_unreachable ();
    5929              :         }
    5930     16051689 :       if (gnu_vector_type_p (type0)
    5931     16051689 :           && (!VECTOR_TYPE_P (type1) || gnu_vector_type_p (type1)))
    5932              :         {
    5933           24 :           if (!COMPARISON_CLASS_P (op0))
    5934           24 :             op0 = cp_build_binary_op (EXPR_LOCATION (op0), NE_EXPR, op0,
    5935              :                                       build_zero_cst (type0), complain);
    5936           24 :           if (!VECTOR_TYPE_P (type1))
    5937              :             {
    5938            9 :               tree m1 = build_all_ones_cst (TREE_TYPE (op0));
    5939            9 :               tree z = build_zero_cst (TREE_TYPE (op0));
    5940            9 :               op1 = build_conditional_expr (location, op1, m1, z, complain);
    5941              :             }
    5942           15 :           else if (!COMPARISON_CLASS_P (op1))
    5943           15 :             op1 = cp_build_binary_op (EXPR_LOCATION (op1), NE_EXPR, op1,
    5944              :                                       build_zero_cst (type1), complain);
    5945              : 
    5946           24 :           if (code == TRUTH_ANDIF_EXPR)
    5947              :             code = BIT_AND_EXPR;
    5948            9 :           else if (code == TRUTH_ORIF_EXPR)
    5949              :             code = BIT_IOR_EXPR;
    5950              :           else
    5951            0 :             gcc_unreachable ();
    5952              : 
    5953           24 :           return cp_build_binary_op (location, code, op0, op1, complain);
    5954              :         }
    5955              : 
    5956     16051665 :       result_type = boolean_type_node;
    5957     16051665 :       break;
    5958              : 
    5959              :       /* Shift operations: result has same type as first operand;
    5960              :          always convert second operand to int.
    5961              :          Also set SHORT_SHIFT if shifting rightward.  */
    5962              : 
    5963      1086065 :     case RSHIFT_EXPR:
    5964      1086065 :       if (gnu_vector_type_p (type0)
    5965          186 :           && code1 == INTEGER_TYPE
    5966      1086121 :           && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE)
    5967              :         {
    5968              :           result_type = type0;
    5969              :           converted = 1;
    5970              :         }
    5971      1086009 :       else if (gnu_vector_type_p (type0)
    5972          130 :                && gnu_vector_type_p (type1)
    5973          130 :                && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE
    5974          127 :                && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE
    5975      1086136 :                && known_eq (TYPE_VECTOR_SUBPARTS (type0),
    5976              :                             TYPE_VECTOR_SUBPARTS (type1)))
    5977              :         {
    5978              :           result_type = type0;
    5979              :           converted = 1;
    5980              :         }
    5981      1085882 :       else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
    5982              :         {
    5983      1085855 :           tree const_op1 = fold_for_warn (op1);
    5984      1085855 :           if (TREE_CODE (const_op1) != INTEGER_CST)
    5985       100402 :             const_op1 = op1;
    5986      1085855 :           result_type = type0;
    5987      1085855 :           doing_shift = true;
    5988      1085855 :           if (TREE_CODE (const_op1) == INTEGER_CST)
    5989              :             {
    5990       985453 :               if (tree_int_cst_lt (const_op1, integer_zero_node))
    5991              :                 {
    5992           48 :                   if ((complain & tf_warning)
    5993           48 :                       && c_inhibit_evaluation_warnings == 0)
    5994           36 :                     warning_at (location, OPT_Wshift_count_negative,
    5995              :                                 "right shift count is negative");
    5996              :                 }
    5997              :               else
    5998              :                 {
    5999       985405 :                   if (!integer_zerop (const_op1))
    6000       985191 :                     short_shift = 1;
    6001              : 
    6002       985405 :                   if (compare_tree_int (const_op1, TYPE_PRECISION (type0)) >= 0
    6003           46 :                       && (complain & tf_warning)
    6004       985451 :                       && c_inhibit_evaluation_warnings == 0)
    6005           34 :                     warning_at (location, OPT_Wshift_count_overflow,
    6006              :                                 "right shift count >= width of type");
    6007              :                 }
    6008              :             }
    6009              :           /* Avoid converting op1 to result_type later.  */
    6010              :           converted = 1;
    6011              :         }
    6012              :       break;
    6013              : 
    6014      3100523 :     case LSHIFT_EXPR:
    6015      3100523 :       if (gnu_vector_type_p (type0)
    6016          229 :           && code1 == INTEGER_TYPE
    6017      3100567 :           && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE)
    6018              :         {
    6019              :           result_type = type0;
    6020              :           converted = 1;
    6021              :         }
    6022      3100479 :       else if (gnu_vector_type_p (type0)
    6023          185 :                && gnu_vector_type_p (type1)
    6024          185 :                && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE
    6025          182 :                && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE
    6026      3100658 :                && known_eq (TYPE_VECTOR_SUBPARTS (type0),
    6027              :                             TYPE_VECTOR_SUBPARTS (type1)))
    6028              :         {
    6029              :           result_type = type0;
    6030              :           converted = 1;
    6031              :         }
    6032      3100300 :       else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
    6033              :         {
    6034      3100245 :           tree const_op0 = fold_for_warn (op0);
    6035      3100245 :           if (TREE_CODE (const_op0) != INTEGER_CST)
    6036       263209 :             const_op0 = op0;
    6037      3100245 :           tree const_op1 = fold_for_warn (op1);
    6038      3100245 :           if (TREE_CODE (const_op1) != INTEGER_CST)
    6039       217380 :             const_op1 = op1;
    6040      3100245 :           result_type = type0;
    6041      3100245 :           doing_shift = true;
    6042      3100245 :           if (TREE_CODE (const_op0) == INTEGER_CST
    6043      2837036 :               && tree_int_cst_sgn (const_op0) < 0
    6044          280 :               && !TYPE_OVERFLOW_WRAPS (type0)
    6045          196 :               && (complain & tf_warning)
    6046      3100441 :               && c_inhibit_evaluation_warnings == 0)
    6047          196 :             warning_at (location, OPT_Wshift_negative_value,
    6048              :                         "left shift of negative value");
    6049      3100245 :           if (TREE_CODE (const_op1) == INTEGER_CST)
    6050              :             {
    6051      2882865 :               if (tree_int_cst_lt (const_op1, integer_zero_node))
    6052              :                 {
    6053           57 :                   if ((complain & tf_warning)
    6054           57 :                       && c_inhibit_evaluation_warnings == 0)
    6055           39 :                     warning_at (location, OPT_Wshift_count_negative,
    6056              :                                 "left shift count is negative");
    6057              :                 }
    6058      2882808 :               else if (compare_tree_int (const_op1,
    6059      2882808 :                                          TYPE_PRECISION (type0)) >= 0)
    6060              :                 {
    6061           83 :                   if ((complain & tf_warning)
    6062           61 :                       && c_inhibit_evaluation_warnings == 0)
    6063           45 :                     warning_at (location, OPT_Wshift_count_overflow,
    6064              :                                 "left shift count >= width of type");
    6065              :                 }
    6066      2882725 :               else if (TREE_CODE (const_op0) == INTEGER_CST
    6067      2657372 :                        && (complain & tf_warning))
    6068      2550898 :                 maybe_warn_shift_overflow (location, const_op0, const_op1);
    6069              :             }
    6070              :           /* Avoid converting op1 to result_type later.  */
    6071              :           converted = 1;
    6072              :         }
    6073              :       break;
    6074              : 
    6075     25647331 :     case EQ_EXPR:
    6076     25647331 :     case NE_EXPR:
    6077     25647331 :       if (gnu_vector_type_p (type0) && gnu_vector_type_p (type1))
    6078         2957 :         goto vector_compare;
    6079     25644374 :       if ((complain & tf_warning)
    6080     22681872 :           && c_inhibit_evaluation_warnings == 0
    6081     47234125 :           && (FLOAT_TYPE_P (type0) || FLOAT_TYPE_P (type1)))
    6082       792430 :         warning_at (location, OPT_Wfloat_equal,
    6083              :                     "comparing floating-point with %<==%> "
    6084              :                     "or %<!=%> is unsafe");
    6085     25644374 :       {
    6086     25644374 :         tree stripped_orig_op0 = tree_strip_any_location_wrapper (orig_op0);
    6087     25644374 :         tree stripped_orig_op1 = tree_strip_any_location_wrapper (orig_op1);
    6088     25644374 :         if ((complain & tf_warning_or_error)
    6089     25644374 :             && ((TREE_CODE (stripped_orig_op0) == STRING_CST
    6090           39 :                  && !integer_zerop (cp_fully_fold (op1)))
    6091     23141655 :                 || (TREE_CODE (stripped_orig_op1) == STRING_CST
    6092           68 :                     && !integer_zerop (cp_fully_fold (op0)))))
    6093           47 :           warning_at (location, OPT_Waddress,
    6094              :                       "comparison with string literal results in "
    6095              :                       "unspecified behavior");
    6096     25644327 :         else if (TREE_CODE (TREE_TYPE (orig_op0)) == ARRAY_TYPE
    6097     25644327 :                  && TREE_CODE (TREE_TYPE (orig_op1)) == ARRAY_TYPE)
    6098              :           {
    6099              :             /* P2865R5 made array comparisons ill-formed in C++26.  */
    6100           68 :             if (complain & tf_warning_or_error)
    6101           45 :               do_warn_array_compare (location, code, stripped_orig_op0,
    6102              :                                      stripped_orig_op1);
    6103           23 :             else if (cxx_dialect >= cxx26)
    6104            1 :               return error_mark_node;
    6105              :           }
    6106              :       }
    6107              : 
    6108     25644373 :       build_type = boolean_type_node;
    6109     25644373 :       if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
    6110              :            || code0 == COMPLEX_TYPE || code0 == ENUMERAL_TYPE)
    6111     21498110 :           && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
    6112              :               || code1 == COMPLEX_TYPE || code1 == ENUMERAL_TYPE))
    6113              :         short_compare = 1;
    6114        39083 :       else if (((code0 == POINTER_TYPE || TYPE_PTRDATAMEM_P (type0))
    6115      4143577 :                 && null_ptr_cst_p (orig_op1))
    6116              :                /* Handle, eg, (void*)0 (c++/43906), and more.  */
    6117      6638087 :                || (code0 == POINTER_TYPE
    6118      2417651 :                    && TYPE_PTR_P (type1) && integer_zerop (op1)))
    6119              :         {
    6120      1744136 :           if (TYPE_PTR_P (type1))
    6121        18595 :             result_type = composite_pointer_type (location,
    6122              :                                                   type0, type1, op0, op1,
    6123              :                                                   CPO_COMPARISON, complain);
    6124              :           else
    6125              :             result_type = type0;
    6126              : 
    6127      1744136 :           if (char_type_p (TREE_TYPE (orig_op1)))
    6128              :             {
    6129           10 :               auto_diagnostic_group d;
    6130           10 :               if (warning_at (location, OPT_Wpointer_compare,
    6131              :                               "comparison between pointer and zero character "
    6132              :                               "constant"))
    6133           10 :                 inform (location,
    6134              :                         "did you mean to dereference the pointer?");
    6135           10 :             }
    6136      1744136 :           warn_for_null_address (location, op0, complain);
    6137              :         }
    6138         3141 :       else if (((code1 == POINTER_TYPE || TYPE_PTRDATAMEM_P (type1))
    6139      2434946 :                 && null_ptr_cst_p (orig_op0))
    6140              :                /* Handle, eg, (void*)0 (c++/43906), and more.  */
    6141      4874463 :                || (code1 == POINTER_TYPE
    6142      2433668 :                    && TYPE_PTR_P (type0) && integer_zerop (op0)))
    6143              :         {
    6144          961 :           if (TYPE_PTR_P (type0))
    6145           68 :             result_type = composite_pointer_type (location,
    6146              :                                                   type0, type1, op0, op1,
    6147              :                                                   CPO_COMPARISON, complain);
    6148              :           else
    6149              :             result_type = type1;
    6150              : 
    6151          961 :           if (char_type_p (TREE_TYPE (orig_op0)))
    6152              :             {
    6153           10 :               auto_diagnostic_group d;
    6154           10 :               if (warning_at (location, OPT_Wpointer_compare,
    6155              :                              "comparison between pointer and zero character "
    6156              :                              "constant"))
    6157           10 :                 inform (location,
    6158              :                         "did you mean to dereference the pointer?");
    6159           10 :             }
    6160          961 :           warn_for_null_address (location, op1, complain);
    6161              :         }
    6162      2436717 :       else if ((code0 == POINTER_TYPE && code1 == POINTER_TYPE)
    6163        37787 :                || (TYPE_PTRDATAMEM_P (type0) && TYPE_PTRDATAMEM_P (type1)))
    6164      2399315 :         result_type = composite_pointer_type (location,
    6165              :                                               type0, type1, op0, op1,
    6166              :                                               CPO_COMPARISON, complain);
    6167        37402 :       else if (null_ptr_cst_p (orig_op0) && null_ptr_cst_p (orig_op1))
    6168              :         /* One of the operands must be of nullptr_t type.  */
    6169           67 :         result_type = TREE_TYPE (nullptr_node);
    6170        37335 :       else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
    6171              :         {
    6172           58 :           result_type = type0;
    6173           58 :           if (complain & tf_error)
    6174           56 :             permerror (location, "ISO C++ forbids comparison between "
    6175              :                        "pointer and integer");
    6176              :           else
    6177            2 :             return error_mark_node;
    6178              :         }
    6179        37277 :       else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
    6180              :         {
    6181        34670 :           result_type = type1;
    6182        34670 :           if (complain & tf_error)
    6183           69 :             permerror (location, "ISO C++ forbids comparison between "
    6184              :                        "pointer and integer");
    6185              :           else
    6186        34601 :             return error_mark_node;
    6187              :         }
    6188         2607 :       else if (TYPE_PTRMEMFUNC_P (type0) && null_ptr_cst_p (orig_op1))
    6189              :         {
    6190          212 :           if (TARGET_PTRMEMFUNC_VBIT_LOCATION
    6191              :               == ptrmemfunc_vbit_in_delta)
    6192              :             {
    6193              :               tree pfn0, delta0, e1, e2;
    6194              : 
    6195              :               if (TREE_SIDE_EFFECTS (op0))
    6196              :                 op0 = cp_save_expr (op0);
    6197              : 
    6198              :               pfn0 = pfn_from_ptrmemfunc (op0);
    6199              :               delta0 = delta_from_ptrmemfunc (op0);
    6200              :               {
    6201              :                 /* If we will warn below about a null-address compare
    6202              :                    involving the orig_op0 ptrmemfunc, we'd likely also
    6203              :                    warn about the pfn0's null-address compare, and
    6204              :                    that would be redundant, so suppress it.  */
    6205              :                 warning_sentinel ws (warn_address);
    6206              :                 e1 = cp_build_binary_op (location,
    6207              :                                          EQ_EXPR,
    6208              :                                          pfn0,
    6209              :                                          build_zero_cst (TREE_TYPE (pfn0)),
    6210              :                                          complain);
    6211              :               }
    6212              :               e2 = cp_build_binary_op (location,
    6213              :                                        BIT_AND_EXPR,
    6214              :                                        delta0,
    6215              :                                        integer_one_node,
    6216              :                                        complain);
    6217              : 
    6218              :               if (complain & tf_warning)
    6219              :                 maybe_warn_zero_as_null_pointer_constant (op1, input_location);
    6220              : 
    6221              :               e2 = cp_build_binary_op (location,
    6222              :                                        EQ_EXPR, e2, integer_zero_node,
    6223              :                                        complain);
    6224              :               op0 = cp_build_binary_op (location,
    6225              :                                         TRUTH_ANDIF_EXPR, e1, e2,
    6226              :                                         complain);
    6227              :               op1 = cp_convert (TREE_TYPE (op0), integer_one_node, complain);
    6228              :             }
    6229              :           else
    6230              :             {
    6231          212 :               op0 = build_ptrmemfunc_access_expr (op0, pfn_identifier);
    6232          212 :               op1 = cp_convert (TREE_TYPE (op0), op1, complain);
    6233              :             }
    6234          212 :           result_type = TREE_TYPE (op0);
    6235              : 
    6236          212 :           warn_for_null_address (location, orig_op0, complain);
    6237              :         }
    6238         2395 :       else if (TYPE_PTRMEMFUNC_P (type1) && null_ptr_cst_p (orig_op0))
    6239           36 :         return cp_build_binary_op (location, code, op1, op0, complain);
    6240         2359 :       else if (TYPE_PTRMEMFUNC_P (type0) && TYPE_PTRMEMFUNC_P (type1))
    6241              :         {
    6242          125 :           tree type;
    6243              :           /* E will be the final comparison.  */
    6244          125 :           tree e;
    6245              :           /* E1 and E2 are for scratch.  */
    6246          125 :           tree e1;
    6247          125 :           tree e2;
    6248          125 :           tree pfn0;
    6249          125 :           tree pfn1;
    6250          125 :           tree delta0;
    6251          125 :           tree delta1;
    6252              : 
    6253          125 :           type = composite_pointer_type (location, type0, type1, op0, op1,
    6254              :                                          CPO_COMPARISON, complain);
    6255              : 
    6256          125 :           if (!same_type_p (TREE_TYPE (op0), type))
    6257            6 :             op0 = cp_convert_and_check (type, op0, complain);
    6258          125 :           if (!same_type_p (TREE_TYPE (op1), type))
    6259            9 :             op1 = cp_convert_and_check (type, op1, complain);
    6260              : 
    6261          125 :           if (op0 == error_mark_node || op1 == error_mark_node)
    6262              :             return error_mark_node;
    6263              : 
    6264          122 :           if (TREE_SIDE_EFFECTS (op0))
    6265           61 :             op0 = cp_save_expr (op0);
    6266          122 :           if (TREE_SIDE_EFFECTS (op1))
    6267            3 :             op1 = cp_save_expr (op1);
    6268              : 
    6269          122 :           pfn0 = pfn_from_ptrmemfunc (op0);
    6270          122 :           pfn0 = cp_fully_fold (pfn0);
    6271              :           /* Avoid -Waddress warnings (c++/64877).  */
    6272          122 :           if (TREE_CODE (pfn0) == ADDR_EXPR)
    6273           16 :             suppress_warning (pfn0, OPT_Waddress);
    6274          122 :           pfn1 = pfn_from_ptrmemfunc (op1);
    6275          122 :           pfn1 = cp_fully_fold (pfn1);
    6276          122 :           delta0 = delta_from_ptrmemfunc (op0);
    6277          122 :           delta1 = delta_from_ptrmemfunc (op1);
    6278          122 :           if (TARGET_PTRMEMFUNC_VBIT_LOCATION
    6279              :               == ptrmemfunc_vbit_in_delta)
    6280              :             {
    6281              :               /* We generate:
    6282              : 
    6283              :                  (op0.pfn == op1.pfn
    6284              :                   && ((op0.delta == op1.delta)
    6285              :                        || (!op0.pfn && op0.delta & 1 == 0
    6286              :                            && op1.delta & 1 == 0))
    6287              : 
    6288              :                  The reason for the `!op0.pfn' bit is that a NULL
    6289              :                  pointer-to-member is any member with a zero PFN and
    6290              :                  LSB of the DELTA field is 0.  */
    6291              : 
    6292              :               e1 = cp_build_binary_op (location, BIT_AND_EXPR,
    6293              :                                        delta0,
    6294              :                                        integer_one_node,
    6295              :                                        complain);
    6296              :               e1 = cp_build_binary_op (location,
    6297              :                                        EQ_EXPR, e1, integer_zero_node,
    6298              :                                        complain);
    6299              :               e2 = cp_build_binary_op (location, BIT_AND_EXPR,
    6300              :                                        delta1,
    6301              :                                        integer_one_node,
    6302              :                                        complain);
    6303              :               e2 = cp_build_binary_op (location,
    6304              :                                        EQ_EXPR, e2, integer_zero_node,
    6305              :                                        complain);
    6306              :               e1 = cp_build_binary_op (location,
    6307              :                                        TRUTH_ANDIF_EXPR, e2, e1,
    6308              :                                        complain);
    6309              :               e2 = cp_build_binary_op (location, EQ_EXPR,
    6310              :                                        pfn0,
    6311              :                                        build_zero_cst (TREE_TYPE (pfn0)),
    6312              :                                        complain);
    6313              :               e2 = cp_build_binary_op (location,
    6314              :                                        TRUTH_ANDIF_EXPR, e2, e1, complain);
    6315              :               e1 = cp_build_binary_op (location,
    6316              :                                        EQ_EXPR, delta0, delta1, complain);
    6317              :               e1 = cp_build_binary_op (location,
    6318              :                                        TRUTH_ORIF_EXPR, e1, e2, complain);
    6319              :             }
    6320              :           else
    6321              :             {
    6322              :               /* We generate:
    6323              : 
    6324              :                  (op0.pfn == op1.pfn
    6325              :                  && (!op0.pfn || op0.delta == op1.delta))
    6326              : 
    6327              :                  The reason for the `!op0.pfn' bit is that a NULL
    6328              :                  pointer-to-member is any member with a zero PFN; the
    6329              :                  DELTA field is unspecified.  */
    6330              : 
    6331          122 :               e1 = cp_build_binary_op (location,
    6332              :                                        EQ_EXPR, delta0, delta1, complain);
    6333          122 :               e2 = cp_build_binary_op (location,
    6334              :                                        EQ_EXPR,
    6335              :                                        pfn0,
    6336          122 :                                        build_zero_cst (TREE_TYPE (pfn0)),
    6337              :                                        complain);
    6338          122 :               e1 = cp_build_binary_op (location,
    6339              :                                        TRUTH_ORIF_EXPR, e1, e2, complain);
    6340              :             }
    6341          122 :           e2 = build2 (EQ_EXPR, boolean_type_node, pfn0, pfn1);
    6342          122 :           e = cp_build_binary_op (location,
    6343              :                                   TRUTH_ANDIF_EXPR, e2, e1, complain);
    6344          122 :           if (code == EQ_EXPR)
    6345              :             return e;
    6346           30 :           return cp_build_binary_op (location,
    6347           30 :                                      EQ_EXPR, e, integer_zero_node, complain);
    6348              :         }
    6349              :       /* [expr.eq]: "If both operands are of type std::meta::info,
    6350              :          comparison is defined as follows..."  */
    6351         2234 :       else if (code0 == META_TYPE && code1 == META_TYPE)
    6352              :         result_type = type0;
    6353              :       else
    6354              :         {
    6355           22 :           gcc_assert (!TYPE_PTRMEMFUNC_P (type0)
    6356              :                       || !same_type_p (TYPE_PTRMEMFUNC_FN_TYPE (type0),
    6357              :                                        type1));
    6358           22 :           gcc_assert (!TYPE_PTRMEMFUNC_P (type1)
    6359              :                       || !same_type_p (TYPE_PTRMEMFUNC_FN_TYPE (type1),
    6360              :                                        type0));
    6361              :         }
    6362              : 
    6363              :       break;
    6364              : 
    6365          241 :     case MAX_EXPR:
    6366          241 :     case MIN_EXPR:
    6367          241 :       if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
    6368          241 :            && (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
    6369              :         shorten = 1;
    6370            0 :       else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
    6371            0 :         result_type = composite_pointer_type (location,
    6372              :                                               type0, type1, op0, op1,
    6373              :                                               CPO_COMPARISON, complain);
    6374              :       break;
    6375              : 
    6376     25485193 :     case LE_EXPR:
    6377     25485193 :     case GE_EXPR:
    6378     25485193 :     case LT_EXPR:
    6379     25485193 :     case GT_EXPR:
    6380     25485193 :     case SPACESHIP_EXPR:
    6381     25485193 :       if (TREE_CODE (orig_op0) == STRING_CST
    6382     25485193 :           || TREE_CODE (orig_op1) == STRING_CST)
    6383              :         {
    6384            0 :           if (complain & tf_warning)
    6385            0 :             warning_at (location, OPT_Waddress,
    6386              :                         "comparison with string literal results "
    6387              :                         "in unspecified behavior");
    6388              :         }
    6389     25485193 :       else if (TREE_CODE (TREE_TYPE (orig_op0)) == ARRAY_TYPE
    6390          164 :                && TREE_CODE (TREE_TYPE (orig_op1)) == ARRAY_TYPE
    6391     25485308 :                && code != SPACESHIP_EXPR)
    6392              :         {
    6393           96 :           if (complain & tf_warning_or_error)
    6394           51 :             do_warn_array_compare (location, code,
    6395              :                                    tree_strip_any_location_wrapper (orig_op0),
    6396              :                                    tree_strip_any_location_wrapper (orig_op1));
    6397           45 :           else if (cxx_dialect >= cxx26)
    6398            1 :             return error_mark_node;
    6399              :         }
    6400              : 
    6401     25485192 :       if (gnu_vector_type_p (type0) && gnu_vector_type_p (type1))
    6402              :         {
    6403         7692 :         vector_compare:
    6404         7692 :           tree intt;
    6405         7692 :           if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (type0),
    6406         7692 :                                                           TREE_TYPE (type1))
    6407         7692 :               && !vector_types_compatible_elements_p (type0, type1))
    6408              :             {
    6409            3 :               if (complain & tf_error)
    6410              :                 {
    6411            3 :                   auto_diagnostic_group d;
    6412            3 :                   error_at (location, "comparing vectors with different "
    6413              :                                       "element types");
    6414            3 :                   inform (location, "operand types are %qT and %qT",
    6415              :                           type0, type1);
    6416            3 :                 }
    6417            3 :               return error_mark_node;
    6418              :             }
    6419              : 
    6420         7689 :           if (maybe_ne (TYPE_VECTOR_SUBPARTS (type0),
    6421        15378 :                         TYPE_VECTOR_SUBPARTS (type1)))
    6422              :             {
    6423            3 :               if (complain & tf_error)
    6424              :                 {
    6425            3 :                   auto_diagnostic_group d;
    6426            3 :                   error_at (location, "comparing vectors with different "
    6427              :                                       "number of elements");
    6428            3 :                   inform (location, "operand types are %qT and %qT",
    6429              :                           type0, type1);
    6430            3 :                 }
    6431            3 :               return error_mark_node;
    6432              :             }
    6433              : 
    6434              :           /* It's not precisely specified how the usual arithmetic
    6435              :              conversions apply to the vector types.  Here, we use
    6436              :              the unsigned type if one of the operands is signed and
    6437              :              the other one is unsigned.  */
    6438         7686 :           if (TYPE_UNSIGNED (type0) != TYPE_UNSIGNED (type1))
    6439              :             {
    6440           36 :               if (!TYPE_UNSIGNED (type0))
    6441           36 :                 op0 = build1 (VIEW_CONVERT_EXPR, type1, op0);
    6442              :               else
    6443            0 :                 op1 = build1 (VIEW_CONVERT_EXPR, type0, op1);
    6444           36 :               warning_at (location, OPT_Wsign_compare, "comparison between "
    6445              :                           "types %qT and %qT", type0, type1);
    6446              :             }
    6447              : 
    6448         7686 :           if (resultcode == SPACESHIP_EXPR)
    6449              :             {
    6450            3 :               if (complain & tf_error)
    6451            3 :                 sorry_at (location, "three-way comparison of vectors");
    6452            3 :               return error_mark_node;
    6453              :             }
    6454              : 
    6455         7683 :           if (VECTOR_BOOLEAN_TYPE_P (type0) && VECTOR_BOOLEAN_TYPE_P (type1))
    6456              :             result_type = type0;
    6457              :           else
    6458              :             {
    6459              :               /* Always construct signed integer vector type.  */
    6460         7683 :               auto intmode = SCALAR_TYPE_MODE (TREE_TYPE (type0));
    6461         7683 :               auto nelts = TYPE_VECTOR_SUBPARTS (type0);
    6462              : 
    6463        15366 :               intt = c_common_type_for_size (GET_MODE_BITSIZE (intmode), 0);
    6464         7683 :               if (!intt)
    6465              :                 {
    6466            0 :                   if (complain & tf_error)
    6467            0 :                     error_at (location, "could not find an integer type "
    6468            0 :                                 "of the same size as %qT", TREE_TYPE (type0));
    6469            0 :                   return error_mark_node;
    6470              :                 }
    6471         7683 :               result_type = build_opaque_vector_type (intt, nelts);
    6472              :             }
    6473         7683 :           return build_vec_cmp (resultcode, result_type, op0, op1);
    6474              :         }
    6475     25480457 :       build_type = boolean_type_node;
    6476     25480457 :       if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
    6477              :            || code0 == ENUMERAL_TYPE)
    6478     22716464 :            && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
    6479              :                || code1 == ENUMERAL_TYPE))
    6480              :         short_compare = 1;
    6481      2764096 :       else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
    6482      2763819 :         result_type = composite_pointer_type (location,
    6483              :                                               type0, type1, op0, op1,
    6484              :                                               CPO_COMPARISON, complain);
    6485           73 :       else if ((code0 == POINTER_TYPE && null_ptr_cst_p (orig_op1))
    6486          205 :                || (code1 == POINTER_TYPE && null_ptr_cst_p (orig_op0))
    6487          428 :                || (null_ptr_cst_p (orig_op0) && null_ptr_cst_p (orig_op1)))
    6488              :         {
    6489              :           /* Core Issue 1512 made this ill-formed.  */
    6490          190 :           if (complain & tf_error)
    6491          186 :             error_at (location, "ordered comparison of pointer with "
    6492              :                       "integer zero (%qT and %qT)", type0, type1);
    6493          190 :           return error_mark_node;
    6494              :         }
    6495           87 :       else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
    6496              :         {
    6497            0 :           result_type = type0;
    6498            0 :           if (complain & tf_error)
    6499            0 :             permerror (location, "ISO C++ forbids comparison between "
    6500              :                        "pointer and integer");
    6501              :           else
    6502            0 :             return error_mark_node;
    6503              :         }
    6504           87 :       else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
    6505              :         {
    6506           24 :           result_type = type1;
    6507           24 :           if (complain & tf_error)
    6508           24 :             permerror (location, "ISO C++ forbids comparison between "
    6509              :                        "pointer and integer");
    6510              :           else
    6511            0 :             return error_mark_node;
    6512              :         }
    6513              : 
    6514     25480267 :       if ((code0 == POINTER_TYPE || code1 == POINTER_TYPE)
    6515      2763844 :           && !processing_template_decl
    6516     28031088 :           && sanitize_flags_p (SANITIZE_POINTER_COMPARE))
    6517              :         {
    6518           49 :           op0 = cp_save_expr (op0);
    6519           49 :           op1 = cp_save_expr (op1);
    6520              : 
    6521           49 :           tree tt = builtin_decl_explicit (BUILT_IN_ASAN_POINTER_COMPARE);
    6522           49 :           instrument_expr = build_call_expr_loc (location, tt, 2, op0, op1);
    6523              :         }
    6524              : 
    6525              :       break;
    6526              : 
    6527            0 :     case UNORDERED_EXPR:
    6528            0 :     case ORDERED_EXPR:
    6529            0 :     case UNLT_EXPR:
    6530            0 :     case UNLE_EXPR:
    6531            0 :     case UNGT_EXPR:
    6532            0 :     case UNGE_EXPR:
    6533            0 :     case UNEQ_EXPR:
    6534            0 :       build_type = integer_type_node;
    6535            0 :       if (code0 != REAL_TYPE || code1 != REAL_TYPE)
    6536              :         {
    6537            0 :           if (complain & tf_error)
    6538            0 :             error ("unordered comparison on non-floating-point argument");
    6539            0 :           return error_mark_node;
    6540              :         }
    6541              :       common = 1;
    6542              :       break;
    6543              : 
    6544              :     default:
    6545              :       break;
    6546              :     }
    6547              : 
    6548    136658330 :   if (((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE
    6549              :         || code0 == ENUMERAL_TYPE)
    6550    111992728 :        && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
    6551              :            || code1 == COMPLEX_TYPE || code1 == ENUMERAL_TYPE)))
    6552              :     arithmetic_types_p = 1;
    6553              :   else
    6554              :     {
    6555     25065788 :       arithmetic_types_p = 0;
    6556              :       /* Vector arithmetic is only allowed when both sides are vectors.  */
    6557     25065788 :       if (gnu_vector_type_p (type0) && gnu_vector_type_p (type1))
    6558              :         {
    6559        60305 :           if (!tree_int_cst_equal (TYPE_SIZE (type0), TYPE_SIZE (type1))
    6560        60305 :               || !vector_types_compatible_elements_p (type0, type1))
    6561              :             {
    6562           18 :               if (complain & tf_error)
    6563              :                 {
    6564              :                   /* "location" already embeds the locations of the
    6565              :                      operands, so we don't need to add them separately
    6566              :                      to richloc.  */
    6567           18 :                   rich_location richloc (line_table, location);
    6568           18 :                   binary_op_error (&richloc, code, type0, type1);
    6569           18 :                 }
    6570           18 :               return error_mark_node;
    6571              :             }
    6572              :           arithmetic_types_p = 1;
    6573              :         }
    6574              :     }
    6575              :   /* Determine the RESULT_TYPE, if it is not already known.  */
    6576    136658312 :   if (!result_type
    6577    136658312 :       && arithmetic_types_p
    6578    107333059 :       && (shorten || common || short_compare))
    6579              :     {
    6580    107332958 :       result_type = cp_common_type (type0, type1);
    6581    107332958 :       if (result_type == error_mark_node)
    6582              :         {
    6583            6 :           tree t1 = type0;
    6584            6 :           tree t2 = type1;
    6585            6 :           if (TREE_CODE (t1) == COMPLEX_TYPE)
    6586            0 :             t1 = TREE_TYPE (t1);
    6587            6 :           if (TREE_CODE (t2) == COMPLEX_TYPE)
    6588            0 :             t2 = TREE_TYPE (t2);
    6589            6 :           gcc_checking_assert (TREE_CODE (t1) == REAL_TYPE
    6590              :                                && TREE_CODE (t2) == REAL_TYPE
    6591              :                                && (extended_float_type_p (t1)
    6592              :                                    || extended_float_type_p (t2))
    6593              :                                && cp_compare_floating_point_conversion_ranks
    6594              :                                     (t1, t2) == 3);
    6595            6 :           if (complain & tf_error)
    6596              :             {
    6597            6 :               rich_location richloc (line_table, location);
    6598            6 :               binary_op_error (&richloc, code, type0, type1);
    6599            6 :             }
    6600            6 :           return error_mark_node;
    6601              :         }
    6602    107332952 :       if (complain & tf_warning)
    6603     97466282 :         do_warn_double_promotion (result_type, type0, type1,
    6604              :                                   "implicit conversion from %qH to %qI "
    6605              :                                   "to match other operand of binary "
    6606              :                                   "expression", location);
    6607    107332952 :       if (do_warn_enum_conversions (location, code, TREE_TYPE (orig_op0),
    6608    107332952 :                                     TREE_TYPE (orig_op1), complain))
    6609            6 :         return error_mark_node;
    6610              :     }
    6611    136658300 :   if (may_need_excess_precision
    6612    101210012 :       && (orig_type0 != type0 || orig_type1 != type1)
    6613        41629 :       && build_type == NULL_TREE
    6614        41629 :       && result_type)
    6615              :     {
    6616        31872 :       gcc_assert (common);
    6617        31872 :       semantic_result_type = cp_common_type (orig_type0, orig_type1);
    6618        31872 :       if (semantic_result_type == error_mark_node)
    6619              :         {
    6620            0 :           tree t1 = orig_type0;
    6621            0 :           tree t2 = orig_type1;
    6622            0 :           if (TREE_CODE (t1) == COMPLEX_TYPE)
    6623            0 :             t1 = TREE_TYPE (t1);
    6624            0 :           if (TREE_CODE (t2) == COMPLEX_TYPE)
    6625            0 :             t2 = TREE_TYPE (t2);
    6626            0 :           gcc_checking_assert (TREE_CODE (t1) == REAL_TYPE
    6627              :                                && TREE_CODE (t2) == REAL_TYPE
    6628              :                                && (extended_float_type_p (t1)
    6629              :                                    || extended_float_type_p (t2))
    6630              :                                && cp_compare_floating_point_conversion_ranks
    6631              :                                     (t1, t2) == 3);
    6632            0 :           if (complain & tf_error)
    6633              :             {
    6634            0 :               rich_location richloc (line_table, location);
    6635            0 :               binary_op_error (&richloc, code, type0, type1);
    6636            0 :             }
    6637            0 :           return error_mark_node;
    6638              :         }
    6639              :     }
    6640              : 
    6641    136658300 :   if (code == SPACESHIP_EXPR)
    6642              :     {
    6643       639593 :       iloc_sentinel s (location);
    6644              : 
    6645       639593 :       tree orig_type0 = TREE_TYPE (orig_op0);
    6646       639593 :       tree_code orig_code0 = TREE_CODE (orig_type0);
    6647       639593 :       tree orig_type1 = TREE_TYPE (orig_op1);
    6648       639593 :       tree_code orig_code1 = TREE_CODE (orig_type1);
    6649       639593 :       if (!result_type || result_type == error_mark_node)
    6650              :         /* Nope.  */
    6651              :         result_type = NULL_TREE;
    6652       639572 :       else if ((orig_code0 == BOOLEAN_TYPE) != (orig_code1 == BOOLEAN_TYPE))
    6653              :         /* "If one of the operands is of type bool and the other is not, the
    6654              :            program is ill-formed."  */
    6655              :         result_type = NULL_TREE;
    6656       639569 :       else if (code0 == POINTER_TYPE && orig_code0 != POINTER_TYPE
    6657           19 :                && code1 == POINTER_TYPE && orig_code1 != POINTER_TYPE)
    6658              :         /* We only do array/function-to-pointer conversion if "at least one of
    6659              :            the operands is of pointer type".  */
    6660              :         result_type = NULL_TREE;
    6661       639550 :       else if (TYPE_PTRFN_P (result_type) || NULLPTR_TYPE_P (result_type))
    6662              :         /* <=> no longer supports equality relations.  */
    6663              :         result_type = NULL_TREE;
    6664       639547 :       else if (orig_code0 == ENUMERAL_TYPE && orig_code1 == ENUMERAL_TYPE
    6665       639577 :                && !(same_type_ignoring_top_level_qualifiers_p
    6666           30 :                     (orig_type0, orig_type1)))
    6667              :         /* "If both operands have arithmetic types, or one operand has integral
    6668              :            type and the other operand has unscoped enumeration type, the usual
    6669              :            arithmetic conversions are applied to the operands."  So we don't do
    6670              :            arithmetic conversions if the operands both have enumeral type.  */
    6671              :         result_type = NULL_TREE;
    6672       639532 :       else if ((orig_code0 == ENUMERAL_TYPE && orig_code1 == REAL_TYPE)
    6673       639526 :                || (orig_code0 == REAL_TYPE && orig_code1 == ENUMERAL_TYPE))
    6674              :         /* [depr.arith.conv.enum]: Three-way comparisons between such operands
    6675              :            [where one is of enumeration type and the other is of a different
    6676              :            enumeration type or a floating-point type] are ill-formed.  */
    6677              :         result_type = NULL_TREE;
    6678              : 
    6679       639520 :       if (result_type)
    6680              :         {
    6681       639520 :           build_type = spaceship_type (result_type, complain);
    6682       639520 :           if (build_type == error_mark_node)
    6683              :             return error_mark_node;
    6684              :         }
    6685              : 
    6686       639578 :       if (result_type && arithmetic_types_p)
    6687              :         {
    6688              :           /* If a narrowing conversion is required, other than from an integral
    6689              :              type to a floating point type, the program is ill-formed.  */
    6690       275727 :           bool ok = true;
    6691       275727 :           if (TREE_CODE (result_type) == REAL_TYPE
    6692          550 :               && CP_INTEGRAL_TYPE_P (orig_type0))
    6693              :             /* OK */;
    6694       275720 :           else if (!check_narrowing (result_type, orig_op0, complain))
    6695       275727 :             ok = false;
    6696       275727 :           if (TREE_CODE (result_type) == REAL_TYPE
    6697          550 :               && CP_INTEGRAL_TYPE_P (orig_type1))
    6698              :             /* OK */;
    6699       275720 :           else if (!check_narrowing (result_type, orig_op1, complain))
    6700              :             ok = false;
    6701       275727 :           if (!ok && !(complain & tf_error))
    6702            2 :             return error_mark_node;
    6703              :         }
    6704       639593 :     }
    6705              : 
    6706    136658283 :   if (!result_type)
    6707              :     {
    6708          550 :       if (complain & tf_error)
    6709              :         {
    6710          210 :           binary_op_rich_location richloc (location,
    6711          210 :                                            orig_op0, orig_op1, true);
    6712          210 :           error_at (&richloc,
    6713              :                     "invalid operands of types %qT and %qT to binary %qO",
    6714          210 :                     TREE_TYPE (orig_op0), TREE_TYPE (orig_op1), code);
    6715          210 :         }
    6716          550 :       return error_mark_node;
    6717              :     }
    6718              : 
    6719              :   /* If we're in a template, the only thing we need to know is the
    6720              :      RESULT_TYPE.  */
    6721    136657733 :   if (processing_template_decl)
    6722              :     {
    6723              :       /* Since the middle-end checks the type when doing a build2, we
    6724              :          need to build the tree in pieces.  This built tree will never
    6725              :          get out of the front-end as we replace it when instantiating
    6726              :          the template.  */
    6727     61415120 :       tree tmp = build2 (resultcode,
    6728              :                          build_type ? build_type : result_type,
    6729              :                          NULL_TREE, op1);
    6730     38660424 :       TREE_OPERAND (tmp, 0) = op0;
    6731     38660424 :       if (semantic_result_type)
    6732            0 :         tmp = build1 (EXCESS_PRECISION_EXPR, semantic_result_type, tmp);
    6733     38660424 :       return tmp;
    6734              :     }
    6735              : 
    6736              :   /* Remember the original type; RESULT_TYPE might be changed later on
    6737              :      by shorten_binary_op.  */
    6738     97997309 :   tree orig_type = result_type;
    6739              : 
    6740     97997309 :   if (arithmetic_types_p)
    6741              :     {
    6742     83871251 :       bool first_complex = (code0 == COMPLEX_TYPE);
    6743     83871251 :       bool second_complex = (code1 == COMPLEX_TYPE);
    6744     83871251 :       int none_complex = (!first_complex && !second_complex);
    6745              : 
    6746              :       /* Adapted from patch for c/24581.  */
    6747     83871251 :       if (first_complex != second_complex
    6748       157573 :           && (code == PLUS_EXPR
    6749              :               || code == MINUS_EXPR
    6750       157573 :               || code == MULT_EXPR
    6751        41213 :               || (code == TRUNC_DIV_EXPR && first_complex))
    6752       144066 :           && TREE_CODE (TREE_TYPE (result_type)) == REAL_TYPE
    6753     84015156 :           && flag_signed_zeros)
    6754              :         {
    6755              :           /* An operation on mixed real/complex operands must be
    6756              :              handled specially, but the language-independent code can
    6757              :              more easily optimize the plain complex arithmetic if
    6758              :              -fno-signed-zeros.  */
    6759       143905 :           tree real_type = TREE_TYPE (result_type);
    6760       143905 :           tree real, imag;
    6761       143905 :           if (first_complex)
    6762              :             {
    6763       110857 :               if (TREE_TYPE (op0) != result_type)
    6764            6 :                 op0 = cp_convert_and_check (result_type, op0, complain);
    6765       110857 :               if (TREE_TYPE (op1) != real_type)
    6766           26 :                 op1 = cp_convert_and_check (real_type, op1, complain);
    6767              :             }
    6768              :           else
    6769              :             {
    6770        33048 :               if (TREE_TYPE (op0) != real_type)
    6771           31 :                 op0 = cp_convert_and_check (real_type, op0, complain);
    6772        33048 :               if (TREE_TYPE (op1) != result_type)
    6773           32 :                 op1 = cp_convert_and_check (result_type, op1, complain);
    6774              :             }
    6775       143905 :           if (TREE_CODE (op0) == ERROR_MARK || TREE_CODE (op1) == ERROR_MARK)
    6776            0 :             return error_mark_node;
    6777       143905 :           if (first_complex)
    6778              :             {
    6779       110857 :               op0 = cp_save_expr (op0);
    6780       110857 :               real = cp_build_unary_op (REALPART_EXPR, op0, true, complain);
    6781       110857 :               imag = cp_build_unary_op (IMAGPART_EXPR, op0, true, complain);
    6782       110857 :               switch (code)
    6783              :                 {
    6784        55405 :                 case MULT_EXPR:
    6785        55405 :                 case TRUNC_DIV_EXPR:
    6786        55405 :                   op1 = cp_save_expr (op1);
    6787        55405 :                   imag = build2 (resultcode, real_type, imag, op1);
    6788              :                   /* Fall through.  */
    6789       110857 :                 case PLUS_EXPR:
    6790       110857 :                 case MINUS_EXPR:
    6791       110857 :                   real = build2 (resultcode, real_type, real, op1);
    6792       110857 :                   break;
    6793            0 :                 default:
    6794            0 :                   gcc_unreachable();
    6795              :                 }
    6796              :             }
    6797              :           else
    6798              :             {
    6799        33048 :               op1 = cp_save_expr (op1);
    6800        33048 :               real = cp_build_unary_op (REALPART_EXPR, op1, true, complain);
    6801        33048 :               imag = cp_build_unary_op (IMAGPART_EXPR, op1, true, complain);
    6802        33048 :               switch (code)
    6803              :                 {
    6804          638 :                 case MULT_EXPR:
    6805          638 :                   op0 = cp_save_expr (op0);
    6806          638 :                   imag = build2 (resultcode, real_type, op0, imag);
    6807              :                   /* Fall through.  */
    6808        17301 :                 case PLUS_EXPR:
    6809        17301 :                   real = build2 (resultcode, real_type, op0, real);
    6810        17301 :                   break;
    6811        15747 :                 case MINUS_EXPR:
    6812        15747 :                   real = build2 (resultcode, real_type, op0, real);
    6813        15747 :                   imag = build1 (NEGATE_EXPR, real_type, imag);
    6814        15747 :                   break;
    6815            0 :                 default:
    6816            0 :                   gcc_unreachable();
    6817              :                 }
    6818              :             }
    6819       143905 :           result = build2 (COMPLEX_EXPR, result_type, real, imag);
    6820       143905 :           if (semantic_result_type)
    6821           24 :             result = build1 (EXCESS_PRECISION_EXPR, semantic_result_type,
    6822              :                              result);
    6823       143905 :           return result;
    6824              :         }
    6825              : 
    6826              :       /* For certain operations (which identify themselves by shorten != 0)
    6827              :          if both args were extended from the same smaller type,
    6828              :          do the arithmetic in that type and then extend.
    6829              : 
    6830              :          shorten !=0 and !=1 indicates a bitwise operation.
    6831              :          For them, this optimization is safe only if
    6832              :          both args are zero-extended or both are sign-extended.
    6833              :          Otherwise, we might change the result.
    6834              :          E.g., (short)-1 | (unsigned short)-1 is (int)-1
    6835              :          but calculated in (unsigned short) it would be (unsigned short)-1.  */
    6836              : 
    6837     83727346 :       if (shorten && none_complex)
    6838              :         {
    6839      6760814 :           final_type = result_type;
    6840      6760814 :           result_type = shorten_binary_op (result_type, op0, op1,
    6841              :                                            shorten == -1);
    6842              :         }
    6843              : 
    6844              :       /* Shifts can be shortened if shifting right.  */
    6845              : 
    6846     83727346 :       if (short_shift)
    6847              :         {
    6848       817800 :           int unsigned_arg;
    6849       817800 :           tree arg0 = get_narrower (op0, &unsigned_arg);
    6850              :           /* We're not really warning here but when we set short_shift we
    6851              :              used fold_for_warn to fold the operand.  */
    6852       817800 :           tree const_op1 = fold_for_warn (op1);
    6853              : 
    6854       817800 :           final_type = result_type;
    6855              : 
    6856       817800 :           if (arg0 == op0 && final_type == TREE_TYPE (op0))
    6857       742272 :             unsigned_arg = TYPE_UNSIGNED (TREE_TYPE (op0));
    6858              : 
    6859       817800 :           if (TYPE_PRECISION (TREE_TYPE (arg0)) < TYPE_PRECISION (result_type)
    6860         2160 :               && tree_int_cst_sgn (const_op1) > 0
    6861              :               /* We can shorten only if the shift count is less than the
    6862              :                  number of bits in the smaller type size.  */
    6863         2160 :               && compare_tree_int (const_op1,
    6864         2160 :                                    TYPE_PRECISION (TREE_TYPE (arg0))) < 0
    6865              :               /* We cannot drop an unsigned shift after sign-extension.  */
    6866       819935 :               && (!TYPE_UNSIGNED (final_type) || unsigned_arg))
    6867              :             {
    6868              :               /* Do an unsigned shift if the operand was zero-extended.  */
    6869         2128 :               result_type
    6870         2128 :                 = c_common_signed_or_unsigned_type (unsigned_arg,
    6871         2128 :                                                     TREE_TYPE (arg0));
    6872              :               /* Convert value-to-be-shifted to that type.  */
    6873         2128 :               if (TREE_TYPE (op0) != result_type)
    6874         2128 :                 op0 = convert (result_type, op0);
    6875              :               converted = 1;
    6876              :             }
    6877              :         }
    6878              : 
    6879              :       /* Comparison operations are shortened too but differently.
    6880              :          They identify themselves by setting short_compare = 1.  */
    6881              : 
    6882     83727346 :       if (short_compare)
    6883              :         {
    6884              :           /* We call shorten_compare only for diagnostics.  */
    6885     28700813 :           tree xop0 = fold_simple (op0);
    6886     28700813 :           tree xop1 = fold_simple (op1);
    6887     28700813 :           tree xresult_type = result_type;
    6888     28700813 :           enum tree_code xresultcode = resultcode;
    6889     28700813 :           shorten_compare (location, &xop0, &xop1, &xresult_type,
    6890              :                            &xresultcode);
    6891              :         }
    6892              : 
    6893     55026446 :       if ((short_compare || code == MIN_EXPR || code == MAX_EXPR)
    6894     28701002 :           && warn_sign_compare
    6895              :           /* Do not warn until the template is instantiated; we cannot
    6896              :              bound the ranges of the arguments until that point.  */
    6897       342145 :           && !processing_template_decl
    6898       342145 :           && (complain & tf_warning)
    6899       334117 :           && c_inhibit_evaluation_warnings == 0
    6900              :           /* Even unsigned enum types promote to signed int.  We don't
    6901              :              want to issue -Wsign-compare warnings for this case.  */
    6902       317635 :           && !enum_cast_to_int (orig_op0)
    6903     84044981 :           && !enum_cast_to_int (orig_op1))
    6904              :         {
    6905       317628 :           warn_for_sign_compare (location, orig_op0, orig_op1, op0, op1,
    6906              :                                  result_type, resultcode);
    6907              :         }
    6908              :     }
    6909              : 
    6910              :   /* If CONVERTED is zero, both args will be converted to type RESULT_TYPE.
    6911              :      Then the expression will be built.
    6912              :      It will be given type FINAL_TYPE if that is nonzero;
    6913              :      otherwise, it will be given type RESULT_TYPE.  */
    6914     97853404 :   if (! converted)
    6915              :     {
    6916     94223411 :       warning_sentinel w (warn_sign_conversion, short_compare);
    6917     94223411 :       if (!same_type_p (TREE_TYPE (op0), result_type))
    6918      4104693 :         op0 = cp_convert_and_check (result_type, op0, complain);
    6919     94223411 :       if (!same_type_p (TREE_TYPE (op1), result_type))
    6920     17966089 :         op1 = cp_convert_and_check (result_type, op1, complain);
    6921              : 
    6922     94223411 :       if (op0 == error_mark_node || op1 == error_mark_node)
    6923           58 :         return error_mark_node;
    6924     94223411 :     }
    6925              : 
    6926     97853346 :   if (build_type == NULL_TREE)
    6927     62669403 :     build_type = result_type;
    6928              : 
    6929     97853346 :   if (doing_shift
    6930      3629347 :       && flag_strong_eval_order == 2
    6931      3531057 :       && TREE_SIDE_EFFECTS (op1)
    6932     97874202 :       && !processing_template_decl)
    6933              :     {
    6934              :       /* In C++17, in both op0 << op1 and op0 >> op1 op0 is sequenced before
    6935              :          op1, so if op1 has side-effects, use SAVE_EXPR around op0.  */
    6936        20856 :       op0 = cp_save_expr (op0);
    6937        20856 :       instrument_expr = op0;
    6938              :     }
    6939              : 
    6940     97853346 :   if (sanitize_flags_p ((SANITIZE_SHIFT
    6941              :                          | SANITIZE_DIVIDE
    6942              :                          | SANITIZE_FLOAT_DIVIDE
    6943              :                          | SANITIZE_SI_OVERFLOW))
    6944        13322 :       && current_function_decl != NULL_TREE
    6945        10919 :       && !processing_template_decl
    6946     97864265 :       && (doing_div_or_mod || doing_shift))
    6947              :     {
    6948              :       /* OP0 and/or OP1 might have side-effects.  */
    6949          924 :       op0 = cp_save_expr (op0);
    6950          924 :       op1 = cp_save_expr (op1);
    6951          924 :       op0 = fold_non_dependent_expr (op0, complain);
    6952          924 :       op1 = fold_non_dependent_expr (op1, complain);
    6953          924 :       tree instrument_expr1 = NULL_TREE;
    6954          924 :       if (doing_div_or_mod
    6955          924 :           && sanitize_flags_p (SANITIZE_DIVIDE
    6956              :                                | SANITIZE_FLOAT_DIVIDE
    6957              :                                | SANITIZE_SI_OVERFLOW))
    6958              :         {
    6959              :           /* For diagnostics we want to use the promoted types without
    6960              :              shorten_binary_op.  So convert the arguments to the
    6961              :              original result_type.  */
    6962          465 :           tree cop0 = op0;
    6963          465 :           tree cop1 = op1;
    6964          465 :           if (TREE_TYPE (cop0) != orig_type)
    6965            6 :             cop0 = cp_convert (orig_type, op0, complain);
    6966          465 :           if (TREE_TYPE (cop1) != orig_type)
    6967           39 :             cop1 = cp_convert (orig_type, op1, complain);
    6968          465 :           instrument_expr1 = ubsan_instrument_division (location, cop0, cop1);
    6969              :         }
    6970          459 :       else if (doing_shift && sanitize_flags_p (SANITIZE_SHIFT))
    6971          378 :         instrument_expr1 = ubsan_instrument_shift (location, code, op0, op1);
    6972          924 :       if (instrument_expr != NULL)
    6973           18 :         instrument_expr = add_stmt_to_compound (instrument_expr,
    6974              :                                                 instrument_expr1);
    6975              :       else
    6976          906 :         instrument_expr = instrument_expr1;
    6977              :     }
    6978              : 
    6979     97853346 :   result = build2_loc (location, resultcode, build_type, op0, op1);
    6980     97853346 :   if (final_type != 0)
    6981      7578614 :     result = cp_convert (final_type, result, complain);
    6982              : 
    6983     97853346 :   if (instrument_expr != NULL)
    6984        21354 :     result = build2 (COMPOUND_EXPR, TREE_TYPE (result),
    6985              :                      instrument_expr, result);
    6986              : 
    6987     97853346 :   if (resultcode == SPACESHIP_EXPR && !processing_template_decl)
    6988       547144 :     result = get_target_expr (result, complain);
    6989              : 
    6990     97853346 :   if (semantic_result_type)
    6991        31848 :     result = build1 (EXCESS_PRECISION_EXPR, semantic_result_type, result);
    6992              : 
    6993     97853346 :   if (!c_inhibit_evaluation_warnings)
    6994              :     {
    6995     82571580 :       if (!processing_template_decl)
    6996              :         {
    6997     82571580 :           op0 = cp_fully_fold (op0);
    6998              :           /* Only consider the second argument if the first isn't overflowed.  */
    6999     82571580 :           if (!CONSTANT_CLASS_P (op0) || TREE_OVERFLOW_P (op0))
    7000              :             return result;
    7001     23099810 :           op1 = cp_fully_fold (op1);
    7002     23099810 :           if (!CONSTANT_CLASS_P (op1) || TREE_OVERFLOW_P (op1))
    7003              :             return result;
    7004              :         }
    7005            0 :       else if (!CONSTANT_CLASS_P (op0) || !CONSTANT_CLASS_P (op1)
    7006            0 :                || TREE_OVERFLOW_P (op0) || TREE_OVERFLOW_P (op1))
    7007              :         return result;
    7008              : 
    7009     17782675 :       tree result_ovl = fold_build2 (resultcode, build_type, op0, op1);
    7010     17782675 :       if (TREE_OVERFLOW_P (result_ovl))
    7011          190 :         overflow_warning (location, result_ovl);
    7012              :     }
    7013              : 
    7014              :   return result;
    7015              : }
    7016              : 
    7017              : /* Build a VEC_PERM_EXPR.
    7018              :    This is a simple wrapper for c_build_vec_perm_expr.  */
    7019              : tree
    7020        17586 : build_x_vec_perm_expr (location_t loc,
    7021              :                         tree arg0, tree arg1, tree arg2,
    7022              :                         tsubst_flags_t complain)
    7023              : {
    7024        17586 :   tree orig_arg0 = arg0;
    7025        17586 :   tree orig_arg1 = arg1;
    7026        17586 :   tree orig_arg2 = arg2;
    7027        17586 :   if (processing_template_decl)
    7028              :     {
    7029           19 :       if (type_dependent_expression_p (arg0)
    7030           13 :           || type_dependent_expression_p (arg1)
    7031           32 :           || type_dependent_expression_p (arg2))
    7032            6 :         return build_min_nt_loc (loc, VEC_PERM_EXPR, arg0, arg1, arg2);
    7033              :     }
    7034        17580 :   tree exp = c_build_vec_perm_expr (loc, arg0, arg1, arg2, complain & tf_error);
    7035        17580 :   if (processing_template_decl && exp != error_mark_node)
    7036           13 :     return build_min_non_dep (VEC_PERM_EXPR, exp, orig_arg0,
    7037           13 :                               orig_arg1, orig_arg2);
    7038              :   return exp;
    7039              : }
    7040              : 
    7041              : /* Build a VEC_PERM_EXPR.
    7042              :    This is a simple wrapper for c_build_shufflevector.  */
    7043              : tree
    7044        41953 : build_x_shufflevector (location_t loc, vec<tree, va_gc> *args,
    7045              :                        tsubst_flags_t complain)
    7046              : {
    7047        41953 :   tree arg0 = (*args)[0];
    7048        41953 :   tree arg1 = (*args)[1];
    7049        41953 :   if (processing_template_decl)
    7050              :     {
    7051          355 :       for (unsigned i = 0; i < args->length (); ++i)
    7052          339 :         if (i <= 1
    7053          339 :             ? type_dependent_expression_p ((*args)[i])
    7054           61 :             : instantiation_dependent_expression_p ((*args)[i]))
    7055              :           {
    7056          243 :             tree exp = build_min_nt_call_vec (NULL, args);
    7057          243 :             CALL_EXPR_IFN (exp) = IFN_SHUFFLEVECTOR;
    7058          243 :             return exp;
    7059              :           }
    7060              :     }
    7061        41710 :   auto_vec<tree, 16> mask;
    7062       564442 :   for (unsigned i = 2; i < args->length (); ++i)
    7063              :     {
    7064       522732 :       tree idx = fold_non_dependent_expr ((*args)[i], complain);
    7065       522732 :       mask.safe_push (idx);
    7066              :     }
    7067        41710 :   tree exp = c_build_shufflevector (loc, arg0, arg1, mask, complain & tf_error);
    7068        41710 :   if (processing_template_decl && exp != error_mark_node)
    7069              :     {
    7070           16 :       exp = build_min_non_dep_call_vec (exp, NULL, args);
    7071           16 :       CALL_EXPR_IFN (exp) = IFN_SHUFFLEVECTOR;
    7072              :     }
    7073        41710 :   return exp;
    7074        41710 : }
    7075              : 
    7076              : /* Return a tree for the sum or difference (RESULTCODE says which)
    7077              :    of pointer PTROP and integer INTOP.  */
    7078              : 
    7079              : static tree
    7080      5411310 : cp_pointer_int_sum (location_t loc, enum tree_code resultcode, tree ptrop,
    7081              :                     tree intop, tsubst_flags_t complain)
    7082              : {
    7083      5411310 :   tree res_type = TREE_TYPE (ptrop);
    7084              : 
    7085              :   /* pointer_int_sum() uses size_in_bytes() on the TREE_TYPE(res_type)
    7086              :      in certain circumstance (when it's valid to do so).  So we need
    7087              :      to make sure it's complete.  We don't need to check here, if we
    7088              :      can actually complete it at all, as those checks will be done in
    7089              :      pointer_int_sum() anyway.  */
    7090      5411310 :   complete_type (TREE_TYPE (res_type));
    7091              : 
    7092      5411310 :   return pointer_int_sum (loc, resultcode, ptrop,
    7093      5411310 :                           intop, complain & tf_warning_or_error);
    7094              : }
    7095              : 
    7096              : /* Return a tree for the difference of pointers OP0 and OP1.
    7097              :    The resulting tree has type int.  If POINTER_SUBTRACT sanitization is
    7098              :    enabled, assign to INSTRUMENT_EXPR call to libsanitizer.  */
    7099              : 
    7100              : static tree
    7101      1470482 : pointer_diff (location_t loc, tree op0, tree op1, tree ptrtype,
    7102              :               tsubst_flags_t complain, tree *instrument_expr)
    7103              : {
    7104      1470482 :   tree result, inttype;
    7105      1470482 :   tree restype = ptrdiff_type_node;
    7106      1470482 :   tree target_type = TREE_TYPE (ptrtype);
    7107              : 
    7108      1470482 :   if (!complete_type_or_maybe_complain (target_type, NULL_TREE, complain))
    7109            9 :     return error_mark_node;
    7110              : 
    7111      1470473 :   if (VOID_TYPE_P (target_type))
    7112              :     {
    7113            0 :       if (complain & tf_error)
    7114            0 :         permerror (loc, "ISO C++ forbids using pointer of "
    7115              :                    "type %<void *%> in subtraction");
    7116              :       else
    7117            0 :         return error_mark_node;
    7118              :     }
    7119      1470473 :   if (TREE_CODE (target_type) == FUNCTION_TYPE)
    7120              :     {
    7121            9 :       if (complain & tf_error)
    7122            3 :         permerror (loc, "ISO C++ forbids using pointer to "
    7123              :                    "a function in subtraction");
    7124              :       else
    7125            6 :         return error_mark_node;
    7126              :     }
    7127      1470467 :   if (TREE_CODE (target_type) == METHOD_TYPE)
    7128              :     {
    7129            0 :       if (complain & tf_error)
    7130            0 :         permerror (loc, "ISO C++ forbids using pointer to "
    7131              :                    "a method in subtraction");
    7132              :       else
    7133            0 :         return error_mark_node;
    7134              :     }
    7135      2940934 :   else if (!verify_type_context (loc, TCTX_POINTER_ARITH,
    7136      1470467 :                                  TREE_TYPE (TREE_TYPE (op0)),
    7137              :                                  !(complain & tf_error))
    7138      2940934 :            || !verify_type_context (loc, TCTX_POINTER_ARITH,
    7139      1470467 :                                     TREE_TYPE (TREE_TYPE (op1)),
    7140              :                                     !(complain & tf_error)))
    7141            0 :     return error_mark_node;
    7142              : 
    7143              :   /* Determine integer type result of the subtraction.  This will usually
    7144              :      be the same as the result type (ptrdiff_t), but may need to be a wider
    7145              :      type if pointers for the address space are wider than ptrdiff_t.  */
    7146      1470467 :   if (TYPE_PRECISION (restype) < TYPE_PRECISION (TREE_TYPE (op0)))
    7147            0 :     inttype = c_common_type_for_size (TYPE_PRECISION (TREE_TYPE (op0)), 0);
    7148              :   else
    7149              :     inttype = restype;
    7150              : 
    7151      1470467 :   if (!processing_template_decl
    7152      1470467 :       && sanitize_flags_p (SANITIZE_POINTER_SUBTRACT))
    7153              :     {
    7154           84 :       op0 = save_expr (op0);
    7155           84 :       op1 = save_expr (op1);
    7156              : 
    7157           84 :       tree tt = builtin_decl_explicit (BUILT_IN_ASAN_POINTER_SUBTRACT);
    7158           84 :       *instrument_expr = build_call_expr_loc (loc, tt, 2, op0, op1);
    7159              :     }
    7160              : 
    7161              :   /* First do the subtraction, then build the divide operator
    7162              :      and only convert at the very end.
    7163              :      Do not do default conversions in case restype is a short type.  */
    7164              : 
    7165              :   /* POINTER_DIFF_EXPR requires a signed integer type of the same size as
    7166              :      pointers.  If some platform cannot provide that, or has a larger
    7167              :      ptrdiff_type to support differences larger than half the address
    7168              :      space, cast the pointers to some larger integer type and do the
    7169              :      computations in that type.  */
    7170      1470467 :   if (TYPE_PRECISION (inttype) > TYPE_PRECISION (TREE_TYPE (op0)))
    7171            0 :     op0 = cp_build_binary_op (loc,
    7172              :                               MINUS_EXPR,
    7173              :                               cp_convert (inttype, op0, complain),
    7174              :                               cp_convert (inttype, op1, complain),
    7175              :                               complain);
    7176              :   else
    7177      1470467 :     op0 = build2_loc (loc, POINTER_DIFF_EXPR, inttype, op0, op1);
    7178              : 
    7179              :   /* This generates an error if op1 is a pointer to an incomplete type.  */
    7180      1470467 :   if (!COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (op1))))
    7181              :     {
    7182            0 :       if (complain & tf_error)
    7183            0 :         error_at (loc, "invalid use of a pointer to an incomplete type in "
    7184              :                   "pointer arithmetic");
    7185              :       else
    7186            0 :         return error_mark_node;
    7187              :     }
    7188              : 
    7189      1470467 :   if (pointer_to_zero_sized_aggr_p (TREE_TYPE (op1)))
    7190              :     {
    7191           15 :       if (complain & tf_error)
    7192           15 :         error_at (loc, "arithmetic on pointer to an empty aggregate");
    7193              :       else
    7194            0 :         return error_mark_node;
    7195              :     }
    7196              : 
    7197      2940931 :   op1 = (TYPE_PTROB_P (ptrtype)
    7198      2940931 :          ? size_in_bytes_loc (loc, target_type)
    7199              :          : integer_one_node);
    7200              : 
    7201              :   /* Do the division.  */
    7202              : 
    7203      1470467 :   result = build2_loc (loc, EXACT_DIV_EXPR, inttype, op0,
    7204              :                        cp_convert (inttype, op1, complain));
    7205      1470467 :   return cp_convert (restype, result, complain);
    7206              : }
    7207              : 
    7208              : /* Construct and perhaps optimize a tree representation
    7209              :    for a unary operation.  CODE, a tree_code, specifies the operation
    7210              :    and XARG is the operand.  */
    7211              : 
    7212              : tree
    7213     62866956 : build_x_unary_op (location_t loc, enum tree_code code, cp_expr xarg,
    7214              :                   tree lookups, tsubst_flags_t complain)
    7215              : {
    7216     62866956 :   tree orig_expr = xarg;
    7217     62866956 :   tree exp;
    7218     62866956 :   int ptrmem = 0;
    7219     62866956 :   tree overload = NULL_TREE;
    7220              : 
    7221     62866956 :   if (processing_template_decl)
    7222              :     {
    7223     42774487 :       if (type_dependent_expression_p (xarg))
    7224              :         {
    7225     27909695 :           tree e = build_min_nt_loc (loc, code, xarg.get_value (), NULL_TREE);
    7226     27909695 :           TREE_TYPE (e) = build_dependent_operator_type (lookups, code, false);
    7227     27909695 :           return e;
    7228              :         }
    7229              :     }
    7230              : 
    7231     34957261 :   exp = NULL_TREE;
    7232              : 
    7233              :   /* [expr.unary.op] says:
    7234              : 
    7235              :        The address of an object of incomplete type can be taken.
    7236              : 
    7237              :      (And is just the ordinary address operator, not an overloaded
    7238              :      "operator &".)  However, if the type is a template
    7239              :      specialization, we must complete the type at this point so that
    7240              :      an overloaded "operator &" will be available if required.  */
    7241     34957261 :   if (code == ADDR_EXPR
    7242      4071590 :       && TREE_CODE (xarg) != TEMPLATE_ID_EXPR
    7243     39028443 :       && ((CLASS_TYPE_P (TREE_TYPE (xarg))
    7244      1791284 :            && !COMPLETE_TYPE_P (complete_type (TREE_TYPE (xarg))))
    7245      4062083 :           || (TREE_CODE (xarg) == OFFSET_REF)))
    7246              :     /* Don't look for a function.  */;
    7247              :   else
    7248     34886311 :     exp = build_new_op (loc, code, LOOKUP_NORMAL, xarg, NULL_TREE,
    7249              :                         NULL_TREE, lookups, &overload, complain);
    7250              : 
    7251     34957261 :   if (!exp && code == ADDR_EXPR)
    7252              :     {
    7253      4071276 :       if (is_overloaded_fn (xarg))
    7254              :         {
    7255       372588 :           tree fn = get_first_fn (xarg);
    7256       745176 :           if (DECL_CONSTRUCTOR_P (fn) || DECL_DESTRUCTOR_P (fn))
    7257              :             {
    7258           12 :               if (complain & tf_error)
    7259           21 :                 error_at (loc, DECL_CONSTRUCTOR_P (fn)
    7260              :                           ? G_("taking address of constructor %qD")
    7261              :                           : G_("taking address of destructor %qD"),
    7262              :                           fn);
    7263           12 :               return error_mark_node;
    7264              :             }
    7265              :         }
    7266              : 
    7267              :       /* A pointer to member-function can be formed only by saying
    7268              :          &X::mf.  */
    7269      4071258 :       if (!flag_ms_extensions && TREE_CODE (TREE_TYPE (xarg)) == METHOD_TYPE
    7270      4129548 :           && (TREE_CODE (xarg) != OFFSET_REF || !PTRMEM_OK_P (xarg)))
    7271              :         {
    7272            9 :           if (TREE_CODE (xarg) != OFFSET_REF
    7273            9 :               || !TYPE_P (TREE_OPERAND (xarg, 0)))
    7274              :             {
    7275            9 :               if (complain & tf_error)
    7276              :                 {
    7277            9 :                   auto_diagnostic_group d;
    7278            9 :                   error_at (loc, "invalid use of %qE to form a "
    7279              :                             "pointer-to-member-function", xarg.get_value ());
    7280            9 :                   if (TREE_CODE (xarg) != OFFSET_REF)
    7281            6 :                     inform (loc, "  a qualified-id is required");
    7282            9 :                 }
    7283            9 :               return error_mark_node;
    7284              :             }
    7285              :           else
    7286              :             {
    7287            0 :               if (complain & tf_error)
    7288            0 :                 error_at (loc, "parentheses around %qE cannot be used to "
    7289              :                           "form a pointer-to-member-function",
    7290              :                           xarg.get_value ());
    7291              :               else
    7292            0 :                 return error_mark_node;
    7293            0 :               PTRMEM_OK_P (xarg) = 1;
    7294              :             }
    7295              :         }
    7296              : 
    7297      4071255 :       if (TREE_CODE (xarg) == OFFSET_REF)
    7298              :         {
    7299        61836 :           ptrmem = PTRMEM_OK_P (xarg);
    7300              : 
    7301            0 :           if (!ptrmem && !flag_ms_extensions
    7302        61836 :               && TREE_CODE (TREE_TYPE (TREE_OPERAND (xarg, 1))) == METHOD_TYPE)
    7303              :             {
    7304              :               /* A single non-static member, make sure we don't allow a
    7305              :                  pointer-to-member.  */
    7306            0 :               xarg = build2 (OFFSET_REF, TREE_TYPE (xarg),
    7307            0 :                              TREE_OPERAND (xarg, 0),
    7308            0 :                              ovl_make (TREE_OPERAND (xarg, 1)));
    7309            0 :               PTRMEM_OK_P (xarg) = ptrmem;
    7310              :             }
    7311              :         }
    7312              : 
    7313      8142510 :       exp = cp_build_addr_expr_strict (xarg, complain);
    7314              : 
    7315      4071255 :       if (TREE_CODE (exp) == PTRMEM_CST)
    7316        60834 :         PTRMEM_CST_LOCATION (exp) = loc;
    7317              :       else
    7318      4010421 :         protected_set_expr_location (exp, loc);
    7319              :     }
    7320              : 
    7321     34957240 :   if (processing_template_decl && exp != error_mark_node)
    7322              :     {
    7323     14864641 :       if (overload != NULL_TREE)
    7324       205173 :         return (build_min_non_dep_op_overload
    7325       205173 :                 (code, exp, overload, orig_expr, integer_zero_node));
    7326              : 
    7327     14659468 :       exp = build_min_non_dep (code, exp, orig_expr,
    7328              :                                /*For {PRE,POST}{INC,DEC}REMENT_EXPR*/NULL_TREE);
    7329              :     }
    7330     34752067 :   if (TREE_CODE (exp) == ADDR_EXPR)
    7331      3275048 :     PTRMEM_OK_P (exp) = ptrmem;
    7332              :   return exp;
    7333              : }
    7334              : 
    7335              : /* Construct and perhaps optimize a tree representation
    7336              :    for __builtin_addressof operation.  ARG specifies the operand.  */
    7337              : 
    7338              : tree
    7339       651533 : cp_build_addressof (location_t loc, tree arg, tsubst_flags_t complain)
    7340              : {
    7341       651533 :   tree orig_expr = arg;
    7342              : 
    7343       651533 :   if (processing_template_decl)
    7344              :     {
    7345       164204 :       if (type_dependent_expression_p (arg))
    7346       164204 :         return build_min_nt_loc (loc, ADDRESSOF_EXPR, arg, NULL_TREE);
    7347              :     }
    7348              : 
    7349       974658 :   tree exp = cp_build_addr_expr_strict (arg, complain);
    7350              : 
    7351       487329 :   if (processing_template_decl && exp != error_mark_node)
    7352            0 :     exp = build_min_non_dep (ADDRESSOF_EXPR, exp, orig_expr, NULL_TREE);
    7353              :   return exp;
    7354              : }
    7355              : 
    7356              : /* Like c_common_truthvalue_conversion, but handle pointer-to-member
    7357              :    constants, where a null value is represented by an INTEGER_CST of
    7358              :    -1.  */
    7359              : 
    7360              : tree
    7361      7842010 : cp_truthvalue_conversion (tree expr, tsubst_flags_t complain)
    7362              : {
    7363      7842010 :   tree type = TREE_TYPE (expr);
    7364      7842010 :   location_t loc = cp_expr_loc_or_input_loc (expr);
    7365      6613327 :   if (TYPE_PTR_OR_PTRMEM_P (type)
    7366              :       /* Avoid ICE on invalid use of non-static member function.  */
    7367     14455050 :       || TREE_CODE (expr) == FUNCTION_DECL)
    7368      1228970 :     return cp_build_binary_op (loc, NE_EXPR, expr, nullptr_node, complain);
    7369              :   else
    7370      6613040 :     return c_common_truthvalue_conversion (loc, expr);
    7371              : }
    7372              : 
    7373              : /* Returns EXPR contextually converted to bool.  */
    7374              : 
    7375              : tree
    7376     74890044 : contextual_conv_bool (tree expr, tsubst_flags_t complain)
    7377              : {
    7378     74890044 :   return perform_implicit_conversion_flags (boolean_type_node, expr,
    7379     74890044 :                                             complain, LOOKUP_NORMAL);
    7380              : }
    7381              : 
    7382              : /* Just like cp_truthvalue_conversion, but we want a CLEANUP_POINT_EXPR.  This
    7383              :    is a low-level function; most callers should use maybe_convert_cond.  */
    7384              : 
    7385              : tree
    7386     50886948 : condition_conversion (tree expr)
    7387              : {
    7388     50886948 :   tree t = contextual_conv_bool (expr, tf_warning_or_error);
    7389     50886948 :   if (!processing_template_decl)
    7390     25082907 :     t = fold_build_cleanup_point_expr (boolean_type_node, t);
    7391     50886948 :   return t;
    7392              : }
    7393              : 
    7394              : /* Returns the address of T.  This function will fold away
    7395              :    ADDR_EXPR of INDIRECT_REF.  This is only for low-level usage;
    7396              :    most places should use cp_build_addr_expr instead.  */
    7397              : 
    7398              : tree
    7399    336599696 : build_address (tree t)
    7400              : {
    7401    336599696 :   if (error_operand_p (t) || !cxx_mark_addressable (t))
    7402           24 :     return error_mark_node;
    7403    336599672 :   gcc_checking_assert (TREE_CODE (t) != CONSTRUCTOR
    7404              :                        || processing_template_decl);
    7405    336599672 :   t = build_fold_addr_expr_loc (EXPR_LOCATION (t), t);
    7406    336599672 :   if (TREE_CODE (t) != ADDR_EXPR)
    7407     59651956 :     t = rvalue (t);
    7408              :   return t;
    7409              : }
    7410              : 
    7411              : /* Return a NOP_EXPR converting EXPR to TYPE.  */
    7412              : 
    7413              : tree
    7414    562652556 : build_nop (tree type, tree expr MEM_STAT_DECL)
    7415              : {
    7416    562652556 :   if (type == error_mark_node || error_operand_p (expr))
    7417              :     return expr;
    7418    562652482 :   return build1_loc (EXPR_LOCATION (expr), NOP_EXPR, type, expr PASS_MEM_STAT);
    7419              : }
    7420              : 
    7421              : /* Take the address of ARG, whatever that means under C++ semantics.
    7422              :    If STRICT_LVALUE is true, require an lvalue; otherwise, allow xvalues
    7423              :    and class rvalues as well.
    7424              : 
    7425              :    Nothing should call this function directly; instead, callers should use
    7426              :    cp_build_addr_expr or cp_build_addr_expr_strict.  */
    7427              : 
    7428              : static tree
    7429    260723019 : cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain)
    7430              : {
    7431    260723019 :   tree argtype;
    7432    260723019 :   tree val;
    7433              : 
    7434    260723019 :   if (!arg || error_operand_p (arg))
    7435           12 :     return error_mark_node;
    7436              : 
    7437    260723007 :   arg = mark_lvalue_use (arg);
    7438    260723007 :   if (error_operand_p (arg))
    7439            3 :     return error_mark_node;
    7440              : 
    7441    260723004 :   argtype = lvalue_type (arg);
    7442    260723004 :   location_t loc = cp_expr_loc_or_input_loc (arg);
    7443              : 
    7444    260723004 :   gcc_assert (!(identifier_p (arg) && IDENTIFIER_ANY_OP_P (arg)));
    7445              : 
    7446     15443512 :   if (TREE_CODE (arg) == COMPONENT_REF && type_unknown_p (arg)
    7447    260723198 :       && !really_overloaded_fn (arg))
    7448              :     {
    7449              :       /* They're trying to take the address of a unique non-static
    7450              :          member function.  This is ill-formed (except in MS-land),
    7451              :          but let's try to DTRT.
    7452              :          Note: We only handle unique functions here because we don't
    7453              :          want to complain if there's a static overload; non-unique
    7454              :          cases will be handled by instantiate_type.  But we need to
    7455              :          handle this case here to allow casts on the resulting PMF.
    7456              :          We could defer this in non-MS mode, but it's easier to give
    7457              :          a useful error here.  */
    7458              : 
    7459              :       /* Inside constant member functions, the `this' pointer
    7460              :          contains an extra const qualifier.  TYPE_MAIN_VARIANT
    7461              :          is used here to remove this const from the diagnostics
    7462              :          and the created OFFSET_REF.  */
    7463           70 :       tree base = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (arg, 0)));
    7464           70 :       tree fn = get_first_fn (TREE_OPERAND (arg, 1));
    7465           70 :       if (!mark_used (fn, complain) && !(complain & tf_error))
    7466            0 :         return error_mark_node;
    7467              :       /* Until microsoft headers are known to incorrectly take the address of
    7468              :          unqualified xobj member functions we should not support this
    7469              :          extension.
    7470              :          See comment in class.cc:resolve_address_of_overloaded_function for
    7471              :          the extended reasoning.  */
    7472           70 :       if (!flag_ms_extensions || DECL_XOBJ_MEMBER_FUNCTION_P (fn))
    7473              :         {
    7474           64 :           auto_diagnostic_group d;
    7475           64 :           tree name = DECL_NAME (fn);
    7476           64 :           if (!(complain & tf_error))
    7477            0 :             return error_mark_node;
    7478           64 :           else if (current_class_type
    7479           64 :                    && TREE_OPERAND (arg, 0) == current_class_ref)
    7480              :             /* An expression like &memfn.  */
    7481           31 :             if (!DECL_XOBJ_MEMBER_FUNCTION_P (fn))
    7482           21 :               permerror (loc,
    7483              :                          "ISO C++ forbids taking the address of an unqualified"
    7484              :                          " or parenthesized non-static member function to form"
    7485              :                          " a pointer to member function.  Say %<&%T::%D%>",
    7486              :                          base, name);
    7487              :             else
    7488           10 :               error_at (loc,
    7489              :                         "ISO C++ forbids taking the address of an unqualified"
    7490              :                         " or parenthesized non-static member function to form"
    7491              :                         " a pointer to explicit object member function");
    7492              :           else
    7493           33 :             if (!DECL_XOBJ_MEMBER_FUNCTION_P (fn))
    7494            9 :               permerror (loc,
    7495              :                          "ISO C++ forbids taking the address of a bound member"
    7496              :                          " function to form a pointer to member function."
    7497              :                          "  Say %<&%T::%D%>",
    7498              :                          base, name);
    7499              :             else
    7500           24 :               error_at (loc,
    7501              :                         "ISO C++ forbids taking the address of a bound member"
    7502              :                         " function to form a pointer to explicit object member"
    7503              :                         " function");
    7504           64 :           if (DECL_XOBJ_MEMBER_FUNCTION_P (fn))
    7505           34 :             inform (loc,
    7506              :                     "a pointer to explicit object member function can only be "
    7507              :                     "formed with %<&%T::%D%>", base, name);
    7508           64 :         }
    7509           70 :       arg = build_offset_ref (base, fn, /*address_p=*/true, complain);
    7510              :     }
    7511              : 
    7512              :   /* Uninstantiated types are all functions.  Taking the
    7513              :      address of a function is a no-op, so just return the
    7514              :      argument.  */
    7515    260723004 :   if (type_unknown_p (arg))
    7516         2962 :     return build1 (ADDR_EXPR, unknown_type_node, arg);
    7517              : 
    7518    260720042 :   if (TREE_CODE (arg) == OFFSET_REF)
    7519              :     /* We want a pointer to member; bypass all the code for actually taking
    7520              :        the address of something.  */
    7521        60995 :     goto offset_ref;
    7522              : 
    7523              :   /* Anything not already handled and not a true memory reference
    7524              :      is an error.  */
    7525    260659047 :   if (!FUNC_OR_METHOD_TYPE_P (argtype))
    7526              :     {
    7527    139030358 :       cp_lvalue_kind kind = lvalue_kind (arg);
    7528    139030358 :       if (kind == clk_none)
    7529              :         {
    7530           24 :           if (complain & tf_error)
    7531           24 :             lvalue_error (loc, lv_addressof);
    7532           24 :           return error_mark_node;
    7533              :         }
    7534    139030334 :       if (strict_lvalue && (kind & (clk_rvalueref|clk_class)))
    7535              :         {
    7536           36 :           if (!(complain & tf_error))
    7537            9 :             return error_mark_node;
    7538              :           /* Make this a permerror because we used to accept it.  */
    7539           27 :           permerror (loc, "taking address of rvalue");
    7540              :         }
    7541              :     }
    7542              : 
    7543    260659014 :   if (TYPE_REF_P (argtype))
    7544              :     {
    7545          236 :       tree type = build_pointer_type (TREE_TYPE (argtype));
    7546          236 :       arg = build1 (CONVERT_EXPR, type, arg);
    7547          236 :       return arg;
    7548              :     }
    7549    260658778 :   else if (pedantic && DECL_MAIN_P (tree_strip_any_location_wrapper (arg)))
    7550              :     {
    7551              :       /* ARM $3.4 */
    7552              :       /* Apparently a lot of autoconf scripts for C++ packages do this,
    7553              :          so only complain if -Wpedantic.  */
    7554            9 :       if (complain & (flag_pedantic_errors ? tf_error : tf_warning))
    7555            9 :         pedwarn (loc, OPT_Wpedantic,
    7556              :                  "ISO C++ forbids taking address of function %<::main%>");
    7557            0 :       else if (flag_pedantic_errors)
    7558            0 :         return error_mark_node;
    7559              :     }
    7560              : 
    7561              :   /* Let &* cancel out to simplify resulting code.  */
    7562    260658778 :   if (INDIRECT_REF_P (arg))
    7563              :     {
    7564     94846061 :       arg = TREE_OPERAND (arg, 0);
    7565     94846061 :       if (TYPE_REF_P (TREE_TYPE (arg)))
    7566              :         {
    7567     57118241 :           tree type = build_pointer_type (TREE_TYPE (TREE_TYPE (arg)));
    7568     57118241 :           arg = build1 (CONVERT_EXPR, type, arg);
    7569              :         }
    7570              :       else
    7571              :         /* Don't let this be an lvalue.  */
    7572     37727820 :         arg = rvalue (arg);
    7573     94846061 :       return arg;
    7574              :     }
    7575              : 
    7576              :   /* Handle complex lvalues (when permitted)
    7577              :      by reduction to simpler cases.  */
    7578    165812717 :   val = unary_complex_lvalue (ADDR_EXPR, arg);
    7579    165812717 :   if (val != 0)
    7580              :     return val;
    7581              : 
    7582    165340261 :   switch (TREE_CODE (arg))
    7583              :     {
    7584            0 :     CASE_CONVERT:
    7585            0 :     case FLOAT_EXPR:
    7586            0 :     case FIX_TRUNC_EXPR:
    7587              :       /* We should have handled this above in the lvalue_kind check.  */
    7588            0 :       gcc_unreachable ();
    7589        77607 :       break;
    7590              : 
    7591        77607 :     case BASELINK:
    7592        77607 :       arg = BASELINK_FUNCTIONS (arg);
    7593              :       /* Fall through.  */
    7594              : 
    7595        77607 :     case OVERLOAD:
    7596        77607 :       arg = OVL_FIRST (arg);
    7597              :       break;
    7598              : 
    7599        60995 :     case OFFSET_REF:
    7600        60995 :     offset_ref:
    7601              :       /* Turn a reference to a non-static data member into a
    7602              :          pointer-to-member.  */
    7603        60995 :       {
    7604        60995 :         tree type;
    7605        60995 :         tree t;
    7606              : 
    7607        60995 :         gcc_assert (PTRMEM_OK_P (arg));
    7608              : 
    7609        60995 :         t = TREE_OPERAND (arg, 1);
    7610        60995 :         if (TYPE_REF_P (TREE_TYPE (t)))
    7611              :           {
    7612           15 :             if (complain & tf_error)
    7613           15 :               error_at (loc,
    7614              :                         "cannot create pointer to reference member %qD", t);
    7615           15 :             return error_mark_node;
    7616              :           }
    7617              : 
    7618              :         /* Forming a pointer-to-member is a use of non-pure-virtual fns.  */
    7619        60980 :         if (TREE_CODE (t) == FUNCTION_DECL
    7620        58445 :             && !DECL_PURE_VIRTUAL_P (t)
    7621       119403 :             && !mark_used (t, complain) && !(complain & tf_error))
    7622            3 :           return error_mark_node;
    7623              : 
    7624              :         /* Pull out the function_decl for a single xobj member function, and
    7625              :            let the rest of this function handle it.  This is similar to how
    7626              :            static member functions are handled in the BASELINK case above.  */
    7627        60977 :         if (DECL_XOBJ_MEMBER_FUNCTION_P (t))
    7628              :           {
    7629              :             arg = t;
    7630              :             break;
    7631              :           }
    7632              : 
    7633        60911 :         type = build_ptrmem_type (context_for_name_lookup (t),
    7634        60911 :                                   TREE_TYPE (t));
    7635        60911 :         t = make_ptrmem_cst (type, t);
    7636        60911 :         return t;
    7637              :       }
    7638              : 
    7639              :     default:
    7640              :       break;
    7641              :     }
    7642              : 
    7643    165340327 :   if (argtype != error_mark_node)
    7644    165340327 :     argtype = build_pointer_type (argtype);
    7645              : 
    7646    165340327 :   if (bitfield_p (arg))
    7647              :     {
    7648           33 :       if (complain & tf_error)
    7649           33 :         error_at (loc, "attempt to take address of bit-field");
    7650           33 :       return error_mark_node;
    7651              :     }
    7652              : 
    7653              :   /* In a template, we are processing a non-dependent expression
    7654              :      so we can just form an ADDR_EXPR with the correct type.  */
    7655    165340294 :   if (processing_template_decl || TREE_CODE (arg) != COMPONENT_REF)
    7656              :     {
    7657    150366480 :       if (!mark_single_function (arg, complain))
    7658            3 :         return error_mark_node;
    7659    150366477 :       val = build_address (arg);
    7660    150366477 :       if (TREE_CODE (arg) == OFFSET_REF)
    7661            0 :         PTRMEM_OK_P (val) = PTRMEM_OK_P (arg);
    7662              :     }
    7663     14973814 :   else if (BASELINK_P (TREE_OPERAND (arg, 1)))
    7664              :     {
    7665           27 :       tree fn = BASELINK_FUNCTIONS (TREE_OPERAND (arg, 1));
    7666              : 
    7667           27 :       if (TREE_CODE (fn) == OVERLOAD && OVL_SINGLE_P (fn))
    7668           27 :         fn = OVL_FIRST (fn);
    7669              : 
    7670              :       /* We can only get here with a single static member
    7671              :          function.  */
    7672           27 :       gcc_assert (TREE_CODE (fn) == FUNCTION_DECL
    7673              :                   && DECL_STATIC_FUNCTION_P (fn));
    7674           27 :       if (!mark_used (fn, complain) && !(complain & tf_error))
    7675            0 :         return error_mark_node;
    7676           27 :       val = build_address (fn);
    7677           27 :       if (TREE_SIDE_EFFECTS (TREE_OPERAND (arg, 0)))
    7678              :         /* Do not lose object's side effects.  */
    7679           12 :         val = build2 (COMPOUND_EXPR, TREE_TYPE (val),
    7680           12 :                       TREE_OPERAND (arg, 0), val);
    7681              :     }
    7682              :   else
    7683              :     {
    7684     14973787 :       tree object = TREE_OPERAND (arg, 0);
    7685     14973787 :       tree field = TREE_OPERAND (arg, 1);
    7686     14973787 :       gcc_assert (same_type_ignoring_top_level_qualifiers_p
    7687              :                   (TREE_TYPE (object), decl_type_context (field)));
    7688     14973787 :       val = build_address (arg);
    7689              :     }
    7690              : 
    7691    165340291 :   if (TYPE_PTR_P (argtype)
    7692    165340291 :       && TREE_CODE (TREE_TYPE (argtype)) == METHOD_TYPE)
    7693              :     {
    7694         1078 :       build_ptrmemfunc_type (argtype);
    7695         1078 :       val = build_ptrmemfunc (argtype, val, 0,
    7696              :                               /*c_cast_p=*/false,
    7697              :                               complain);
    7698              :     }
    7699              : 
    7700              :   /* Ensure we have EXPR_LOCATION set for possible later diagnostics.  */
    7701    165340291 :   if (TREE_CODE (val) == ADDR_EXPR
    7702    165340291 :       && TREE_CODE (TREE_OPERAND (val, 0)) == FUNCTION_DECL)
    7703    116024561 :     SET_EXPR_LOCATION (val, input_location);
    7704              : 
    7705              :   return val;
    7706              : }
    7707              : 
    7708              : /* Take the address of ARG if it has one, even if it's an rvalue.  */
    7709              : 
    7710              : tree
    7711    256164435 : cp_build_addr_expr (tree arg, tsubst_flags_t complain)
    7712              : {
    7713    256164435 :   return cp_build_addr_expr_1 (arg, 0, complain);
    7714              : }
    7715              : 
    7716              : /* Take the address of ARG, but only if it's an lvalue.  */
    7717              : 
    7718              : static tree
    7719      4558584 : cp_build_addr_expr_strict (tree arg, tsubst_flags_t complain)
    7720              : {
    7721      4558584 :   return cp_build_addr_expr_1 (arg, 1, complain);
    7722              : }
    7723              : 
    7724              : /* C++: Must handle pointers to members.
    7725              : 
    7726              :    Perhaps type instantiation should be extended to handle conversion
    7727              :    from aggregates to types we don't yet know we want?  (Or are those
    7728              :    cases typically errors which should be reported?)
    7729              : 
    7730              :    NOCONVERT suppresses the default promotions (such as from short to int).  */
    7731              : 
    7732              : tree
    7733     30518156 : cp_build_unary_op (enum tree_code code, tree xarg, bool noconvert,
    7734              :                    tsubst_flags_t complain)
    7735              : {
    7736              :   /* No default_conversion here.  It causes trouble for ADDR_EXPR.  */
    7737     30518156 :   tree arg = xarg;
    7738     30518156 :   location_t location = cp_expr_loc_or_input_loc (arg);
    7739     30518156 :   tree argtype = 0;
    7740     30518156 :   tree eptype = NULL_TREE;
    7741     30518156 :   const char *errstring = NULL;
    7742     30518156 :   tree val;
    7743     30518156 :   const char *invalid_op_diag;
    7744              : 
    7745     30518156 :   if (!arg || error_operand_p (arg))
    7746            0 :     return error_mark_node;
    7747              : 
    7748     30518156 :   arg = resolve_nondeduced_context (arg, complain);
    7749              : 
    7750     61036312 :   if ((invalid_op_diag
    7751     30518156 :        = targetm.invalid_unary_op ((code == UNARY_PLUS_EXPR
    7752              :                                     ? CONVERT_EXPR
    7753              :                                     : code),
    7754     30518156 :                                    TREE_TYPE (arg))))
    7755              :     {
    7756            0 :       if (complain & tf_error)
    7757            0 :         error (invalid_op_diag);
    7758            0 :       return error_mark_node;
    7759              :     }
    7760              : 
    7761     30518156 :   if (TREE_CODE (arg) == EXCESS_PRECISION_EXPR)
    7762              :     {
    7763         6666 :       eptype = TREE_TYPE (arg);
    7764         6666 :       arg = TREE_OPERAND (arg, 0);
    7765              :     }
    7766              : 
    7767     30518156 :   switch (code)
    7768              :     {
    7769      2357083 :     case UNARY_PLUS_EXPR:
    7770      2357083 :     case NEGATE_EXPR:
    7771      2357083 :       {
    7772      2357083 :         int flags = WANT_ARITH | WANT_ENUM;
    7773              :         /* Unary plus (but not unary minus) is allowed on pointers.  */
    7774      2357083 :         if (code == UNARY_PLUS_EXPR)
    7775       159178 :           flags |= WANT_POINTER;
    7776      2357083 :         arg = build_expr_type_conversion (flags, arg, true);
    7777      2357083 :         if (!arg)
    7778           34 :           errstring = (code == NEGATE_EXPR
    7779           27 :                        ? _("wrong type argument to unary minus")
    7780            7 :                        : _("wrong type argument to unary plus"));
    7781              :         else
    7782              :           {
    7783      2357049 :             if (!noconvert && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (arg)))
    7784       665145 :               arg = cp_perform_integral_promotions (arg, complain);
    7785              : 
    7786              :             /* Make sure the result is not an lvalue: a unary plus or minus
    7787              :                expression is always a rvalue.  */
    7788      2357049 :             arg = rvalue (arg);
    7789              :           }
    7790              :       }
    7791              :       break;
    7792              : 
    7793       904183 :     case BIT_NOT_EXPR:
    7794       904183 :       if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
    7795              :         {
    7796           15 :           code = CONJ_EXPR;
    7797           15 :           if (!noconvert)
    7798              :             {
    7799           15 :               arg = cp_default_conversion (arg, complain);
    7800           15 :               if (arg == error_mark_node)
    7801              :                 return error_mark_node;
    7802              :             }
    7803              :         }
    7804       904168 :       else if (!(arg = build_expr_type_conversion (WANT_INT | WANT_ENUM
    7805              :                                                    | WANT_VECTOR_OR_COMPLEX,
    7806              :                                                    arg, true)))
    7807           16 :         errstring = _("wrong type argument to bit-complement");
    7808       904152 :       else if (!noconvert && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (arg)))
    7809              :         {
    7810              :           /* Warn if the expression has boolean value.  */
    7811       903797 :           if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE
    7812       903797 :               && (complain & tf_warning))
    7813              :             {
    7814           61 :               auto_diagnostic_group d;
    7815           61 :               if (warning_at (location, OPT_Wbool_operation,
    7816              :                               "%<~%> on an expression of type %<bool%>"))
    7817           42 :                 inform (location, "did you mean to use logical not (%<!%>)?");
    7818           61 :             }
    7819       903797 :           arg = cp_perform_integral_promotions (arg, complain);
    7820              :         }
    7821          355 :       else if (!noconvert && VECTOR_TYPE_P (TREE_TYPE (arg)))
    7822          355 :         arg = mark_rvalue_use (arg);
    7823              :       break;
    7824              : 
    7825            0 :     case ABS_EXPR:
    7826            0 :       if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, arg, true)))
    7827            0 :         errstring = _("wrong type argument to abs");
    7828            0 :       else if (!noconvert)
    7829              :         {
    7830            0 :           arg = cp_default_conversion (arg, complain);
    7831            0 :           if (arg == error_mark_node)
    7832              :             return error_mark_node;
    7833              :         }
    7834              :       break;
    7835              : 
    7836            0 :     case CONJ_EXPR:
    7837              :       /* Conjugating a real value is a no-op, but allow it anyway.  */
    7838            0 :       if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, arg, true)))
    7839            0 :         errstring = _("wrong type argument to conjugation");
    7840            0 :       else if (!noconvert)
    7841              :         {
    7842            0 :           arg = cp_default_conversion (arg, complain);
    7843            0 :           if (arg == error_mark_node)
    7844              :             return error_mark_node;
    7845              :         }
    7846              :       break;
    7847              : 
    7848     17884775 :     case TRUTH_NOT_EXPR:
    7849     17884775 :       if (gnu_vector_type_p (TREE_TYPE (arg)))
    7850           60 :         return cp_build_binary_op (input_location, EQ_EXPR, arg,
    7851           60 :                                    build_zero_cst (TREE_TYPE (arg)), complain);
    7852     17884715 :       arg = contextual_conv_bool (arg, complain);
    7853     17884715 :       if (arg != error_mark_node)
    7854              :         {
    7855     17884706 :           if (processing_template_decl)
    7856      8346099 :             return build1_loc (location, TRUTH_NOT_EXPR, boolean_type_node, arg);
    7857      9538607 :           val = invert_truthvalue_loc (location, arg);
    7858      9538607 :           if (obvalue_p (val))
    7859        12006 :             val = non_lvalue_loc (location, val);
    7860      9538607 :           return val;
    7861              :         }
    7862            9 :       errstring = _("in argument to unary !");
    7863            9 :       break;
    7864              : 
    7865              :     case NOP_EXPR:
    7866              :       break;
    7867              : 
    7868       443342 :     case REALPART_EXPR:
    7869       443342 :     case IMAGPART_EXPR:
    7870       443342 :       val = build_real_imag_expr (input_location, code, arg);
    7871       443342 :       if (eptype && TREE_CODE (eptype) == COMPLEX_EXPR)
    7872            0 :         val = build1_loc (input_location, EXCESS_PRECISION_EXPR,
    7873            0 :                           TREE_TYPE (eptype), val);
    7874              :       return val;
    7875              : 
    7876      8376788 :     case PREINCREMENT_EXPR:
    7877      8376788 :     case POSTINCREMENT_EXPR:
    7878      8376788 :     case PREDECREMENT_EXPR:
    7879      8376788 :     case POSTDECREMENT_EXPR:
    7880              :       /* Handle complex lvalues (when permitted)
    7881              :          by reduction to simpler cases.  */
    7882              : 
    7883      8376788 :       val = unary_complex_lvalue (code, arg);
    7884      8376788 :       if (val != 0)
    7885           32 :         goto return_build_unary_op;
    7886              : 
    7887      8376756 :       tree stripped_arg;
    7888      8376756 :       stripped_arg = tree_strip_any_location_wrapper (arg);
    7889      2071964 :       if ((VAR_P (stripped_arg) || TREE_CODE (stripped_arg) == PARM_DECL)
    7890      7743475 :           && !DECL_READ_P (stripped_arg)
    7891      9472276 :           && (VAR_P (stripped_arg) ? warn_unused_but_set_variable
    7892              :                                    : warn_unused_but_set_parameter) > 1)
    7893              :         {
    7894         9904 :           arg = mark_lvalue_use (arg);
    7895         9904 :           DECL_READ_P (stripped_arg) = 0;
    7896              :         }
    7897              :       else
    7898      8366852 :         arg = mark_lvalue_use (arg);
    7899              : 
    7900              :       /* Increment or decrement the real part of the value,
    7901              :          and don't change the imaginary part.  */
    7902      8376756 :       if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
    7903              :         {
    7904           18 :           tree real, imag;
    7905              : 
    7906           18 :           arg = cp_stabilize_reference (arg);
    7907           18 :           real = cp_build_unary_op (REALPART_EXPR, arg, true, complain);
    7908           18 :           imag = cp_build_unary_op (IMAGPART_EXPR, arg, true, complain);
    7909           18 :           real = cp_build_unary_op (code, real, true, complain);
    7910           18 :           if (real == error_mark_node || imag == error_mark_node)
    7911              :             return error_mark_node;
    7912           15 :           val = build2 (COMPLEX_EXPR, TREE_TYPE (arg), real, imag);
    7913           15 :           goto return_build_unary_op;
    7914              :         }
    7915              : 
    7916              :       /* Report invalid types.  */
    7917              : 
    7918      8376738 :       if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_POINTER,
    7919              :                                               arg, true)))
    7920              :         {
    7921           36 :           if (code == PREINCREMENT_EXPR)
    7922            9 :             errstring = _("no pre-increment operator for type");
    7923           27 :           else if (code == POSTINCREMENT_EXPR)
    7924            9 :             errstring = _("no post-increment operator for type");
    7925           18 :           else if (code == PREDECREMENT_EXPR)
    7926            9 :             errstring = _("no pre-decrement operator for type");
    7927              :           else
    7928            9 :             errstring = _("no post-decrement operator for type");
    7929              :           break;
    7930              :         }
    7931      8376702 :       else if (arg == error_mark_node)
    7932              :         return error_mark_node;
    7933              : 
    7934              :       /* Report something read-only.  */
    7935              : 
    7936      8376702 :       if (CP_TYPE_CONST_P (TREE_TYPE (arg))
    7937      8376702 :           || TREE_READONLY (arg))
    7938              :         {
    7939          119 :           if (complain & tf_error)
    7940          119 :             cxx_readonly_error (location, arg,
    7941          119 :                                 ((code == PREINCREMENT_EXPR
    7942          119 :                                   || code == POSTINCREMENT_EXPR)
    7943              :                                  ? lv_increment : lv_decrement));
    7944              :           else
    7945            0 :             return error_mark_node;
    7946              :         }
    7947              : 
    7948      8376702 :       {
    7949      8376702 :         tree inc;
    7950      8376702 :         tree declared_type = unlowered_expr_type (arg);
    7951              : 
    7952      8376702 :         argtype = TREE_TYPE (arg);
    7953              : 
    7954              :         /* ARM $5.2.5 last annotation says this should be forbidden.  */
    7955      8376702 :         if (TREE_CODE (argtype) == ENUMERAL_TYPE)
    7956              :           {
    7957            0 :             if (complain & tf_error)
    7958            0 :               permerror (location, (code == PREINCREMENT_EXPR
    7959            0 :                                     || code == POSTINCREMENT_EXPR)
    7960              :                          ? G_("ISO C++ forbids incrementing an enum")
    7961              :                          : G_("ISO C++ forbids decrementing an enum"));
    7962              :             else
    7963            0 :               return error_mark_node;
    7964              :           }
    7965              : 
    7966              :         /* Compute the increment.  */
    7967              : 
    7968      8376702 :         if (TYPE_PTR_P (argtype))
    7969              :           {
    7970      2673460 :             tree type = complete_type (TREE_TYPE (argtype));
    7971              : 
    7972      2673460 :             if (!COMPLETE_OR_VOID_TYPE_P (type))
    7973              :               {
    7974           10 :                 if (complain & tf_error)
    7975            9 :                   error_at (location, ((code == PREINCREMENT_EXPR
    7976            9 :                                         || code == POSTINCREMENT_EXPR))
    7977              :                             ? G_("cannot increment a pointer to incomplete "
    7978              :                                  "type %qT")
    7979              :                             : G_("cannot decrement a pointer to incomplete "
    7980              :                                  "type %qT"),
    7981            9 :                             TREE_TYPE (argtype));
    7982              :                 else
    7983            1 :                   return error_mark_node;
    7984              :               }
    7985      2673450 :             else if (!TYPE_PTROB_P (argtype))
    7986              :               {
    7987           69 :                 if (complain & tf_error)
    7988           63 :                   pedwarn (location, OPT_Wpointer_arith,
    7989           63 :                            (code == PREINCREMENT_EXPR
    7990           63 :                               || code == POSTINCREMENT_EXPR)
    7991              :                            ? G_("ISO C++ forbids incrementing a pointer "
    7992              :                                 "of type %qT")
    7993              :                            : G_("ISO C++ forbids decrementing a pointer "
    7994              :                                 "of type %qT"),
    7995              :                            argtype);
    7996              :                 else
    7997            6 :                   return error_mark_node;
    7998              :               }
    7999      2673381 :             else if (!verify_type_context (location, TCTX_POINTER_ARITH,
    8000      2673381 :                                            TREE_TYPE (argtype),
    8001              :                                            !(complain & tf_error)))
    8002            0 :               return error_mark_node;
    8003              : 
    8004      2673453 :             inc = cxx_sizeof_nowarn (TREE_TYPE (argtype));
    8005              :           }
    8006              :         else
    8007      5703099 :           inc = VECTOR_TYPE_P (argtype)
    8008      5703242 :             ? build_one_cst (argtype)
    8009              :             : integer_one_node;
    8010              : 
    8011      8376695 :         inc = cp_convert (argtype, inc, complain);
    8012              : 
    8013              :         /* If 'arg' is an Objective-C PROPERTY_REF expression, then we
    8014              :            need to ask Objective-C to build the increment or decrement
    8015              :            expression for it.  */
    8016      8376695 :         if (objc_is_property_ref (arg))
    8017            0 :           return objc_build_incr_expr_for_property_ref (input_location, code,
    8018            0 :                                                         arg, inc);
    8019              : 
    8020              :         /* Complain about anything else that is not a true lvalue.  */
    8021      8376695 :         if (!lvalue_or_else (arg, ((code == PREINCREMENT_EXPR
    8022      8376695 :                                     || code == POSTINCREMENT_EXPR)
    8023              :                                    ? lv_increment : lv_decrement),
    8024              :                              complain))
    8025           36 :           return error_mark_node;
    8026              : 
    8027              :         /* [depr.volatile.type] "Postfix ++ and -- expressions and
    8028              :            prefix ++ and -- expressions of volatile-qualified arithmetic
    8029              :            and pointer types are deprecated."  */
    8030      8376374 :         if ((TREE_THIS_VOLATILE (arg) || CP_TYPE_VOLATILE_P (TREE_TYPE (arg)))
    8031      8376659 :             && (complain & tf_warning))
    8032          398 :           warning_at (location, OPT_Wvolatile,
    8033              :                       "%qs expression of %<volatile%>-qualified type is "
    8034              :                       "deprecated",
    8035              :                       ((code == PREINCREMENT_EXPR
    8036              :                         || code == POSTINCREMENT_EXPR)
    8037              :                        ? "++" : "--"));
    8038              : 
    8039              :         /* Forbid using -- or ++ in C++17 on `bool'.  */
    8040      8376659 :         if (TREE_CODE (declared_type) == BOOLEAN_TYPE)
    8041              :           {
    8042           95 :             if (code == POSTDECREMENT_EXPR || code == PREDECREMENT_EXPR)
    8043              :               {
    8044           33 :                 if (complain & tf_error)
    8045           33 :                   error_at (location,
    8046              :                             "use of an operand of type %qT in %<operator--%> "
    8047              :                             "is forbidden", boolean_type_node);
    8048           33 :                 return error_mark_node;
    8049              :               }
    8050              :             else
    8051              :               {
    8052           62 :                 if (cxx_dialect >= cxx17)
    8053              :                   {
    8054           33 :                     if (complain & tf_error)
    8055           32 :                       error_at (location,
    8056              :                                 "use of an operand of type %qT in "
    8057              :                                 "%<operator++%> is forbidden in C++17",
    8058              :                                 boolean_type_node);
    8059           33 :                     return error_mark_node;
    8060              :                   }
    8061              :                 /* Otherwise, [depr.incr.bool] says this is deprecated.  */
    8062           29 :                 else if (complain & tf_warning)
    8063           25 :                   warning_at (location, OPT_Wdeprecated,
    8064              :                               "use of an operand of type %qT "
    8065              :                               "in %<operator++%> is deprecated",
    8066              :                               boolean_type_node);
    8067              :               }
    8068           29 :             val = boolean_increment (code, arg);
    8069              :           }
    8070      8376564 :         else if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
    8071              :           /* An rvalue has no cv-qualifiers.  */
    8072      1332731 :           val = build2 (code, cv_unqualified (TREE_TYPE (arg)), arg, inc);
    8073              :         else
    8074      7043833 :           val = build2 (code, TREE_TYPE (arg), arg, inc);
    8075              : 
    8076      8376593 :         TREE_SIDE_EFFECTS (val) = 1;
    8077      8376593 :         goto return_build_unary_op;
    8078              :       }
    8079              : 
    8080       551985 :     case ADDR_EXPR:
    8081              :       /* Note that this operation never does default_conversion
    8082              :          regardless of NOCONVERT.  */
    8083       551985 :       return cp_build_addr_expr (arg, complain);
    8084              : 
    8085              :     default:
    8086              :       break;
    8087              :     }
    8088              : 
    8089      3261296 :   if (!errstring)
    8090              :     {
    8091      3261216 :       if (argtype == 0)
    8092      3261216 :         argtype = TREE_TYPE (arg);
    8093      3261216 :       val = build1 (code, argtype, arg);
    8094     11637856 :     return_build_unary_op:
    8095     11637856 :       if (eptype)
    8096         6657 :         val = build1 (EXCESS_PRECISION_EXPR, eptype, val);
    8097     11637856 :       return val;
    8098              :     }
    8099              : 
    8100           95 :   if (complain & tf_error)
    8101           50 :     error_at (location, "%s", errstring);
    8102           95 :   return error_mark_node;
    8103              : }
    8104              : 
    8105              : /* Hook for the c-common bits that build a unary op.  */
    8106              : tree
    8107         4136 : build_unary_op (location_t /*location*/,
    8108              :                 enum tree_code code, tree xarg, bool noconvert)
    8109              : {
    8110         4136 :   return cp_build_unary_op (code, xarg, noconvert, tf_warning_or_error);
    8111              : }
    8112              : 
    8113              : /* Adjust LVALUE, an MODIFY_EXPR, PREINCREMENT_EXPR or PREDECREMENT_EXPR,
    8114              :    so that it is a valid lvalue even for GENERIC by replacing
    8115              :    (lhs = rhs) with ((lhs = rhs), lhs)
    8116              :    (--lhs) with ((--lhs), lhs)
    8117              :    (++lhs) with ((++lhs), lhs)
    8118              :    and if lhs has side-effects, calling cp_stabilize_reference on it, so
    8119              :    that it can be evaluated multiple times.  */
    8120              : 
    8121              : tree
    8122       395703 : genericize_compound_lvalue (tree lvalue)
    8123              : {
    8124       395703 :   if (TREE_SIDE_EFFECTS (TREE_OPERAND (lvalue, 0)))
    8125          196 :     lvalue = build2 (TREE_CODE (lvalue), TREE_TYPE (lvalue),
    8126          196 :                      cp_stabilize_reference (TREE_OPERAND (lvalue, 0)),
    8127          196 :                      TREE_OPERAND (lvalue, 1));
    8128       395703 :   return build2 (COMPOUND_EXPR, TREE_TYPE (TREE_OPERAND (lvalue, 0)),
    8129       395703 :                  lvalue, TREE_OPERAND (lvalue, 0));
    8130              : }
    8131              : 
    8132              : /* Apply unary lvalue-demanding operator CODE to the expression ARG
    8133              :    for certain kinds of expressions which are not really lvalues
    8134              :    but which we can accept as lvalues.
    8135              : 
    8136              :    If ARG is not a kind of expression we can handle, return
    8137              :    NULL_TREE.  */
    8138              : 
    8139              : tree
    8140    298934245 : unary_complex_lvalue (enum tree_code code, tree arg)
    8141              : {
    8142              :   /* Inside a template, making these kinds of adjustments is
    8143              :      pointless; we are only concerned with the type of the
    8144              :      expression.  */
    8145    299329718 :   if (processing_template_decl)
    8146              :     return NULL_TREE;
    8147              : 
    8148              :   /* Handle (a, b) used as an "lvalue".  */
    8149    212315880 :   if (TREE_CODE (arg) == COMPOUND_EXPR)
    8150              :     {
    8151       396808 :       tree real_result = cp_build_unary_op (code, TREE_OPERAND (arg, 1), false,
    8152              :                                             tf_warning_or_error);
    8153       396808 :       return build2 (COMPOUND_EXPR, TREE_TYPE (real_result),
    8154       793616 :                      TREE_OPERAND (arg, 0), real_result);
    8155              :     }
    8156              : 
    8157              :   /* Handle (a ? b : c) used as an "lvalue".  */
    8158    211919072 :   if (TREE_CODE (arg) == COND_EXPR
    8159    211843374 :       || TREE_CODE (arg) == MIN_EXPR || TREE_CODE (arg) == MAX_EXPR)
    8160        75698 :     return rationalize_conditional_expr (code, arg, tf_warning_or_error);
    8161              : 
    8162              :   /* Handle (a = b), (++a), and (--a) used as an "lvalue".  */
    8163    211843374 :   if (TREE_CODE (arg) == MODIFY_EXPR
    8164    211448024 :       || TREE_CODE (arg) == PREINCREMENT_EXPR
    8165    211447963 :       || TREE_CODE (arg) == PREDECREMENT_EXPR)
    8166       395473 :     return unary_complex_lvalue (code, genericize_compound_lvalue (arg));
    8167              : 
    8168    211447901 :   if (code != ADDR_EXPR)
    8169              :     return NULL_TREE;
    8170              : 
    8171              :   /* Handle (a = b) used as an "lvalue" for `&'.  */
    8172    207656928 :   if (TREE_CODE (arg) == MODIFY_EXPR
    8173    207656928 :       || TREE_CODE (arg) == INIT_EXPR)
    8174              :     {
    8175            0 :       tree real_result = cp_build_unary_op (code, TREE_OPERAND (arg, 0), false,
    8176              :                                             tf_warning_or_error);
    8177            0 :       arg = build2 (COMPOUND_EXPR, TREE_TYPE (real_result),
    8178              :                     arg, real_result);
    8179            0 :       suppress_warning (arg /* What warning? */);
    8180            0 :       return arg;
    8181              :     }
    8182              : 
    8183    320699068 :   if (FUNC_OR_METHOD_TYPE_P (TREE_TYPE (arg))
    8184    320698011 :       || TREE_CODE (arg) == OFFSET_REF)
    8185              :     return NULL_TREE;
    8186              : 
    8187              :   /* We permit compiler to make function calls returning
    8188              :      objects of aggregate type look like lvalues.  */
    8189    113041083 :   {
    8190    113041083 :     tree targ = arg;
    8191              : 
    8192    113041083 :     if (TREE_CODE (targ) == SAVE_EXPR)
    8193            0 :       targ = TREE_OPERAND (targ, 0);
    8194              : 
    8195    113041083 :     if (TREE_CODE (targ) == CALL_EXPR && MAYBE_CLASS_TYPE_P (TREE_TYPE (targ)))
    8196              :       {
    8197           26 :         if (TREE_CODE (arg) == SAVE_EXPR)
    8198              :           targ = arg;
    8199              :         else
    8200           26 :           targ = build_cplus_new (TREE_TYPE (arg), arg, tf_warning_or_error);
    8201           26 :         return build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg)), targ);
    8202              :       }
    8203              : 
    8204    113041057 :     if (TREE_CODE (arg) == SAVE_EXPR && INDIRECT_REF_P (targ))
    8205            0 :       return build3 (SAVE_EXPR, build_pointer_type (TREE_TYPE (arg)),
    8206            0 :                      TREE_OPERAND (targ, 0), current_function_decl, NULL);
    8207              :   }
    8208              : 
    8209              :   /* Don't let anything else be handled specially.  */
    8210              :   return NULL_TREE;
    8211              : }
    8212              : 
    8213              : /* Mark EXP saying that we need to be able to take the
    8214              :    address of it; it should not be allocated in a register.
    8215              :    Value is true if successful.  ARRAY_REF_P is true if this
    8216              :    is for ARRAY_REF construction - in that case we don't want
    8217              :    to look through VIEW_CONVERT_EXPR from VECTOR_TYPE to ARRAY_TYPE,
    8218              :    it is fine to use ARRAY_REFs for vector subscripts on vector
    8219              :    register variables.
    8220              : 
    8221              :    C++: we do not allow `current_class_ptr' to be addressable.  */
    8222              : 
    8223              : bool
    8224    356327689 : cxx_mark_addressable (tree exp, bool array_ref_p)
    8225              : {
    8226    356327689 :   tree x = exp;
    8227              : 
    8228    417197602 :   while (1)
    8229    417197602 :     switch (TREE_CODE (x))
    8230              :       {
    8231     30432830 :       case VIEW_CONVERT_EXPR:
    8232     30432830 :         if (array_ref_p
    8233       772523 :             && TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE
    8234     31011619 :             && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (x, 0))))
    8235              :           return true;
    8236     30429772 :         x = TREE_OPERAND (x, 0);
    8237     30429772 :         break;
    8238              : 
    8239     30089249 :       case COMPONENT_REF:
    8240     30089249 :         if (bitfield_p (x))
    8241            9 :           error ("attempt to take address of bit-field");
    8242              :         /* FALLTHRU */
    8243     30440141 :       case ADDR_EXPR:
    8244     30440141 :       case ARRAY_REF:
    8245     30440141 :       case REALPART_EXPR:
    8246     30440141 :       case IMAGPART_EXPR:
    8247     30440141 :         x = TREE_OPERAND (x, 0);
    8248     30440141 :         break;
    8249              : 
    8250      8073357 :       case PARM_DECL:
    8251      8073357 :         if (x == current_class_ptr)
    8252              :           {
    8253           18 :             error ("cannot take the address of %<this%>, which is an rvalue expression");
    8254           18 :             TREE_ADDRESSABLE (x) = 1; /* so compiler doesn't die later.  */
    8255           18 :             return true;
    8256              :           }
    8257              :         /* Fall through.  */
    8258              : 
    8259     74589580 :       case VAR_DECL:
    8260              :         /* Caller should not be trying to mark initialized
    8261              :            constant fields addressable.  */
    8262     74589580 :         gcc_assert (DECL_LANG_SPECIFIC (x) == 0
    8263              :                     || DECL_IN_AGGR_P (x) == 0
    8264              :                     || TREE_STATIC (x)
    8265              :                     || DECL_EXTERNAL (x));
    8266     74589580 :         if (VAR_P (x)
    8267     66516241 :             && DECL_ANON_UNION_VAR_P (x)
    8268     74589647 :             && !TREE_ADDRESSABLE (x))
    8269           35 :           cxx_mark_addressable (DECL_VALUE_EXPR (x));
    8270              :         /* Fall through.  */
    8271              : 
    8272     74706465 :       case RESULT_DECL:
    8273     74706556 :         if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)
    8274     74706547 :             && !DECL_ARTIFICIAL (x))
    8275              :           {
    8276           31 :             if (VAR_P (x) && DECL_HARD_REGISTER (x))
    8277              :               {
    8278           15 :                 error
    8279           15 :                   ("address of explicit register variable %qD requested", x);
    8280           15 :                 return false;
    8281              :               }
    8282           16 :             else if (extra_warnings)
    8283            3 :               warning
    8284            3 :                 (OPT_Wextra, "address requested for %qD, which is declared %<register%>", x);
    8285              :           }
    8286     74706450 :         TREE_ADDRESSABLE (x) = 1;
    8287     74706450 :         return true;
    8288              : 
    8289    170668220 :       case CONST_DECL:
    8290    170668220 :       case FUNCTION_DECL:
    8291    170668220 :         TREE_ADDRESSABLE (x) = 1;
    8292    170668220 :         return true;
    8293              : 
    8294        53478 :       case CONSTRUCTOR:
    8295        53478 :         TREE_ADDRESSABLE (x) = 1;
    8296        53478 :         return true;
    8297              : 
    8298     17109642 :       case TARGET_EXPR:
    8299     17109642 :         TREE_ADDRESSABLE (x) = 1;
    8300     17109642 :         cxx_mark_addressable (TARGET_EXPR_SLOT (x));
    8301     17109642 :         return true;
    8302              : 
    8303              :       default:
    8304              :         return true;
    8305              :     }
    8306              : }
    8307              : 
    8308              : /* Build and return a conditional expression IFEXP ? OP1 : OP2.  */
    8309              : 
    8310              : tree
    8311      9542735 : build_x_conditional_expr (location_t loc, tree ifexp, tree op1, tree op2,
    8312              :                           tsubst_flags_t complain)
    8313              : {
    8314      9542735 :   tree orig_ifexp = ifexp;
    8315      9542735 :   tree orig_op1 = op1;
    8316      9542735 :   tree orig_op2 = op2;
    8317      9542735 :   tree expr;
    8318              : 
    8319      9542735 :   if (processing_template_decl)
    8320              :     {
    8321              :       /* The standard says that the expression is type-dependent if
    8322              :          IFEXP is type-dependent, even though the eventual type of the
    8323              :          expression doesn't dependent on IFEXP.  */
    8324      3386476 :       if (type_dependent_expression_p (ifexp)
    8325              :           /* As a GNU extension, the middle operand may be omitted.  */
    8326      1853314 :           || (op1 && type_dependent_expression_p (op1))
    8327      4733532 :           || type_dependent_expression_p (op2))
    8328      2067563 :         return build_min_nt_loc (loc, COND_EXPR, ifexp, op1, op2);
    8329              :     }
    8330              : 
    8331      7475172 :   expr = build_conditional_expr (loc, ifexp, op1, op2, complain);
    8332      7475172 :   if (processing_template_decl && expr != error_mark_node)
    8333              :     {
    8334      1318907 :       tree min = build_min_non_dep (COND_EXPR, expr,
    8335              :                                     orig_ifexp, orig_op1, orig_op2);
    8336      1318907 :       expr = convert_from_reference (min);
    8337              :     }
    8338              :   return expr;
    8339              : }
    8340              : 
    8341              : /* Given a list of expressions, return a compound expression
    8342              :    that performs them all and returns the value of the last of them.  */
    8343              : 
    8344              : tree
    8345     31140217 : build_x_compound_expr_from_list (tree list, expr_list_kind exp,
    8346              :                                  tsubst_flags_t complain)
    8347              : {
    8348     31140217 :   tree expr = TREE_VALUE (list);
    8349              : 
    8350       444653 :   if (BRACE_ENCLOSED_INITIALIZER_P (expr)
    8351     31584858 :       && !CONSTRUCTOR_IS_DIRECT_INIT (expr))
    8352              :     {
    8353           14 :       if (complain & tf_error)
    8354           28 :         pedwarn (cp_expr_loc_or_input_loc (expr), 0,
    8355              :                  "list-initializer for non-class type must not "
    8356              :                  "be parenthesized");
    8357              :       else
    8358            0 :         return error_mark_node;
    8359              :     }
    8360              : 
    8361     31140217 :   if (TREE_CHAIN (list))
    8362              :     {
    8363           23 :       if (complain & tf_error)
    8364           14 :         switch (exp)
    8365              :           {
    8366           12 :           case ELK_INIT:
    8367           12 :             permerror (input_location, "expression list treated as compound "
    8368              :                                        "expression in initializer");
    8369           12 :             break;
    8370            1 :           case ELK_MEM_INIT:
    8371            1 :             permerror (input_location, "expression list treated as compound "
    8372              :                                        "expression in mem-initializer");
    8373            1 :             break;
    8374            1 :           case ELK_FUNC_CAST:
    8375            1 :             permerror (input_location, "expression list treated as compound "
    8376              :                                        "expression in functional cast");
    8377            1 :             break;
    8378            0 :           default:
    8379            0 :             gcc_unreachable ();
    8380              :           }
    8381              :       else
    8382            9 :         return error_mark_node;
    8383              : 
    8384           28 :       for (list = TREE_CHAIN (list); list; list = TREE_CHAIN (list))
    8385           28 :         expr = build_x_compound_expr (EXPR_LOCATION (TREE_VALUE (list)),
    8386           14 :                                       expr, TREE_VALUE (list), NULL_TREE,
    8387              :                                       complain);
    8388              :     }
    8389              : 
    8390              :   return expr;
    8391              : }
    8392              : 
    8393              : /* Like build_x_compound_expr_from_list, but using a VEC.  */
    8394              : 
    8395              : tree
    8396       388799 : build_x_compound_expr_from_vec (vec<tree, va_gc> *vec, const char *msg,
    8397              :                                 tsubst_flags_t complain)
    8398              : {
    8399       388799 :   if (vec_safe_is_empty (vec))
    8400              :     return NULL_TREE;
    8401       388799 :   else if (vec->length () == 1)
    8402       388735 :     return (*vec)[0];
    8403              :   else
    8404              :     {
    8405           64 :       tree expr;
    8406           64 :       unsigned int ix;
    8407           64 :       tree t;
    8408              : 
    8409           64 :       if (msg != NULL)
    8410              :         {
    8411            4 :           if (complain & tf_error)
    8412            0 :             permerror (input_location,
    8413              :                        "%s expression list treated as compound expression",
    8414              :                        msg);
    8415              :           else
    8416            4 :             return error_mark_node;
    8417              :         }
    8418              : 
    8419           60 :       expr = (*vec)[0];
    8420          134 :       for (ix = 1; vec->iterate (ix, &t); ++ix)
    8421           74 :         expr = build_x_compound_expr (EXPR_LOCATION (t), expr,
    8422              :                                       t, NULL_TREE, complain);
    8423              : 
    8424              :       return expr;
    8425              :     }
    8426              : }
    8427              : 
    8428              : /* Handle overloading of the ',' operator when needed.  */
    8429              : 
    8430              : tree
    8431      3054770 : build_x_compound_expr (location_t loc, tree op1, tree op2,
    8432              :                        tree lookups, tsubst_flags_t complain)
    8433              : {
    8434      3054770 :   tree result;
    8435      3054770 :   tree orig_op1 = op1;
    8436      3054770 :   tree orig_op2 = op2;
    8437      3054770 :   tree overload = NULL_TREE;
    8438              : 
    8439      3054770 :   if (processing_template_decl)
    8440              :     {
    8441      2814365 :       if (type_dependent_expression_p (op1)
    8442      2814365 :           || type_dependent_expression_p (op2))
    8443              :         {
    8444      2551573 :           result = build_min_nt_loc (loc, COMPOUND_EXPR, op1, op2);
    8445      2551573 :           TREE_TYPE (result)
    8446      2551573 :             = build_dependent_operator_type (lookups, COMPOUND_EXPR, false);
    8447      2551573 :           return result;
    8448              :         }
    8449              :     }
    8450              : 
    8451       503197 :   result = build_new_op (loc, COMPOUND_EXPR, LOOKUP_NORMAL, op1, op2,
    8452              :                          NULL_TREE, lookups, &overload, complain);
    8453       503197 :   if (!result)
    8454       494942 :     result = cp_build_compound_expr (op1, op2, complain);
    8455              : 
    8456       503197 :   if (processing_template_decl && result != error_mark_node)
    8457              :     {
    8458       260971 :       if (overload != NULL_TREE)
    8459           52 :         return (build_min_non_dep_op_overload
    8460           52 :                 (COMPOUND_EXPR, result, overload, orig_op1, orig_op2));
    8461              : 
    8462       260919 :       return build_min_non_dep (COMPOUND_EXPR, result, orig_op1, orig_op2);
    8463              :     }
    8464              : 
    8465              :   return result;
    8466              : }
    8467              : 
    8468              : /* Like cp_build_compound_expr, but for the c-common bits.  */
    8469              : 
    8470              : tree
    8471        16534 : build_compound_expr (location_t /*loc*/, tree lhs, tree rhs)
    8472              : {
    8473        16534 :   return cp_build_compound_expr (lhs, rhs, tf_warning_or_error);
    8474              : }
    8475              : 
    8476              : /* Build a compound expression.  */
    8477              : 
    8478              : tree
    8479       645284 : cp_build_compound_expr (tree lhs, tree rhs, tsubst_flags_t complain)
    8480              : {
    8481       645284 :   lhs = convert_to_void (lhs, ICV_LEFT_OF_COMMA, complain);
    8482              : 
    8483       645284 :   if (lhs == error_mark_node || rhs == error_mark_node)
    8484              :     return error_mark_node;
    8485              : 
    8486       645281 :   if (TREE_CODE (lhs) == EXCESS_PRECISION_EXPR)
    8487            0 :     lhs = TREE_OPERAND (lhs, 0);
    8488       645281 :   tree eptype = NULL_TREE;
    8489       645281 :   if (TREE_CODE (rhs) == EXCESS_PRECISION_EXPR)
    8490              :     {
    8491            3 :       eptype = TREE_TYPE (rhs);
    8492            3 :       rhs = TREE_OPERAND (rhs, 0);
    8493              :     }
    8494              : 
    8495       645281 :   if (TREE_CODE (rhs) == TARGET_EXPR)
    8496              :     {
    8497              :       /* If the rhs is a TARGET_EXPR, then build the compound
    8498              :          expression inside the target_expr's initializer. This
    8499              :          helps the compiler to eliminate unnecessary temporaries.  */
    8500        30479 :       tree init = TARGET_EXPR_INITIAL (rhs);
    8501              : 
    8502        30479 :       init = build2 (COMPOUND_EXPR, TREE_TYPE (init), lhs, init);
    8503        30479 :       TARGET_EXPR_INITIAL (rhs) = init;
    8504              : 
    8505        30479 :       if (eptype)
    8506            0 :         rhs = build1 (EXCESS_PRECISION_EXPR, eptype, rhs);
    8507        30479 :       return rhs;
    8508              :     }
    8509              : 
    8510       614802 :   rhs = resolve_nondeduced_context (rhs, complain);
    8511              : 
    8512       614802 :   if (type_unknown_p (rhs))
    8513              :     {
    8514           33 :       if (complain & tf_error)
    8515           51 :         error_at (cp_expr_loc_or_input_loc (rhs),
    8516              :                   "no context to resolve type of %qE", rhs);
    8517           33 :       return error_mark_node;
    8518              :     }
    8519              : 
    8520       614769 :   tree ret = build2 (COMPOUND_EXPR, TREE_TYPE (rhs), lhs, rhs);
    8521       614769 :   if (eptype)
    8522            3 :     ret = build1 (EXCESS_PRECISION_EXPR, eptype, ret);
    8523              :   return ret;
    8524              : }
    8525              : 
    8526              : /* Issue a diagnostic message if casting from SRC_TYPE to DEST_TYPE
    8527              :    casts away constness.  CAST gives the type of cast.  Returns true
    8528              :    if the cast is ill-formed, false if it is well-formed.
    8529              : 
    8530              :    ??? This function warns for casting away any qualifier not just
    8531              :    const.  We would like to specify exactly what qualifiers are casted
    8532              :    away.
    8533              : */
    8534              : 
    8535              : static bool
    8536       775495 : check_for_casting_away_constness (location_t loc, tree src_type,
    8537              :                                   tree dest_type, enum tree_code cast,
    8538              :                                   tsubst_flags_t complain)
    8539              : {
    8540              :   /* C-style casts are allowed to cast away constness.  With
    8541              :      WARN_CAST_QUAL, we still want to issue a warning.  */
    8542       775495 :   if (cast == CAST_EXPR && !warn_cast_qual)
    8543              :     return false;
    8544              : 
    8545       617514 :   if (!casts_away_constness (src_type, dest_type, complain))
    8546              :     return false;
    8547              : 
    8548          400 :   switch (cast)
    8549              :     {
    8550          343 :     case CAST_EXPR:
    8551          343 :       if (complain & tf_warning)
    8552          343 :         warning_at (loc, OPT_Wcast_qual,
    8553              :                     "cast from type %qT to type %qT casts away qualifiers",
    8554              :                     src_type, dest_type);
    8555              :       return false;
    8556              : 
    8557           36 :     case STATIC_CAST_EXPR:
    8558           36 :       if (complain & tf_error)
    8559           24 :         error_at (loc, "%<static_cast%> from type %qT to type %qT casts "
    8560              :                   "away qualifiers",
    8561              :                   src_type, dest_type);
    8562              :       return true;
    8563              : 
    8564           21 :     case REINTERPRET_CAST_EXPR:
    8565           21 :       if (complain & tf_error)
    8566           15 :         error_at (loc, "%<reinterpret_cast%> from type %qT to type %qT "
    8567              :                   "casts away qualifiers",
    8568              :                   src_type, dest_type);
    8569              :       return true;
    8570              : 
    8571            0 :     default:
    8572            0 :       gcc_unreachable();
    8573              :     }
    8574              : }
    8575              : 
    8576              : /* Warns if the cast from expression EXPR to type TYPE is useless.  */
    8577              : void
    8578     49775692 : maybe_warn_about_useless_cast (location_t loc, tree type, tree expr,
    8579              :                                tsubst_flags_t complain)
    8580              : {
    8581     49775692 :   if (warn_useless_cast
    8582          152 :       && complain & tf_warning)
    8583              :     {
    8584          152 :       if (TYPE_REF_P (type)
    8585          152 :           ? ((TYPE_REF_IS_RVALUE (type)
    8586           86 :               ? xvalue_p (expr) : lvalue_p (expr))
    8587          172 :              && same_type_p (TREE_TYPE (expr), TREE_TYPE (type)))
    8588              :           /* Don't warn when converting a class object to a non-reference type,
    8589              :              because that's a common way to create a temporary.  */
    8590           66 :           : (!glvalue_p (expr) && same_type_p (TREE_TYPE (expr), type)))
    8591           96 :         warning_at (loc, OPT_Wuseless_cast,
    8592              :                     "useless cast to type %q#T", type);
    8593              :     }
    8594     49775692 : }
    8595              : 
    8596              : /* Warns if the cast ignores cv-qualifiers on TYPE.  */
    8597              : static void
    8598     49769527 : maybe_warn_about_cast_ignoring_quals (location_t loc, tree type,
    8599              :                                       tsubst_flags_t complain)
    8600              : {
    8601     49769527 :   if (warn_ignored_qualifiers
    8602       273897 :       && complain & tf_warning
    8603       273408 :       && !CLASS_TYPE_P (type)
    8604     50037613 :       && (cp_type_quals (type) & (TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE)))
    8605           36 :     warning_at (loc, OPT_Wignored_qualifiers,
    8606              :                 "type qualifiers ignored on cast result type");
    8607     49769527 : }
    8608              : 
    8609              : /* Convert EXPR (an expression with pointer-to-member type) to TYPE
    8610              :    (another pointer-to-member type in the same hierarchy) and return
    8611              :    the converted expression.  If ALLOW_INVERSE_P is permitted, a
    8612              :    pointer-to-derived may be converted to pointer-to-base; otherwise,
    8613              :    only the other direction is permitted.  If C_CAST_P is true, this
    8614              :    conversion is taking place as part of a C-style cast.  */
    8615              : 
    8616              : tree
    8617        28074 : convert_ptrmem (tree type, tree expr, bool allow_inverse_p,
    8618              :                 bool c_cast_p, tsubst_flags_t complain)
    8619              : {
    8620        28074 :   if (same_type_p (type, TREE_TYPE (expr)))
    8621              :     return expr;
    8622              : 
    8623        28074 :   if (TYPE_PTRDATAMEM_P (type))
    8624              :     {
    8625          382 :       tree obase = TYPE_PTRMEM_CLASS_TYPE (TREE_TYPE (expr));
    8626          382 :       tree nbase = TYPE_PTRMEM_CLASS_TYPE (type);
    8627          382 :       tree delta = (get_delta_difference
    8628          382 :                     (obase, nbase,
    8629              :                      allow_inverse_p, c_cast_p, complain));
    8630              : 
    8631          382 :       if (delta == error_mark_node)
    8632              :         return error_mark_node;
    8633              : 
    8634          376 :       if (!same_type_p (obase, nbase))
    8635              :         {
    8636          293 :           if (TREE_CODE (expr) == PTRMEM_CST)
    8637          157 :             expr = cplus_expand_constant (expr);
    8638              : 
    8639          293 :           tree cond = cp_build_binary_op (input_location, EQ_EXPR, expr,
    8640          293 :                                           build_int_cst (TREE_TYPE (expr), -1),
    8641              :                                           complain);
    8642          293 :           tree op1 = build_nop (ptrdiff_type_node, expr);
    8643          293 :           tree op2 = cp_build_binary_op (input_location, PLUS_EXPR, op1, delta,
    8644              :                                          complain);
    8645              : 
    8646          293 :           expr = fold_build3_loc (input_location,
    8647              :                                   COND_EXPR, ptrdiff_type_node, cond, op1, op2);
    8648              :         }
    8649              : 
    8650          376 :       return build_nop (type, expr);
    8651              :     }
    8652              :   else
    8653        27692 :     return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr,
    8654        27692 :                              allow_inverse_p, c_cast_p, complain);
    8655              : }
    8656              : 
    8657              : /* Perform a static_cast from EXPR to TYPE.  When C_CAST_P is true,
    8658              :    this static_cast is being attempted as one of the possible casts
    8659              :    allowed by a C-style cast.  (In that case, accessibility of base
    8660              :    classes is not considered, and it is OK to cast away
    8661              :    constness.)  Return the result of the cast.  *VALID_P is set to
    8662              :    indicate whether or not the cast was valid.  */
    8663              : 
    8664              : static tree
    8665     49294804 : build_static_cast_1 (location_t loc, tree type, tree expr, bool c_cast_p,
    8666              :                      bool *valid_p, tsubst_flags_t complain)
    8667              : {
    8668     49294804 :   tree intype;
    8669     49294804 :   tree result;
    8670     49294804 :   cp_lvalue_kind clk;
    8671              : 
    8672              :   /* Assume the cast is valid.  */
    8673     49294804 :   *valid_p = true;
    8674              : 
    8675     49294804 :   intype = unlowered_expr_type (expr);
    8676              : 
    8677              :   /* Save casted types in the function's used types hash table.  */
    8678     49294804 :   used_types_insert (type);
    8679              : 
    8680              :   /* A prvalue of non-class type is cv-unqualified.  */
    8681     49294804 :   if (!CLASS_TYPE_P (type))
    8682     46183512 :     type = cv_unqualified (type);
    8683              : 
    8684              :   /* [expr.static.cast]
    8685              : 
    8686              :      An lvalue of type "cv1 B", where B is a class type, can be cast
    8687              :      to type "reference to cv2 D", where D is a class derived (clause
    8688              :      _class.derived_) from B, if a valid standard conversion from
    8689              :      "pointer to D" to "pointer to B" exists (_conv.ptr_), cv2 is the
    8690              :      same cv-qualification as, or greater cv-qualification than, cv1,
    8691              :      and B is not a virtual base class of D.  */
    8692              :   /* We check this case before checking the validity of "TYPE t =
    8693              :      EXPR;" below because for this case:
    8694              : 
    8695              :        struct B {};
    8696              :        struct D : public B { D(const B&); };
    8697              :        extern B& b;
    8698              :        void f() { static_cast<const D&>(b); }
    8699              : 
    8700              :      we want to avoid constructing a new D.  The standard is not
    8701              :      completely clear about this issue, but our interpretation is
    8702              :      consistent with other compilers.  */
    8703     49294804 :   if (TYPE_REF_P (type)
    8704      5477640 :       && CLASS_TYPE_P (TREE_TYPE (type))
    8705      3617085 :       && CLASS_TYPE_P (intype)
    8706      3617068 :       && (TYPE_REF_IS_RVALUE (type) || lvalue_p (expr))
    8707      3595819 :       && DERIVED_FROM_P (intype, TREE_TYPE (type))
    8708      3565370 :       && can_convert (build_pointer_type (TYPE_MAIN_VARIANT (intype)),
    8709      3565370 :                       build_pointer_type (TYPE_MAIN_VARIANT
    8710              :                                           (TREE_TYPE (type))),
    8711              :                       complain)
    8712     52860174 :       && (c_cast_p
    8713      3565346 :           || at_least_as_qualified_p (TREE_TYPE (type), intype)))
    8714              :     {
    8715      3565370 :       tree base;
    8716              : 
    8717      3565370 :       if (processing_template_decl)
    8718              :         return expr;
    8719              : 
    8720              :       /* There is a standard conversion from "D*" to "B*" even if "B"
    8721              :          is ambiguous or inaccessible.  If this is really a
    8722              :          static_cast, then we check both for inaccessibility and
    8723              :          ambiguity.  However, if this is a static_cast being performed
    8724              :          because the user wrote a C-style cast, then accessibility is
    8725              :          not considered.  */
    8726      6683524 :       base = lookup_base (TREE_TYPE (type), intype,
    8727              :                           c_cast_p ? ba_unique : ba_check,
    8728              :                           NULL, complain);
    8729      3341774 :       expr = cp_build_addr_expr (expr, complain);
    8730              : 
    8731      3341774 :       if (sanitize_flags_p (SANITIZE_VPTR))
    8732              :         {
    8733          475 :           tree ubsan_check
    8734          475 :             = cp_ubsan_maybe_instrument_downcast (loc, type,
    8735              :                                                   intype, expr);
    8736          475 :           if (ubsan_check)
    8737      3341774 :             expr = ubsan_check;
    8738              :         }
    8739              : 
    8740              :       /* Convert from "B*" to "D*".  This function will check that "B"
    8741              :          is not a virtual base of "D".  Even if we don't have a guarantee
    8742              :          that expr is NULL, if the static_cast is to a reference type,
    8743              :          it is UB if it would be NULL, so omit the non-NULL check.  */
    8744      3341774 :       expr = build_base_path (MINUS_EXPR, expr, base,
    8745              :                               /*nonnull=*/flag_delete_null_pointer_checks,
    8746              :                               complain);
    8747              : 
    8748              :       /* Convert the pointer to a reference -- but then remember that
    8749              :          there are no expressions with reference type in C++.
    8750              : 
    8751              :          We call rvalue so that there's an actual tree code
    8752              :          (NON_LVALUE_EXPR) for the static_cast; otherwise, if the operand
    8753              :          is a variable with the same type, the conversion would get folded
    8754              :          away, leaving just the variable and causing lvalue_kind to give
    8755              :          the wrong answer.  */
    8756      3341774 :       expr = cp_fold_convert (type, expr);
    8757              : 
    8758              :       /* When -fsanitize=null, make sure to diagnose reference binding to
    8759              :          NULL even when the reference is converted to pointer later on.  */
    8760      3341774 :       if (sanitize_flags_p (SANITIZE_NULL)
    8761          481 :           && TREE_CODE (expr) == COND_EXPR
    8762            6 :           && TREE_OPERAND (expr, 2)
    8763            6 :           && TREE_CODE (TREE_OPERAND (expr, 2)) == INTEGER_CST
    8764      3341780 :           && TREE_TYPE (TREE_OPERAND (expr, 2)) == type)
    8765            6 :         ubsan_maybe_instrument_reference (&TREE_OPERAND (expr, 2));
    8766              : 
    8767      3341774 :       return convert_from_reference (rvalue (expr));
    8768              :     }
    8769              : 
    8770              :   /* "A glvalue of type cv1 T1 can be cast to type rvalue reference to
    8771              :      cv2 T2 if cv2 T2 is reference-compatible with cv1 T1 (8.5.3)."  */
    8772     45729434 :   if (TYPE_REF_P (type)
    8773      1912270 :       && TYPE_REF_IS_RVALUE (type)
    8774       796964 :       && (clk = real_lvalue_p (expr))
    8775       785854 :       && reference_compatible_p (TREE_TYPE (type), intype)
    8776     46515285 :       && (c_cast_p || at_least_as_qualified_p (TREE_TYPE (type), intype)))
    8777              :     {
    8778       785851 :       if (processing_template_decl)
    8779              :         return expr;
    8780       785355 :       if (clk == clk_ordinary)
    8781              :         {
    8782              :           /* Handle the (non-bit-field) lvalue case here by casting to
    8783              :              lvalue reference and then changing it to an rvalue reference.
    8784              :              Casting an xvalue to rvalue reference will be handled by the
    8785              :              main code path.  */
    8786       785352 :           tree lref = cp_build_reference_type (TREE_TYPE (type), false);
    8787       785352 :           result = (perform_direct_initialization_if_possible
    8788       785352 :                     (lref, expr, c_cast_p, complain));
    8789       785352 :           result = build1 (NON_LVALUE_EXPR, type, result);
    8790       785352 :           return convert_from_reference (result);
    8791              :         }
    8792              :       else
    8793              :         /* For a bit-field or packed field, bind to a temporary.  */
    8794            3 :         expr = rvalue (expr);
    8795              :     }
    8796              : 
    8797              :   /* Resolve overloaded address here rather than once in
    8798              :      implicit_conversion and again in the inverse code below.  */
    8799     44943586 :   if (TYPE_PTRMEMFUNC_P (type) && type_unknown_p (expr))
    8800              :     {
    8801           21 :       expr = instantiate_type (type, expr, complain);
    8802           21 :       intype = TREE_TYPE (expr);
    8803              :     }
    8804              : 
    8805              :   /* [expr.static.cast]
    8806              : 
    8807              :      Any expression can be explicitly converted to type cv void.  */
    8808     44943586 :   if (VOID_TYPE_P (type))
    8809              :     {
    8810       554431 :       if (TREE_CODE (expr) == EXCESS_PRECISION_EXPR)
    8811            0 :         expr = TREE_OPERAND (expr, 0);
    8812       554431 :       return convert_to_void (expr, ICV_CAST, complain);
    8813              :     }
    8814              : 
    8815              :   /* [class.abstract]
    8816              :      An abstract class shall not be used ... as the type of an explicit
    8817              :      conversion.  */
    8818     44389155 :   if (abstract_virtuals_error (ACU_CAST, type, complain))
    8819            6 :     return error_mark_node;
    8820              : 
    8821              :   /* [expr.static.cast]
    8822              : 
    8823              :      An expression e can be explicitly converted to a type T using a
    8824              :      static_cast of the form static_cast<T>(e) if the declaration T
    8825              :      t(e);" is well-formed, for some invented temporary variable
    8826              :      t.  */
    8827     44389149 :   result = perform_direct_initialization_if_possible (type, expr,
    8828              :                                                       c_cast_p, complain);
    8829              :   /* P1975 allows static_cast<Aggr>(42), as well as static_cast<T[5]>(42),
    8830              :      which initialize the first element of the aggregate.  We need to handle
    8831              :      the array case specifically.  */
    8832     44389149 :   if (result == NULL_TREE
    8833      4549283 :       && cxx_dialect >= cxx20
    8834      3221874 :       && TREE_CODE (type) == ARRAY_TYPE)
    8835              :     {
    8836              :       /* Create { EXPR } and perform direct-initialization from it.  */
    8837           15 :       tree e = build_constructor_single (init_list_type_node, NULL_TREE, expr);
    8838           15 :       CONSTRUCTOR_IS_DIRECT_INIT (e) = true;
    8839           15 :       CONSTRUCTOR_IS_PAREN_INIT (e) = true;
    8840           15 :       result = perform_direct_initialization_if_possible (type, e, c_cast_p,
    8841              :                                                           complain);
    8842              :     }
    8843      4549283 :   if (result)
    8844              :     {
    8845     39839881 :       if (processing_template_decl)
    8846              :         return expr;
    8847              : 
    8848     39164398 :       result = convert_from_reference (result);
    8849              : 
    8850              :       /* [expr.static.cast]
    8851              : 
    8852              :          If T is a reference type, the result is an lvalue; otherwise,
    8853              :          the result is an rvalue.  */
    8854     39164398 :       if (!TYPE_REF_P (type))
    8855              :         {
    8856     38038073 :           result = rvalue (result);
    8857              : 
    8858     38038073 :           if (result == expr && SCALAR_TYPE_P (type))
    8859              :             /* Leave some record of the cast.  */
    8860      2307100 :             result = build_nop (type, expr);
    8861              :         }
    8862     39164398 :       return result;
    8863              :     }
    8864              : 
    8865              :   /* [expr.static.cast]
    8866              : 
    8867              :      The inverse of any standard conversion sequence (clause _conv_),
    8868              :      other than the lvalue-to-rvalue (_conv.lval_), array-to-pointer
    8869              :      (_conv.array_), function-to-pointer (_conv.func_), and boolean
    8870              :      (_conv.bool_) conversions, can be performed explicitly using
    8871              :      static_cast subject to the restriction that the explicit
    8872              :      conversion does not cast away constness (_expr.const.cast_), and
    8873              :      the following additional rules for specific cases:  */
    8874              :   /* For reference, the conversions not excluded are: integral
    8875              :      promotions, floating-point promotion, integral conversions,
    8876              :      floating-point conversions, floating-integral conversions,
    8877              :      pointer conversions, and pointer to member conversions.  */
    8878              :   /* DR 128
    8879              : 
    8880              :      A value of integral _or enumeration_ type can be explicitly
    8881              :      converted to an enumeration type.  */
    8882              :   /* The effect of all that is that any conversion between any two
    8883              :      types which are integral, floating, or enumeration types can be
    8884              :      performed.  */
    8885      4549268 :   if ((INTEGRAL_OR_ENUMERATION_TYPE_P (type)
    8886      2498180 :        || SCALAR_FLOAT_TYPE_P (type))
    8887      2135945 :       && (INTEGRAL_OR_ENUMERATION_TYPE_P (intype)
    8888       186721 :           || SCALAR_FLOAT_TYPE_P (intype)))
    8889              :     {
    8890      2033473 :       if (processing_template_decl)
    8891              :         return expr;
    8892      1943967 :       if (TREE_CODE (expr) == EXCESS_PRECISION_EXPR)
    8893            0 :         expr = TREE_OPERAND (expr, 0);
    8894              :       /* [expr.static.cast]: "If the value is not a bit-field, the result
    8895              :          refers to the object or the specified base class subobject thereof;
    8896              :          otherwise, the lvalue-to-rvalue conversion is applied to the
    8897              :          bit-field and the resulting prvalue is used as the operand of the
    8898              :          static_cast."  There are no prvalue bit-fields; the l-to-r conversion
    8899              :          will give us an object of the underlying type of the bit-field.  */
    8900      1943967 :       expr = decay_conversion (expr, complain);
    8901      1943967 :       return ocp_convert (type, expr, CONV_C_CAST, LOOKUP_NORMAL, complain);
    8902              :     }
    8903              : 
    8904       771464 :   if (TYPE_PTR_P (type) && TYPE_PTR_P (intype)
    8905       766996 :       && CLASS_TYPE_P (TREE_TYPE (type))
    8906       182359 :       && CLASS_TYPE_P (TREE_TYPE (intype))
    8907      2548576 :       && can_convert (build_pointer_type (TYPE_MAIN_VARIANT
    8908              :                                           (TREE_TYPE (intype))),
    8909        32781 :                       build_pointer_type (TYPE_MAIN_VARIANT
    8910              :                                           (TREE_TYPE (type))),
    8911              :                       complain))
    8912              :     {
    8913        32442 :       tree base;
    8914              : 
    8915        32442 :       if (processing_template_decl)
    8916              :         return expr;
    8917              : 
    8918        32424 :       if (!c_cast_p
    8919        32424 :           && check_for_casting_away_constness (loc, intype, type,
    8920              :                                                STATIC_CAST_EXPR,
    8921              :                                                complain))
    8922            6 :         return error_mark_node;
    8923        64297 :       base = lookup_base (TREE_TYPE (type), TREE_TYPE (intype),
    8924              :                           c_cast_p ? ba_unique : ba_check,
    8925              :                           NULL, complain);
    8926        32418 :       expr = build_base_path (MINUS_EXPR, expr, base, /*nonnull=*/false,
    8927              :                               complain);
    8928              : 
    8929        32418 :       if (sanitize_flags_p (SANITIZE_VPTR))
    8930              :         {
    8931           43 :           tree ubsan_check
    8932           43 :             = cp_ubsan_maybe_instrument_downcast (loc, type,
    8933              :                                                   intype, expr);
    8934           43 :           if (ubsan_check)
    8935        32418 :             expr = ubsan_check;
    8936              :         }
    8937              : 
    8938        32418 :       return cp_fold_convert (type, expr);
    8939              :     }
    8940              : 
    8941           89 :   if ((TYPE_PTRDATAMEM_P (type) && TYPE_PTRDATAMEM_P (intype))
    8942      2483353 :       || (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype)))
    8943              :     {
    8944          232 :       tree c1;
    8945          232 :       tree c2;
    8946          232 :       tree t1;
    8947          232 :       tree t2;
    8948              : 
    8949          232 :       c1 = TYPE_PTRMEM_CLASS_TYPE (intype);
    8950          232 :       c2 = TYPE_PTRMEM_CLASS_TYPE (type);
    8951              : 
    8952          232 :       if (TYPE_PTRDATAMEM_P (type))
    8953              :         {
    8954           89 :           t1 = (build_ptrmem_type
    8955           89 :                 (c1,
    8956           89 :                  TYPE_MAIN_VARIANT (TYPE_PTRMEM_POINTED_TO_TYPE (intype))));
    8957           89 :           t2 = (build_ptrmem_type
    8958           89 :                 (c2,
    8959           89 :                  TYPE_MAIN_VARIANT (TYPE_PTRMEM_POINTED_TO_TYPE (type))));
    8960              :         }
    8961              :       else
    8962              :         {
    8963              :           t1 = intype;
    8964              :           t2 = type;
    8965              :         }
    8966          232 :       if (can_convert (t1, t2, complain) || can_convert (t2, t1, complain))
    8967              :         {
    8968          154 :           if (!c_cast_p
    8969          154 :               && check_for_casting_away_constness (loc, intype, type,
    8970              :                                                    STATIC_CAST_EXPR,
    8971              :                                                    complain))
    8972            9 :             return error_mark_node;
    8973          145 :           if (processing_template_decl)
    8974              :             return expr;
    8975          145 :           return convert_ptrmem (type, expr, /*allow_inverse_p=*/1,
    8976          145 :                                  c_cast_p, complain);
    8977              :         }
    8978              :     }
    8979              : 
    8980              :   /* [expr.static.cast]
    8981              : 
    8982              :      An rvalue of type "pointer to cv void" can be explicitly
    8983              :      converted to a pointer to object type.  A value of type pointer
    8984              :      to object converted to "pointer to cv void" and back to the
    8985              :      original pointer type will have its original value.  */
    8986      2483199 :   if (TYPE_PTR_P (intype)
    8987       831736 :       && VOID_TYPE_P (TREE_TYPE (intype))
    8988      3181598 :       && TYPE_PTROB_P (type))
    8989              :     {
    8990       666153 :       if (!c_cast_p
    8991       666153 :           && check_for_casting_away_constness (loc, intype, type,
    8992              :                                                STATIC_CAST_EXPR,
    8993              :                                                complain))
    8994           21 :         return error_mark_node;
    8995       666132 :       if (processing_template_decl)
    8996              :         return expr;
    8997       582941 :       return build_nop (type, expr);
    8998              :     }
    8999              : 
    9000      1817046 :   *valid_p = false;
    9001      1817046 :   return error_mark_node;
    9002              : }
    9003              : 
    9004              : /* Return an expression representing static_cast<TYPE>(EXPR).  */
    9005              : 
    9006              : tree
    9007     16704083 : build_static_cast (location_t loc, tree type, tree oexpr,
    9008              :                    tsubst_flags_t complain)
    9009              : {
    9010     16704083 :   tree expr = oexpr;
    9011     16704083 :   tree result;
    9012     16704083 :   bool valid_p;
    9013              : 
    9014     16704083 :   if (type == error_mark_node || expr == error_mark_node)
    9015              :     return error_mark_node;
    9016              : 
    9017     16704000 :   bool dependent = (dependent_type_p (type)
    9018     16704000 :                     || type_dependent_expression_p (expr));
    9019     11644729 :   if (dependent)
    9020              :     {
    9021      6131598 :     tmpl:
    9022      6131598 :       expr = build_min (STATIC_CAST_EXPR, type, oexpr);
    9023              :       /* We don't know if it will or will not have side effects.  */
    9024      6131598 :       TREE_SIDE_EFFECTS (expr) = 1;
    9025      6131598 :       result = convert_from_reference (expr);
    9026      6131598 :       protected_set_expr_location (result, loc);
    9027      6131598 :       return result;
    9028              :     }
    9029              : 
    9030              :   /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
    9031              :      Strip such NOP_EXPRs if VALUE is being used in non-lvalue context.  */
    9032     11644729 :   if (!TYPE_REF_P (type)
    9033      6168183 :       && TREE_CODE (expr) == NOP_EXPR
    9034     11751790 :       && TREE_TYPE (expr) == TREE_TYPE (TREE_OPERAND (expr, 0)))
    9035           50 :     expr = TREE_OPERAND (expr, 0);
    9036              : 
    9037     11644729 :   result = build_static_cast_1 (loc, type, expr, /*c_cast_p=*/false,
    9038              :                                 &valid_p, complain);
    9039     11644729 :   if (valid_p)
    9040              :     {
    9041     11641413 :       if (result != error_mark_node)
    9042              :         {
    9043     11641304 :           maybe_warn_about_useless_cast (loc, type, expr, complain);
    9044     11641304 :           maybe_warn_about_cast_ignoring_quals (loc, type, complain);
    9045              :         }
    9046     11641413 :       if (processing_template_decl)
    9047      1072327 :         goto tmpl;
    9048     10569086 :       protected_set_expr_location (result, loc);
    9049     10569086 :       return result;
    9050              :     }
    9051              : 
    9052         3316 :   if (complain & tf_error)
    9053              :     {
    9054          162 :       auto_diagnostic_group d;
    9055          162 :       error_at (loc, "invalid %<static_cast%> from type %qT to type %qT",
    9056          162 :                 TREE_TYPE (expr), type);
    9057          162 :       if ((TYPE_PTR_P (type) || TYPE_REF_P (type))
    9058          120 :           && CLASS_TYPE_P (TREE_TYPE (type))
    9059          191 :             && !COMPLETE_TYPE_P (TREE_TYPE (type)))
    9060           17 :         inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (TREE_TYPE (type))),
    9061           17 :                 "class type %qT is incomplete", TREE_TYPE (type));
    9062          162 :       tree expr_type = TREE_TYPE (expr);
    9063          162 :       if (TYPE_PTR_P (expr_type))
    9064           35 :         expr_type = TREE_TYPE (expr_type);
    9065          162 :       if (CLASS_TYPE_P (expr_type) && !COMPLETE_TYPE_P (expr_type))
    9066           12 :         inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (expr_type)),
    9067              :                 "class type %qT is incomplete", expr_type);
    9068          162 :     }
    9069         3316 :   return error_mark_node;
    9070              : }
    9071              : 
    9072              : /* EXPR is an expression with member function or pointer-to-member
    9073              :    function type.  TYPE is a pointer type.  Converting EXPR to TYPE is
    9074              :    not permitted by ISO C++, but we accept it in some modes.  If we
    9075              :    are not in one of those modes, issue a diagnostic.  Return the
    9076              :    converted expression.  */
    9077              : 
    9078              : tree
    9079          163 : convert_member_func_to_ptr (tree type, tree expr, tsubst_flags_t complain)
    9080              : {
    9081          163 :   tree intype;
    9082          163 :   tree decl;
    9083              : 
    9084          163 :   intype = TREE_TYPE (expr);
    9085          163 :   gcc_assert (TYPE_PTRMEMFUNC_P (intype)
    9086              :               || TREE_CODE (intype) == METHOD_TYPE);
    9087              : 
    9088          163 :   if (!(complain & tf_warning_or_error))
    9089            0 :     return error_mark_node;
    9090              : 
    9091          163 :   location_t loc = cp_expr_loc_or_input_loc (expr);
    9092              : 
    9093          163 :   if (pedantic || warn_pmf2ptr)
    9094          203 :     pedwarn (loc, pedantic ? OPT_Wpedantic : OPT_Wpmf_conversions,
    9095              :              "converting from %qH to %qI", intype, type);
    9096              : 
    9097          163 :   STRIP_ANY_LOCATION_WRAPPER (expr);
    9098              : 
    9099          163 :   if (TREE_CODE (intype) == METHOD_TYPE)
    9100           71 :     expr = build_addr_func (expr, complain);
    9101           92 :   else if (TREE_CODE (expr) == PTRMEM_CST)
    9102           74 :     expr = build_address (PTRMEM_CST_MEMBER (expr));
    9103              :   else
    9104              :     {
    9105           18 :       decl = maybe_dummy_object (TYPE_PTRMEM_CLASS_TYPE (intype), 0);
    9106           18 :       decl = build_address (decl);
    9107           18 :       expr = get_member_function_from_ptrfunc (&decl, expr, complain);
    9108              :     }
    9109              : 
    9110          163 :   if (expr == error_mark_node)
    9111              :     return error_mark_node;
    9112              : 
    9113          163 :   expr = build_nop (type, expr);
    9114          163 :   SET_EXPR_LOCATION (expr, loc);
    9115          163 :   return expr;
    9116              : }
    9117              : 
    9118              : /* Build a NOP_EXPR to TYPE, but mark it as a reinterpret_cast so that
    9119              :    constexpr evaluation knows to reject it.  */
    9120              : 
    9121              : static tree
    9122       112139 : build_nop_reinterpret (tree type, tree expr)
    9123              : {
    9124       112139 :   tree ret = build_nop (type, expr);
    9125       112139 :   if (ret != expr)
    9126       112139 :     REINTERPRET_CAST_P (ret) = true;
    9127       112139 :   return ret;
    9128              : }
    9129              : 
    9130              : /* Return a representation for a reinterpret_cast from EXPR to TYPE.
    9131              :    If C_CAST_P is true, this reinterpret cast is being done as part of
    9132              :    a C-style cast.  If VALID_P is non-NULL, *VALID_P is set to
    9133              :    indicate whether or not reinterpret_cast was valid.  */
    9134              : 
    9135              : static tree
    9136      1962082 : build_reinterpret_cast_1 (location_t loc, tree type, tree expr,
    9137              :                           bool c_cast_p, bool *valid_p,
    9138              :                           tsubst_flags_t complain)
    9139              : {
    9140      1962082 :   tree intype;
    9141              : 
    9142              :   /* Assume the cast is invalid.  */
    9143      1962082 :   if (valid_p)
    9144      1813786 :     *valid_p = true;
    9145              : 
    9146      1962082 :   if (type == error_mark_node || error_operand_p (expr))
    9147              :     return error_mark_node;
    9148              : 
    9149      1962082 :   intype = TREE_TYPE (expr);
    9150              : 
    9151              :   /* Save casted types in the function's used types hash table.  */
    9152      1962082 :   used_types_insert (type);
    9153              : 
    9154              :   /* A prvalue of non-class type is cv-unqualified.  */
    9155      1962082 :   if (!CLASS_TYPE_P (type))
    9156      1962073 :     type = cv_unqualified (type);
    9157              : 
    9158              :   /* [expr.reinterpret.cast]
    9159              :      A glvalue of type T1, designating an object x, can be cast to the type
    9160              :      "reference to T2" if an expression of type "pointer to T1" can be
    9161              :      explicitly converted to the type "pointer to T2" using a reinterpret_cast.
    9162              :      The result is that of *reinterpret_cast<T2 *>(p) where p is a pointer to x
    9163              :      of type "pointer to T1". No temporary is created, no copy is made, and no
    9164              :      constructors (11.4.4) or conversion functions (11.4.7) are called.  */
    9165      1962082 :   if (TYPE_REF_P (type))
    9166              :     {
    9167         9522 :       if (!glvalue_p (expr))
    9168              :         {
    9169            9 :           if (complain & tf_error)
    9170            9 :             error_at (loc, "invalid cast of a prvalue expression of type "
    9171              :                       "%qT to type %qT",
    9172              :                       intype, type);
    9173            9 :           return error_mark_node;
    9174              :         }
    9175              : 
    9176              :       /* Warn about a reinterpret_cast from "A*" to "B&" if "A" and
    9177              :          "B" are related class types; the reinterpret_cast does not
    9178              :          adjust the pointer.  */
    9179         9513 :       if (TYPE_PTR_P (intype)
    9180            3 :           && (complain & tf_warning)
    9181         9516 :           && (comptypes (TREE_TYPE (intype), TREE_TYPE (type),
    9182              :                          COMPARE_BASE | COMPARE_DERIVED)))
    9183            3 :         warning_at (loc, 0, "casting %qT to %qT does not dereference pointer",
    9184              :                     intype, type);
    9185              : 
    9186         9513 :       expr = cp_build_addr_expr (expr, complain);
    9187              : 
    9188         9513 :       if (warn_strict_aliasing > 2)
    9189           72 :         cp_strict_aliasing_warning (EXPR_LOCATION (expr), type, expr);
    9190              : 
    9191         9513 :       if (expr != error_mark_node)
    9192         9513 :         expr = build_reinterpret_cast_1
    9193         9513 :           (loc, build_pointer_type (TREE_TYPE (type)), expr, c_cast_p,
    9194              :            valid_p, complain);
    9195         9513 :       if (expr != error_mark_node)
    9196              :         /* cp_build_indirect_ref isn't right for rvalue refs.  */
    9197         9510 :         expr = convert_from_reference (fold_convert (type, expr));
    9198         9513 :       return expr;
    9199              :     }
    9200              : 
    9201              :   /* As a G++ extension, we consider conversions from member
    9202              :      functions, and pointers to member functions to
    9203              :      pointer-to-function and pointer-to-void types.  If
    9204              :      -Wno-pmf-conversions has not been specified,
    9205              :      convert_member_func_to_ptr will issue an error message.  */
    9206          249 :   if ((TYPE_PTRMEMFUNC_P (intype)
    9207      1952389 :        || TREE_CODE (intype) == METHOD_TYPE)
    9208          242 :       && TYPE_PTR_P (type)
    9209      1952723 :       && (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE
    9210          121 :           || VOID_TYPE_P (TREE_TYPE (type))))
    9211          154 :     return convert_member_func_to_ptr (type, expr, complain);
    9212              : 
    9213              :   /* If the cast is not to a reference type, the lvalue-to-rvalue,
    9214              :      array-to-pointer, and function-to-pointer conversions are
    9215              :      performed.  */
    9216      1952406 :   expr = decay_conversion (expr, complain);
    9217              : 
    9218              :   /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
    9219              :      Strip such NOP_EXPRs if VALUE is being used in non-lvalue context.  */
    9220      1952406 :   if (TREE_CODE (expr) == NOP_EXPR
    9221      1952406 :       && TREE_TYPE (expr) == TREE_TYPE (TREE_OPERAND (expr, 0)))
    9222          388 :     expr = TREE_OPERAND (expr, 0);
    9223              : 
    9224      1952406 :   if (error_operand_p (expr))
    9225           30 :     return error_mark_node;
    9226              : 
    9227      1952376 :   intype = TREE_TYPE (expr);
    9228              : 
    9229              :   /* [expr.reinterpret.cast]
    9230              :      A pointer can be converted to any integral type large enough to
    9231              :      hold it. ... A value of type std::nullptr_t can be converted to
    9232              :      an integral type; the conversion has the same meaning and
    9233              :      validity as a conversion of (void*)0 to the integral type.  */
    9234      1952376 :   if (CP_INTEGRAL_TYPE_P (type)
    9235       163657 :       && (TYPE_PTR_P (intype) || NULLPTR_TYPE_P (intype)))
    9236              :     {
    9237       161738 :       if (TYPE_PRECISION (type) < TYPE_PRECISION (intype))
    9238              :         {
    9239           21 :           if (complain & tf_error)
    9240           15 :             permerror (loc, "cast from %qH to %qI loses precision",
    9241              :                        intype, type);
    9242              :           else
    9243            6 :             return error_mark_node;
    9244              :         }
    9245       161732 :       if (NULLPTR_TYPE_P (intype))
    9246           98 :         return build_int_cst (type, 0);
    9247              :     }
    9248              :   /* [expr.reinterpret.cast]
    9249              :      A value of integral or enumeration type can be explicitly
    9250              :      converted to a pointer.  */
    9251      1790638 :   else if (TYPE_PTR_P (type) && INTEGRAL_OR_ENUMERATION_TYPE_P (intype))
    9252              :     /* OK */
    9253              :     ;
    9254      1756869 :   else if ((INTEGRAL_OR_ENUMERATION_TYPE_P (type)
    9255      1754935 :             || TYPE_PTR_OR_PTRMEM_P (type))
    9256      1869565 :            && same_type_p (type, intype))
    9257              :     /* DR 799 */
    9258          525 :     return rvalue (expr);
    9259      1756344 :   else if (TYPE_PTRFN_P (type) && TYPE_PTRFN_P (intype))
    9260              :     {
    9261          267 :       if ((complain & tf_warning)
    9262          534 :           && !cxx_safe_function_type_cast_p (TREE_TYPE (type),
    9263          267 :                                              TREE_TYPE (intype)))
    9264          145 :         warning_at (loc, OPT_Wcast_function_type,
    9265              :                     "cast between incompatible function types"
    9266              :                     " from %qH to %qI", intype, type);
    9267          267 :       return build_nop_reinterpret (type, expr);
    9268              :     }
    9269      1756077 :   else if (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype))
    9270              :     {
    9271           79 :       if ((complain & tf_warning)
    9272          158 :           && !cxx_safe_function_type_cast_p
    9273           79 :                 (TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE_RAW (type)),
    9274           79 :                  TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE_RAW (intype))))
    9275           52 :         warning_at (loc, OPT_Wcast_function_type,
    9276              :                     "cast between incompatible pointer to member types"
    9277              :                     " from %qH to %qI", intype, type);
    9278           79 :       return build_nop_reinterpret (type, expr);
    9279              :     }
    9280           21 :   else if ((TYPE_PTRDATAMEM_P (type) && TYPE_PTRDATAMEM_P (intype))
    9281      1755998 :            || (TYPE_PTROBV_P (type) && TYPE_PTROBV_P (intype)))
    9282              :     {
    9283       111538 :       if (!c_cast_p
    9284       111538 :           && check_for_casting_away_constness (loc, intype, type,
    9285              :                                                REINTERPRET_CAST_EXPR,
    9286              :                                                complain))
    9287           21 :         return error_mark_node;
    9288              :       /* Warn about possible alignment problems.  */
    9289       111517 :       if ((STRICT_ALIGNMENT || warn_cast_align == 2)
    9290           24 :           && (complain & tf_warning)
    9291           24 :           && !VOID_TYPE_P (type)
    9292           24 :           && TREE_CODE (TREE_TYPE (intype)) != FUNCTION_TYPE
    9293           24 :           && COMPLETE_TYPE_P (TREE_TYPE (type))
    9294           24 :           && COMPLETE_TYPE_P (TREE_TYPE (intype))
    9295       111565 :           && min_align_of_type (TREE_TYPE (type))
    9296           24 :              > min_align_of_type (TREE_TYPE (intype)))
    9297           18 :         warning_at (loc, OPT_Wcast_align, "cast from %qH to %qI "
    9298              :                     "increases required alignment of target type",
    9299              :                     intype, type);
    9300              : 
    9301       111517 :       if (warn_strict_aliasing <= 2)
    9302              :         /* strict_aliasing_warning STRIP_NOPs its expr.  */
    9303        99683 :         cp_strict_aliasing_warning (EXPR_LOCATION (expr), type, expr);
    9304              : 
    9305       111517 :       return build_nop_reinterpret (type, expr);
    9306              :     }
    9307          297 :   else if ((TYPE_PTRFN_P (type) && TYPE_PTROBV_P (intype))
    9308      1644620 :            || (TYPE_PTRFN_P (intype) && TYPE_PTROBV_P (type)))
    9309              :     {
    9310          276 :       if (complain & tf_warning)
    9311              :         /* C++11 5.2.10 p8 says that "Converting a function pointer to an
    9312              :            object pointer type or vice versa is conditionally-supported."  */
    9313          276 :         warning_at (loc, OPT_Wconditionally_supported,
    9314              :                     "casting between pointer-to-function and "
    9315              :                     "pointer-to-object is conditionally-supported");
    9316          276 :       return build_nop_reinterpret (type, expr);
    9317              :     }
    9318      1644184 :   else if (gnu_vector_type_p (type) && scalarish_type_p (intype))
    9319      1642215 :     return convert_to_vector (type, rvalue (expr));
    9320         1969 :   else if (gnu_vector_type_p (intype)
    9321         1969 :            && INTEGRAL_OR_ENUMERATION_TYPE_P (type))
    9322         1867 :     return convert_to_integer_nofold (type, expr);
    9323              :   else
    9324              :     {
    9325          102 :       if (valid_p)
    9326           84 :         *valid_p = false;
    9327          102 :       if (complain & tf_error)
    9328           93 :         error_at (loc, "invalid cast from type %qT to type %qT",
    9329              :                   intype, type);
    9330          102 :       return error_mark_node;
    9331              :     }
    9332              : 
    9333       195403 :   expr = cp_convert (type, expr, complain);
    9334       195403 :   if (TREE_CODE (expr) == NOP_EXPR)
    9335              :     /* Mark any nop_expr that created as a reintepret_cast.  */
    9336            0 :     REINTERPRET_CAST_P (expr) = true;
    9337              :   return expr;
    9338              : }
    9339              : 
    9340              : tree
    9341       727675 : build_reinterpret_cast (location_t loc, tree type, tree expr,
    9342              :                         tsubst_flags_t complain)
    9343              : {
    9344       727675 :   tree r;
    9345              : 
    9346       727675 :   if (type == error_mark_node || expr == error_mark_node)
    9347              :     return error_mark_node;
    9348              : 
    9349       727668 :   if (processing_template_decl)
    9350              :     {
    9351       588829 :       tree t = build_min (REINTERPRET_CAST_EXPR, type, expr);
    9352              : 
    9353       588829 :       if (!TREE_SIDE_EFFECTS (t)
    9354       588829 :           && type_dependent_expression_p (expr))
    9355              :         /* There might turn out to be side effects inside expr.  */
    9356       282943 :         TREE_SIDE_EFFECTS (t) = 1;
    9357       588829 :       r = convert_from_reference (t);
    9358       588829 :       protected_set_expr_location (r, loc);
    9359       588829 :       return r;
    9360              :     }
    9361              : 
    9362       138839 :   r = build_reinterpret_cast_1 (loc, type, expr, /*c_cast_p=*/false,
    9363              :                                 /*valid_p=*/NULL, complain);
    9364       138839 :   if (r != error_mark_node)
    9365              :     {
    9366       138776 :       maybe_warn_about_useless_cast (loc, type, expr, complain);
    9367       138776 :       maybe_warn_about_cast_ignoring_quals (loc, type, complain);
    9368              :     }
    9369       138839 :   protected_set_expr_location (r, loc);
    9370       138839 :   return r;
    9371              : }
    9372              : 
    9373              : /* Perform a const_cast from EXPR to TYPE.  If the cast is valid,
    9374              :    return an appropriate expression.  Otherwise, return
    9375              :    error_mark_node.  If the cast is not valid, and COMPLAIN is true,
    9376              :    then a diagnostic will be issued.  If VALID_P is non-NULL, we are
    9377              :    performing a C-style cast, its value upon return will indicate
    9378              :    whether or not the conversion succeeded.  */
    9379              : 
    9380              : static tree
    9381     37989947 : build_const_cast_1 (location_t loc, tree dst_type, tree expr,
    9382              :                     tsubst_flags_t complain, bool *valid_p)
    9383              : {
    9384     37989947 :   tree src_type;
    9385     37989947 :   tree reference_type;
    9386              : 
    9387              :   /* Callers are responsible for handling error_mark_node as a
    9388              :      destination type.  */
    9389     37989947 :   gcc_assert (dst_type != error_mark_node);
    9390              :   /* In a template, callers should be building syntactic
    9391              :      representations of casts, not using this machinery.  */
    9392     37989947 :   gcc_assert (!processing_template_decl);
    9393              : 
    9394              :   /* Assume the conversion is invalid.  */
    9395     37989947 :   if (valid_p)
    9396     37793880 :     *valid_p = false;
    9397              : 
    9398     37989947 :   if (!INDIRECT_TYPE_P (dst_type) && !TYPE_PTRDATAMEM_P (dst_type))
    9399              :     {
    9400     36991581 :       if (complain & tf_error)
    9401            9 :         error_at (loc, "invalid use of %<const_cast%> with type %qT, "
    9402              :                   "which is not a pointer, reference, "
    9403              :                   "nor a pointer-to-data-member type", dst_type);
    9404     36991581 :       return error_mark_node;
    9405              :     }
    9406              : 
    9407       998366 :   if (TREE_CODE (TREE_TYPE (dst_type)) == FUNCTION_TYPE)
    9408              :     {
    9409         4131 :       if (complain & tf_error)
    9410            6 :         error_at (loc, "invalid use of %<const_cast%> with type %qT, "
    9411              :                   "which is a pointer or reference to a function type",
    9412              :                   dst_type);
    9413         4131 :        return error_mark_node;
    9414              :     }
    9415              : 
    9416              :   /* A prvalue of non-class type is cv-unqualified.  */
    9417       994235 :   dst_type = cv_unqualified (dst_type);
    9418              : 
    9419              :   /* Save casted types in the function's used types hash table.  */
    9420       994235 :   used_types_insert (dst_type);
    9421              : 
    9422       994235 :   src_type = TREE_TYPE (expr);
    9423              :   /* Expressions do not really have reference types.  */
    9424       994235 :   if (TYPE_REF_P (src_type))
    9425            0 :     src_type = TREE_TYPE (src_type);
    9426              : 
    9427              :   /* [expr.const.cast]
    9428              : 
    9429              :      For two object types T1 and T2, if a pointer to T1 can be explicitly
    9430              :      converted to the type "pointer to T2" using a const_cast, then the
    9431              :      following conversions can also be made:
    9432              : 
    9433              :      -- an lvalue of type T1 can be explicitly converted to an lvalue of
    9434              :      type T2 using the cast const_cast<T2&>;
    9435              : 
    9436              :      -- a glvalue of type T1 can be explicitly converted to an xvalue of
    9437              :      type T2 using the cast const_cast<T2&&>; and
    9438              : 
    9439              :      -- if T1 is a class type, a prvalue of type T1 can be explicitly
    9440              :      converted to an xvalue of type T2 using the cast const_cast<T2&&>.  */
    9441              : 
    9442       994235 :   if (TYPE_REF_P (dst_type))
    9443              :     {
    9444       125037 :       reference_type = dst_type;
    9445       125037 :       if (!TYPE_REF_IS_RVALUE (dst_type)
    9446       125037 :           ? lvalue_p (expr)
    9447         1052 :           : obvalue_p (expr))
    9448              :         /* OK.  */;
    9449              :       else
    9450              :         {
    9451           35 :           if (complain & tf_error)
    9452            9 :             error_at (loc, "invalid %<const_cast%> of an rvalue of type %qT "
    9453              :                       "to type %qT",
    9454              :                       src_type, dst_type);
    9455           35 :           return error_mark_node;
    9456              :         }
    9457       125002 :       dst_type = build_pointer_type (TREE_TYPE (dst_type));
    9458       125002 :       src_type = build_pointer_type (src_type);
    9459              :     }
    9460              :   else
    9461              :     {
    9462       869198 :       reference_type = NULL_TREE;
    9463              :       /* If the destination type is not a reference type, the
    9464              :          lvalue-to-rvalue, array-to-pointer, and function-to-pointer
    9465              :          conversions are performed.  */
    9466       869198 :       src_type = type_decays_to (src_type);
    9467       869198 :       if (src_type == error_mark_node)
    9468              :         return error_mark_node;
    9469              :     }
    9470              : 
    9471       994200 :   if (TYPE_PTR_P (src_type) || TYPE_PTRDATAMEM_P (src_type))
    9472              :     {
    9473       578170 :       if (comp_ptr_ttypes_const (dst_type, src_type, bounds_none))
    9474              :         {
    9475       339794 :           if (valid_p)
    9476              :             {
    9477       143805 :               *valid_p = true;
    9478              :               /* This cast is actually a C-style cast.  Issue a warning if
    9479              :                  the user is making a potentially unsafe cast.  */
    9480       143805 :               check_for_casting_away_constness (loc, src_type, dst_type,
    9481              :                                                 CAST_EXPR, complain);
    9482              :               /* ??? comp_ptr_ttypes_const ignores TYPE_ALIGN.  */
    9483       143805 :               if ((STRICT_ALIGNMENT || warn_cast_align == 2)
    9484            3 :                   && (complain & tf_warning)
    9485       143811 :                   && min_align_of_type (TREE_TYPE (dst_type))
    9486            3 :                      > min_align_of_type (TREE_TYPE (src_type)))
    9487            3 :                 warning_at (loc, OPT_Wcast_align, "cast from %qH to %qI "
    9488              :                             "increases required alignment of target type",
    9489              :                             src_type, dst_type);
    9490              :             }
    9491       339794 :           if (reference_type)
    9492              :             {
    9493       123936 :               expr = cp_build_addr_expr (expr, complain);
    9494       123936 :               if (expr == error_mark_node)
    9495              :                 return error_mark_node;
    9496       123918 :               expr = build_nop (reference_type, expr);
    9497       123918 :               return convert_from_reference (expr);
    9498              :             }
    9499              :           else
    9500              :             {
    9501       215858 :               expr = decay_conversion (expr, complain);
    9502       215858 :               if (expr == error_mark_node)
    9503              :                 return error_mark_node;
    9504              : 
    9505              :               /* build_c_cast puts on a NOP_EXPR to make the result not an
    9506              :                  lvalue.  Strip such NOP_EXPRs if VALUE is being used in
    9507              :                  non-lvalue context.  */
    9508       215858 :               if (TREE_CODE (expr) == NOP_EXPR
    9509       215858 :                   && TREE_TYPE (expr) == TREE_TYPE (TREE_OPERAND (expr, 0)))
    9510            3 :                 expr = TREE_OPERAND (expr, 0);
    9511       215858 :               return build_nop (dst_type, expr);
    9512              :             }
    9513              :         }
    9514       238376 :       else if (valid_p
    9515       476704 :                && !at_least_as_qualified_p (TREE_TYPE (dst_type),
    9516       238328 :                                             TREE_TYPE (src_type)))
    9517        15111 :         check_for_casting_away_constness (loc, src_type, dst_type,
    9518              :                                           CAST_EXPR, complain);
    9519              :     }
    9520              : 
    9521       654406 :   if (complain & tf_error)
    9522           30 :     error_at (loc, "invalid %<const_cast%> from type %qT to type %qT",
    9523              :               src_type, dst_type);
    9524       654406 :   return error_mark_node;
    9525              : }
    9526              : 
    9527              : tree
    9528       669887 : build_const_cast (location_t loc, tree type, tree expr,
    9529              :                   tsubst_flags_t complain)
    9530              : {
    9531       669887 :   tree r;
    9532              : 
    9533       669887 :   if (type == error_mark_node || error_operand_p (expr))
    9534              :     return error_mark_node;
    9535              : 
    9536       669879 :   if (processing_template_decl)
    9537              :     {
    9538       473812 :       tree t = build_min (CONST_CAST_EXPR, type, expr);
    9539              : 
    9540       473812 :       if (!TREE_SIDE_EFFECTS (t)
    9541       473812 :           && type_dependent_expression_p (expr))
    9542              :         /* There might turn out to be side effects inside expr.  */
    9543       366691 :         TREE_SIDE_EFFECTS (t) = 1;
    9544       473812 :       r = convert_from_reference (t);
    9545       473812 :       protected_set_expr_location (r, loc);
    9546       473812 :       return r;
    9547              :     }
    9548              : 
    9549       196067 :   r = build_const_cast_1 (loc, type, expr, complain, /*valid_p=*/NULL);
    9550       196067 :   if (r != error_mark_node)
    9551              :     {
    9552       195989 :       maybe_warn_about_useless_cast (loc, type, expr, complain);
    9553       195989 :       maybe_warn_about_cast_ignoring_quals (loc, type, complain);
    9554              :     }
    9555       196067 :   protected_set_expr_location (r, loc);
    9556       196067 :   return r;
    9557              : }
    9558              : 
    9559              : /* Like cp_build_c_cast, but for the c-common bits.  */
    9560              : 
    9561              : tree
    9562            0 : build_c_cast (location_t loc, tree type, tree expr)
    9563              : {
    9564            0 :   return cp_build_c_cast (loc, type, expr, tf_warning_or_error);
    9565              : }
    9566              : 
    9567              : /* Like the "build_c_cast" used for c-common, but using cp_expr to
    9568              :    preserve location information even for tree nodes that don't
    9569              :    support it.  */
    9570              : 
    9571              : cp_expr
    9572     10389626 : build_c_cast (location_t loc, tree type, cp_expr expr)
    9573              : {
    9574     10389626 :   cp_expr result = cp_build_c_cast (loc, type, expr, tf_warning_or_error);
    9575     10389626 :   result.set_location (loc);
    9576     10389626 :   return result;
    9577              : }
    9578              : 
    9579              : /* Build an expression representing an explicit C-style cast to type
    9580              :    TYPE of expression EXPR.  */
    9581              : 
    9582              : tree
    9583     40494263 : cp_build_c_cast (location_t loc, tree type, tree expr,
    9584              :                  tsubst_flags_t complain)
    9585              : {
    9586     40494263 :   tree value = expr;
    9587     40494263 :   tree result;
    9588     40494263 :   bool valid_p;
    9589              : 
    9590     40494263 :   if (type == error_mark_node || error_operand_p (expr))
    9591              :     return error_mark_node;
    9592              : 
    9593     40494096 :   if (processing_template_decl)
    9594              :     {
    9595      2700207 :       tree t = build_min (CAST_EXPR, type,
    9596              :                           tree_cons (NULL_TREE, value, NULL_TREE));
    9597              :       /* We don't know if it will or will not have side effects.  */
    9598      2700207 :       TREE_SIDE_EFFECTS (t) = 1;
    9599      2700207 :       return convert_from_reference (t);
    9600              :     }
    9601              : 
    9602              :   /* Casts to a (pointer to a) specific ObjC class (or 'id' or
    9603              :      'Class') should always be retained, because this information aids
    9604              :      in method lookup.  */
    9605     37793889 :   if (objc_is_object_ptr (type)
    9606     37793889 :       && objc_is_object_ptr (TREE_TYPE (expr)))
    9607            0 :     return build_nop (type, expr);
    9608              : 
    9609              :   /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
    9610              :      Strip such NOP_EXPRs if VALUE is being used in non-lvalue context.  */
    9611     37793889 :   if (!TYPE_REF_P (type)
    9612     37791729 :       && TREE_CODE (value) == NOP_EXPR
    9613     38247574 :       && TREE_TYPE (value) == TREE_TYPE (TREE_OPERAND (value, 0)))
    9614       228210 :     value = TREE_OPERAND (value, 0);
    9615              : 
    9616     37793889 :   if (TREE_CODE (type) == ARRAY_TYPE)
    9617              :     {
    9618              :       /* Allow casting from T1* to T2[] because Cfront allows it.
    9619              :          NIHCL uses it. It is not valid ISO C++ however.  */
    9620            3 :       if (TYPE_PTR_P (TREE_TYPE (expr)))
    9621              :         {
    9622            0 :           if (complain & tf_error)
    9623            0 :             permerror (loc, "ISO C++ forbids casting to an array type %qT",
    9624              :                        type);
    9625              :           else
    9626            0 :             return error_mark_node;
    9627            0 :           type = build_pointer_type (TREE_TYPE (type));
    9628              :         }
    9629              :       else
    9630              :         {
    9631            3 :           if (complain & tf_error)
    9632            3 :             error_at (loc, "ISO C++ forbids casting to an array type %qT",
    9633              :                       type);
    9634            3 :           return error_mark_node;
    9635              :         }
    9636              :     }
    9637              : 
    9638     37793886 :   if (FUNC_OR_METHOD_TYPE_P (type))
    9639              :     {
    9640           15 :       if (complain & tf_error)
    9641           15 :         error_at (loc, "invalid cast to function type %qT", type);
    9642           15 :       return error_mark_node;
    9643              :     }
    9644              : 
    9645     37793871 :   if (TYPE_PTR_P (type)
    9646       800002 :       && TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE
    9647              :       /* Casting to an integer of smaller size is an error detected elsewhere.  */
    9648       414644 :       && TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (value))
    9649              :       /* Don't warn about converting any constant.  */
    9650     38153178 :       && !TREE_CONSTANT (value))
    9651           47 :     warning_at (loc, OPT_Wint_to_pointer_cast,
    9652              :                 "cast to pointer from integer of different size");
    9653              : 
    9654              :   /* A C-style cast can be a const_cast.  */
    9655     37793871 :   result = build_const_cast_1 (loc, type, value, complain & tf_warning,
    9656              :                                &valid_p);
    9657     37793871 :   if (valid_p)
    9658              :     {
    9659       143796 :       if (result != error_mark_node)
    9660              :         {
    9661       143787 :           maybe_warn_about_useless_cast (loc, type, value, complain);
    9662       143787 :           maybe_warn_about_cast_ignoring_quals (loc, type, complain);
    9663              :         }
    9664            9 :       else if (complain & tf_error)
    9665            9 :         build_const_cast_1 (loc, type, value, tf_error, &valid_p);
    9666       143796 :       return result;
    9667              :     }
    9668              : 
    9669              :   /* Or a static cast.  */
    9670     37650075 :   result = build_static_cast_1 (loc, type, value, /*c_cast_p=*/true,
    9671              :                                 &valid_p, complain);
    9672              :   /* Or a reinterpret_cast.  */
    9673     37650075 :   if (!valid_p)
    9674      1813730 :     result = build_reinterpret_cast_1 (loc, type, value, /*c_cast_p=*/true,
    9675              :                                        &valid_p, complain);
    9676              :   /* The static_cast or reinterpret_cast may be followed by a
    9677              :      const_cast.  */
    9678     37650075 :   if (valid_p
    9679              :       /* A valid cast may result in errors if, for example, a
    9680              :          conversion to an ambiguous base class is required.  */
    9681     37650075 :       && !error_operand_p (result))
    9682              :     {
    9683     37649671 :       tree result_type;
    9684              : 
    9685     37649671 :       maybe_warn_about_useless_cast (loc, type, value, complain);
    9686     37649671 :       maybe_warn_about_cast_ignoring_quals (loc, type, complain);
    9687              : 
    9688              :       /* Non-class rvalues always have cv-unqualified type.  */
    9689     37649671 :       if (!CLASS_TYPE_P (type))
    9690     34930226 :         type = TYPE_MAIN_VARIANT (type);
    9691     37649671 :       result_type = TREE_TYPE (result);
    9692     37649671 :       if (!CLASS_TYPE_P (result_type) && !TYPE_REF_P (type))
    9693     34929138 :         result_type = TYPE_MAIN_VARIANT (result_type);
    9694              :       /* If the type of RESULT does not match TYPE, perform a
    9695              :          const_cast to make it match.  If the static_cast or
    9696              :          reinterpret_cast succeeded, we will differ by at most
    9697              :          cv-qualification, so the follow-on const_cast is guaranteed
    9698              :          to succeed.  */
    9699     37649671 :       if (!same_type_p (non_reference (type), non_reference (result_type)))
    9700              :         {
    9701            0 :           result = build_const_cast_1 (loc, type, result, tf_none, &valid_p);
    9702            0 :           gcc_assert (valid_p);
    9703              :         }
    9704     37649671 :       return result;
    9705              :     }
    9706              : 
    9707          404 :   return error_mark_node;
    9708              : }
    9709              : 
    9710              : /* Warn when a value is moved to itself with std::move.  LHS is the target,
    9711              :    RHS may be the std::move call, and LOC is the location of the whole
    9712              :    assignment.  Return true if we warned.  */
    9713              : 
    9714              : bool
    9715     27631029 : maybe_warn_self_move (location_t loc, tree lhs, tree rhs)
    9716              : {
    9717     27631029 :   if (!warn_self_move)
    9718              :     return false;
    9719              : 
    9720              :   /* C++98 doesn't know move.  */
    9721       364135 :   if (cxx_dialect < cxx11)
    9722              :     return false;
    9723              : 
    9724       344312 :   if (processing_template_decl)
    9725              :     return false;
    9726              : 
    9727        26203 :   if (!REFERENCE_REF_P (rhs)
    9728       299663 :       || TREE_CODE (TREE_OPERAND (rhs, 0)) != CALL_EXPR)
    9729              :     return false;
    9730         4620 :   tree fn = TREE_OPERAND (rhs, 0);
    9731         4620 :   if (!is_std_move_p (fn))
    9732              :     return false;
    9733              : 
    9734              :   /* Just a little helper to strip * and various NOPs.  */
    9735         6519 :   auto extract_op = [] (tree &op) {
    9736         4346 :     STRIP_NOPS (op);
    9737         5567 :     while (INDIRECT_REF_P (op))
    9738         1221 :       op = TREE_OPERAND (op, 0);
    9739         4346 :     op = maybe_undo_parenthesized_ref (op);
    9740         4346 :     STRIP_ANY_LOCATION_WRAPPER (op);
    9741         4346 :   };
    9742              : 
    9743         2173 :   tree arg = CALL_EXPR_ARG (fn, 0);
    9744         2173 :   extract_op (arg);
    9745         2173 :   if (TREE_CODE (arg) == ADDR_EXPR)
    9746         1495 :     arg = TREE_OPERAND (arg, 0);
    9747         2173 :   tree type = TREE_TYPE (lhs);
    9748         2173 :   tree orig_lhs = lhs;
    9749         2173 :   extract_op (lhs);
    9750         2173 :   if (cp_tree_equal (lhs, arg)
    9751              :       /* Also warn in a member-initializer-list, as in : i(std::move(i)).  */
    9752         2173 :       || (TREE_CODE (lhs) == FIELD_DECL
    9753          640 :           && TREE_CODE (arg) == COMPONENT_REF
    9754          305 :           && cp_tree_equal (TREE_OPERAND (arg, 0), current_class_ref)
    9755            6 :           && TREE_OPERAND (arg, 1) == lhs))
    9756          117 :     if (warning_at (loc, OPT_Wself_move,
    9757              :                     "moving %qE of type %qT to itself", orig_lhs, type))
    9758              :       return true;
    9759              : 
    9760              :   return false;
    9761              : }
    9762              : 
    9763              : /* For use from the C common bits.  */
    9764              : tree
    9765         4766 : build_modify_expr (location_t location,
    9766              :                    tree lhs, tree /*lhs_origtype*/,
    9767              :                    enum tree_code modifycode,
    9768              :                    location_t /*rhs_location*/, tree rhs,
    9769              :                    tree /*rhs_origtype*/)
    9770              : {
    9771         4766 :   return cp_build_modify_expr (location, lhs, modifycode, rhs,
    9772         4766 :                                tf_warning_or_error);
    9773              : }
    9774              : 
    9775              : /* Build an assignment expression of lvalue LHS from value RHS.
    9776              :    MODIFYCODE is the code for a binary operator that we use
    9777              :    to combine the old value of LHS with RHS to get the new value.
    9778              :    Or else MODIFYCODE is NOP_EXPR meaning do a simple assignment.
    9779              : 
    9780              :    C++: If MODIFYCODE is INIT_EXPR, then leave references unbashed.  */
    9781              : 
    9782              : tree
    9783     36028124 : cp_build_modify_expr (location_t loc, tree lhs, enum tree_code modifycode,
    9784              :                       tree rhs, tsubst_flags_t complain)
    9785              : {
    9786     36028124 :   lhs = mark_lvalue_use_nonread (lhs);
    9787              : 
    9788     36028124 :   tree result = NULL_TREE;
    9789     36028124 :   tree newrhs = rhs;
    9790     36028124 :   tree lhstype = TREE_TYPE (lhs);
    9791     36028124 :   tree olhs = lhs;
    9792     36028124 :   tree olhstype = lhstype;
    9793     36028124 :   bool plain_assign = (modifycode == NOP_EXPR);
    9794     36028124 :   bool compound_side_effects_p = false;
    9795     36028124 :   tree preeval = NULL_TREE;
    9796              : 
    9797              :   /* Avoid duplicate error messages from operands that had errors.  */
    9798     36028124 :   if (error_operand_p (lhs) || error_operand_p (rhs))
    9799           19 :     return error_mark_node;
    9800              : 
    9801     36028187 :   while (TREE_CODE (lhs) == COMPOUND_EXPR)
    9802              :     {
    9803           82 :       if (TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0)))
    9804           70 :         compound_side_effects_p = true;
    9805           82 :       lhs = TREE_OPERAND (lhs, 1);
    9806              :     }
    9807              : 
    9808              :   /* Handle control structure constructs used as "lvalues".  Note that we
    9809              :      leave COMPOUND_EXPR on the LHS because it is sequenced after the RHS.  */
    9810     36028105 :   switch (TREE_CODE (lhs))
    9811              :     {
    9812              :       /* Handle --foo = 5; as these are valid constructs in C++.  */
    9813           27 :     case PREDECREMENT_EXPR:
    9814           27 :     case PREINCREMENT_EXPR:
    9815           27 :       if (compound_side_effects_p)
    9816            9 :         newrhs = rhs = stabilize_expr (rhs, &preeval);
    9817           27 :       lhs = genericize_compound_lvalue (lhs);
    9818          173 :     maybe_add_compound:
    9819              :       /* If we had (bar, --foo) = 5; or (bar, (baz, --foo)) = 5;
    9820              :          and looked through the COMPOUND_EXPRs, readd them now around
    9821              :          the resulting lhs.  */
    9822          173 :       if (TREE_CODE (olhs) == COMPOUND_EXPR)
    9823              :         {
    9824            9 :           lhs = build2 (COMPOUND_EXPR, lhstype, TREE_OPERAND (olhs, 0), lhs);
    9825            9 :           tree *ptr = &TREE_OPERAND (lhs, 1);
    9826            9 :           for (olhs = TREE_OPERAND (olhs, 1);
    9827           12 :                TREE_CODE (olhs) == COMPOUND_EXPR;
    9828            3 :                olhs = TREE_OPERAND (olhs, 1))
    9829              :             {
    9830            3 :               *ptr = build2 (COMPOUND_EXPR, lhstype,
    9831            3 :                              TREE_OPERAND (olhs, 0), *ptr);
    9832            3 :               ptr = &TREE_OPERAND (*ptr, 1);
    9833              :             }
    9834              :         }
    9835              :       break;
    9836              : 
    9837          146 :     case MODIFY_EXPR:
    9838          146 :       if (compound_side_effects_p)
    9839            0 :         newrhs = rhs = stabilize_expr (rhs, &preeval);
    9840          146 :       lhs = genericize_compound_lvalue (lhs);
    9841          146 :       goto maybe_add_compound;
    9842              : 
    9843            0 :     case MIN_EXPR:
    9844            0 :     case MAX_EXPR:
    9845              :       /* MIN_EXPR and MAX_EXPR are currently only permitted as lvalues,
    9846              :          when neither operand has side-effects.  */
    9847            0 :       if (!lvalue_or_else (lhs, lv_assign, complain))
    9848            0 :         return error_mark_node;
    9849              : 
    9850            0 :       gcc_assert (!TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0))
    9851              :                   && !TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 1)));
    9852              : 
    9853            0 :       lhs = build3 (COND_EXPR, TREE_TYPE (lhs),
    9854            0 :                     build2 (TREE_CODE (lhs) == MIN_EXPR ? LE_EXPR : GE_EXPR,
    9855              :                             boolean_type_node,
    9856            0 :                             TREE_OPERAND (lhs, 0),
    9857            0 :                             TREE_OPERAND (lhs, 1)),
    9858            0 :                     TREE_OPERAND (lhs, 0),
    9859            0 :                     TREE_OPERAND (lhs, 1));
    9860          212 :       gcc_fallthrough ();
    9861              : 
    9862              :       /* Handle (a ? b : c) used as an "lvalue".  */
    9863          212 :     case COND_EXPR:
    9864          212 :       {
    9865              :         /* Produce (a ? (b = rhs) : (c = rhs))
    9866              :            except that the RHS goes through a save-expr
    9867              :            so the code to compute it is only emitted once.  */
    9868          212 :         if (VOID_TYPE_P (TREE_TYPE (rhs)))
    9869              :           {
    9870           18 :             if (complain & tf_error)
    9871           24 :               error_at (cp_expr_loc_or_loc (rhs, loc),
    9872              :                         "void value not ignored as it ought to be");
    9873           18 :             return error_mark_node;
    9874              :           }
    9875              : 
    9876          194 :         rhs = stabilize_expr (rhs, &preeval);
    9877              : 
    9878              :         /* Check this here to avoid odd errors when trying to convert
    9879              :            a throw to the type of the COND_EXPR.  */
    9880          194 :         if (!lvalue_or_else (lhs, lv_assign, complain))
    9881            6 :           return error_mark_node;
    9882              : 
    9883          188 :         tree op1 = TREE_OPERAND (lhs, 1);
    9884          188 :         if (TREE_CODE (op1) != THROW_EXPR)
    9885          182 :           op1 = cp_build_modify_expr (loc, op1, modifycode, rhs, complain);
    9886              :         /* When sanitizing undefined behavior, even when rhs doesn't need
    9887              :            stabilization at this point, the sanitization might add extra
    9888              :            SAVE_EXPRs in there and so make sure there is no tree sharing
    9889              :            in the rhs, otherwise those SAVE_EXPRs will have initialization
    9890              :            only in one of the two branches.  */
    9891          188 :         if (sanitize_flags_p (SANITIZE_UNDEFINED
    9892              :                               | SANITIZE_UNDEFINED_NONDEFAULT))
    9893            3 :           rhs = unshare_expr (rhs);
    9894          188 :         tree op2 = TREE_OPERAND (lhs, 2);
    9895          188 :         if (TREE_CODE (op2) != THROW_EXPR)
    9896          182 :           op2 = cp_build_modify_expr (loc, op2, modifycode, rhs, complain);
    9897          188 :         tree cond = build_conditional_expr (input_location,
    9898          188 :                                             TREE_OPERAND (lhs, 0), op1, op2,
    9899              :                                             complain);
    9900              : 
    9901          188 :         if (cond == error_mark_node)
    9902              :           return cond;
    9903              :         /* If we had (e, (a ? b : c)) = d; or (e, (f, (a ? b : c))) = d;
    9904              :            and looked through the COMPOUND_EXPRs, readd them now around
    9905              :            the resulting cond before adding the preevaluated rhs.  */
    9906          185 :         if (TREE_CODE (olhs) == COMPOUND_EXPR)
    9907              :           {
    9908           18 :             cond = build2 (COMPOUND_EXPR, TREE_TYPE (cond),
    9909           18 :                            TREE_OPERAND (olhs, 0), cond);
    9910           18 :             tree *ptr = &TREE_OPERAND (cond, 1);
    9911           18 :             for (olhs = TREE_OPERAND (olhs, 1);
    9912           21 :                  TREE_CODE (olhs) == COMPOUND_EXPR;
    9913            3 :                  olhs = TREE_OPERAND (olhs, 1))
    9914              :               {
    9915            3 :                 *ptr = build2 (COMPOUND_EXPR, TREE_TYPE (cond),
    9916            3 :                                TREE_OPERAND (olhs, 0), *ptr);
    9917            3 :                 ptr = &TREE_OPERAND (*ptr, 1);
    9918              :               }
    9919              :           }
    9920              :         /* Make sure the code to compute the rhs comes out
    9921              :            before the split.  */
    9922          185 :         result = cond;
    9923          185 :         goto ret;
    9924              :       }
    9925              : 
    9926              :     default:
    9927              :       lhs = olhs;
    9928              :       break;
    9929              :     }
    9930              : 
    9931     36027893 :   if (modifycode == INIT_EXPR)
    9932              :     {
    9933      4097454 :       if (BRACE_ENCLOSED_INITIALIZER_P (rhs))
    9934              :         /* Do the default thing.  */;
    9935      3905138 :       else if (TREE_CODE (rhs) == CONSTRUCTOR)
    9936              :         {
    9937              :           /* Compound literal.  */
    9938           96 :           if (! same_type_p (TREE_TYPE (rhs), lhstype))
    9939              :             /* Call convert to generate an error; see PR 11063.  */
    9940            0 :             rhs = convert (lhstype, rhs);
    9941           96 :           result = cp_build_init_expr (lhs, rhs);
    9942           96 :           TREE_SIDE_EFFECTS (result) = 1;
    9943           96 :           goto ret;
    9944              :         }
    9945      3905042 :       else if (! MAYBE_CLASS_TYPE_P (lhstype))
    9946              :         /* Do the default thing.  */;
    9947              :       else
    9948              :         {
    9949        39926 :           releasing_vec rhs_vec = make_tree_vector_single (rhs);
    9950        39926 :           result = build_special_member_call (lhs, complete_ctor_identifier,
    9951              :                                               &rhs_vec, lhstype, LOOKUP_NORMAL,
    9952              :                                               complain);
    9953        39926 :           if (result == NULL_TREE)
    9954            0 :             return error_mark_node;
    9955        39926 :           goto ret;
    9956        39926 :         }
    9957              :     }
    9958              :   else
    9959              :     {
    9960     31930439 :       lhs = require_complete_type (lhs, complain);
    9961     31930439 :       if (lhs == error_mark_node)
    9962              :         return error_mark_node;
    9963              : 
    9964     31930369 :       if (modifycode == NOP_EXPR)
    9965              :         {
    9966     27581891 :           maybe_warn_self_move (loc, lhs, rhs);
    9967              : 
    9968     27581891 :           if (c_dialect_objc ())
    9969              :             {
    9970            0 :               result = objc_maybe_build_modify_expr (lhs, rhs);
    9971            0 :               if (result)
    9972            0 :                 goto ret;
    9973              :             }
    9974              : 
    9975              :           /* `operator=' is not an inheritable operator.  */
    9976     27581891 :           if (! MAYBE_CLASS_TYPE_P (lhstype))
    9977              :             /* Do the default thing.  */;
    9978              :           else
    9979              :             {
    9980      3411244 :               result = build_new_op (input_location, MODIFY_EXPR,
    9981              :                                      LOOKUP_NORMAL, lhs, rhs,
    9982              :                                      make_node (NOP_EXPR), NULL_TREE,
    9983              :                                      /*overload=*/NULL, complain);
    9984      3411244 :               if (result == NULL_TREE)
    9985            0 :                 return error_mark_node;
    9986      3411244 :               goto ret;
    9987              :             }
    9988              :           lhstype = olhstype;
    9989              :         }
    9990              :       else
    9991              :         {
    9992      4348478 :           tree init = NULL_TREE;
    9993              : 
    9994              :           /* A binary op has been requested.  Combine the old LHS
    9995              :              value with the RHS producing the value we should actually
    9996              :              store into the LHS.  */
    9997      4348478 :           gcc_assert (!((TYPE_REF_P (lhstype)
    9998              :                          && MAYBE_CLASS_TYPE_P (TREE_TYPE (lhstype)))
    9999              :                         || MAYBE_CLASS_TYPE_P (lhstype)));
   10000              : 
   10001              :           /* Preevaluate the RHS to make sure its evaluation is complete
   10002              :              before the lvalue-to-rvalue conversion of the LHS:
   10003              : 
   10004              :              [expr.ass] With respect to an indeterminately-sequenced
   10005              :              function call, the operation of a compound assignment is a
   10006              :              single evaluation. [ Note: Therefore, a function call shall
   10007              :              not intervene between the lvalue-to-rvalue conversion and the
   10008              :              side effect associated with any single compound assignment
   10009              :              operator. -- end note ]  */
   10010      4348478 :           lhs = cp_stabilize_reference (lhs);
   10011      4348478 :           rhs = decay_conversion (rhs, complain);
   10012      4348478 :           if (rhs == error_mark_node)
   10013          123 :             return error_mark_node;
   10014              : 
   10015      4348475 :           {
   10016      4348475 :             auto_diagnostic_group d;
   10017      4348475 :             rhs = stabilize_expr (rhs, &init);
   10018      4348475 :             bool clear_decl_read = false;
   10019      4348475 :             tree stripped_lhs = tree_strip_any_location_wrapper (lhs);
   10020      1354381 :             if ((VAR_P (stripped_lhs) || TREE_CODE (stripped_lhs) == PARM_DECL)
   10021      3623745 :                 && !DECL_READ_P (stripped_lhs)
   10022       933542 :                 && (VAR_P (stripped_lhs) ? warn_unused_but_set_variable
   10023              :                                          : warn_unused_but_set_parameter) > 2
   10024         7009 :                 && !CLASS_TYPE_P (TREE_TYPE (lhs))
   10025      4355484 :                 && !CLASS_TYPE_P (TREE_TYPE (rhs)))
   10026              :               {
   10027         7009 :                 mark_exp_read (rhs);
   10028         7009 :                 if (!DECL_READ_P (stripped_lhs))
   10029      4348475 :                   clear_decl_read = true;
   10030              :               }
   10031      4348475 :             newrhs = cp_build_binary_op (loc, modifycode, lhs, rhs, complain);
   10032      4348475 :             if (clear_decl_read)
   10033         7009 :               DECL_READ_P (stripped_lhs) = 0;
   10034      4348475 :             if (newrhs == error_mark_node)
   10035              :               {
   10036          120 :                 if (complain & tf_error)
   10037           24 :                   inform (loc, "  in evaluation of %<%Q(%#T, %#T)%>",
   10038           24 :                           modifycode, TREE_TYPE (lhs), TREE_TYPE (rhs));
   10039          120 :                 return error_mark_node;
   10040              :               }
   10041      4348475 :           }
   10042              : 
   10043      4348355 :           if (init)
   10044       268312 :             newrhs = build2 (COMPOUND_EXPR, TREE_TYPE (newrhs), init, newrhs);
   10045              : 
   10046              :           /* Now it looks like a plain assignment.  */
   10047      4348355 :           modifycode = NOP_EXPR;
   10048      4348355 :           if (c_dialect_objc ())
   10049              :             {
   10050            0 :               result = objc_maybe_build_modify_expr (lhs, newrhs);
   10051            0 :               if (result)
   10052            0 :                 goto ret;
   10053              :             }
   10054              :         }
   10055     28519002 :       gcc_assert (!TYPE_REF_P (lhstype));
   10056     28519002 :       gcc_assert (!TYPE_REF_P (TREE_TYPE (newrhs)));
   10057              :     }
   10058              : 
   10059              :   /* The left-hand side must be an lvalue.  */
   10060     32576434 :   if (!lvalue_or_else (lhs, lv_assign, complain))
   10061          454 :     return error_mark_node;
   10062              : 
   10063              :   /* Warn about modifying something that is `const'.  Don't warn if
   10064              :      this is initialization.  */
   10065     32575980 :   if (modifycode != INIT_EXPR
   10066     32575980 :       && (TREE_READONLY (lhs) || CP_TYPE_CONST_P (lhstype)
   10067              :           /* Functions are not modifiable, even though they are
   10068              :              lvalues.  */
   10069     28483190 :           || FUNC_OR_METHOD_TYPE_P (TREE_TYPE (lhs))
   10070              :           /* If it's an aggregate and any field is const, then it is
   10071              :              effectively const.  */
   10072     28483142 :           || (CLASS_TYPE_P (lhstype)
   10073            0 :               && C_TYPE_FIELDS_READONLY (lhstype))))
   10074              :     {
   10075        35406 :       if (complain & tf_error)
   10076           85 :         cxx_readonly_error (loc, lhs, lv_assign);
   10077        35406 :       return error_mark_node;
   10078              :     }
   10079              : 
   10080              :   /* If storing into a structure or union member, it may have been given a
   10081              :      lowered bitfield type.  We need to convert to the declared type first,
   10082              :      so retrieve it now.  */
   10083              : 
   10084     32540574 :   olhstype = unlowered_expr_type (lhs);
   10085              : 
   10086              :   /* Convert new value to destination type.  */
   10087              : 
   10088     32540574 :   if (TREE_CODE (lhstype) == ARRAY_TYPE)
   10089              :     {
   10090          198 :       int from_array;
   10091              : 
   10092          198 :       if (BRACE_ENCLOSED_INITIALIZER_P (newrhs))
   10093              :         {
   10094           12 :           if (modifycode != INIT_EXPR)
   10095              :             {
   10096           12 :               if (complain & tf_error)
   10097           12 :                 error_at (loc,
   10098              :                           "assigning to an array from an initializer list");
   10099           12 :               return error_mark_node;
   10100              :             }
   10101            0 :           if (check_array_initializer (lhs, lhstype, newrhs))
   10102            0 :             return error_mark_node;
   10103            0 :           newrhs = digest_init (lhstype, newrhs, complain);
   10104            0 :           if (newrhs == error_mark_node)
   10105              :             return error_mark_node;
   10106              :         }
   10107              : 
   10108              :       /* C++11 8.5/17: "If the destination type is an array of characters,
   10109              :          an array of char16_t, an array of char32_t, or an array of wchar_t,
   10110              :          and the initializer is a string literal...".  */
   10111          186 :       else if ((TREE_CODE (tree_strip_any_location_wrapper (newrhs))
   10112              :                 == STRING_CST)
   10113           43 :                && char_type_p (TREE_TYPE (TYPE_MAIN_VARIANT (lhstype)))
   10114          229 :                && modifycode == INIT_EXPR)
   10115              :         {
   10116           28 :           newrhs = digest_init (lhstype, newrhs, complain);
   10117           28 :           if (newrhs == error_mark_node)
   10118              :             return error_mark_node;
   10119              :         }
   10120              : 
   10121          158 :       else if (!same_or_base_type_p (TYPE_MAIN_VARIANT (lhstype),
   10122              :                                      TYPE_MAIN_VARIANT (TREE_TYPE (newrhs))))
   10123              :         {
   10124           22 :           if (complain & tf_error)
   10125           12 :             error_at (loc, "incompatible types in assignment of %qT to %qT",
   10126           12 :                       TREE_TYPE (rhs), lhstype);
   10127           22 :           return error_mark_node;
   10128              :         }
   10129              : 
   10130              :       /* Allow array assignment in compiler-generated code.  */
   10131          136 :       else if (DECL_P (lhs) && DECL_ARTIFICIAL (lhs))
   10132              :         /* OK, used by coroutines (co-await-initlist1.C).  */;
   10133          130 :       else if (!current_function_decl
   10134          130 :                || !DECL_DEFAULTED_FN (current_function_decl))
   10135              :         {
   10136              :           /* This routine is used for both initialization and assignment.
   10137              :              Make sure the diagnostic message differentiates the context.  */
   10138           80 :           if (complain & tf_error)
   10139              :             {
   10140           30 :               if (modifycode == INIT_EXPR)
   10141            9 :                 error_at (loc, "array used as initializer");
   10142              :               else
   10143           21 :                 error_at (loc, "invalid array assignment");
   10144              :             }
   10145           80 :           return error_mark_node;
   10146              :         }
   10147              : 
   10148          131 :       from_array = TREE_CODE (TREE_TYPE (newrhs)) == ARRAY_TYPE
   10149           84 :                    ? 1 + (modifycode != INIT_EXPR) : 0;
   10150           84 :       result = build_vec_init (lhs, NULL_TREE, newrhs,
   10151              :                                /*explicit_value_init_p=*/false,
   10152              :                                from_array, complain);
   10153           84 :       goto ret;
   10154              :     }
   10155              : 
   10156     32540376 :   if (modifycode == INIT_EXPR)
   10157              :     /* Calls with INIT_EXPR are all direct-initialization, so don't set
   10158              :        LOOKUP_ONLYCONVERTING.  */
   10159      4057373 :     newrhs = convert_for_initialization (lhs, olhstype, newrhs, LOOKUP_NORMAL,
   10160              :                                          ICR_INIT, NULL_TREE, 0,
   10161              :                                          complain | tf_no_cleanup);
   10162              :   else
   10163     28483003 :     newrhs = convert_for_assignment (olhstype, newrhs, ICR_ASSIGN,
   10164              :                                      NULL_TREE, 0, complain, LOOKUP_IMPLICIT);
   10165              : 
   10166     32540376 :   if (!same_type_p (lhstype, olhstype))
   10167       374370 :     newrhs = cp_convert_and_check (lhstype, newrhs, complain);
   10168              : 
   10169     32540376 :   if (modifycode != INIT_EXPR)
   10170              :     {
   10171     28483003 :       if (TREE_CODE (newrhs) == CALL_EXPR
   10172     28483003 :           && TYPE_NEEDS_CONSTRUCTING (lhstype))
   10173            0 :         newrhs = build_cplus_new (lhstype, newrhs, complain);
   10174              : 
   10175              :       /* Can't initialize directly from a TARGET_EXPR, since that would
   10176              :          cause the lhs to be constructed twice, and possibly result in
   10177              :          accidental self-initialization.  So we force the TARGET_EXPR to be
   10178              :          expanded without a target.  */
   10179     28483003 :       if (TREE_CODE (newrhs) == TARGET_EXPR)
   10180           87 :         newrhs = build2 (COMPOUND_EXPR, TREE_TYPE (newrhs), newrhs,
   10181           87 :                          TARGET_EXPR_SLOT (newrhs));
   10182              :     }
   10183              : 
   10184     32540376 :   if (newrhs == error_mark_node)
   10185              :     return error_mark_node;
   10186              : 
   10187     32539735 :   if (c_dialect_objc () && flag_objc_gc)
   10188              :     {
   10189            0 :       result = objc_generate_write_barrier (lhs, modifycode, newrhs);
   10190              : 
   10191            0 :       if (result)
   10192            0 :         goto ret;
   10193              :     }
   10194              : 
   10195     36597059 :   result = build2_loc (loc, modifycode == NOP_EXPR ? MODIFY_EXPR : INIT_EXPR,
   10196              :                        lhstype, lhs, newrhs);
   10197     32539735 :   if (modifycode == INIT_EXPR)
   10198      4057324 :     set_target_expr_eliding (newrhs);
   10199              : 
   10200     32539735 :   TREE_SIDE_EFFECTS (result) = 1;
   10201     32539735 :   if (!plain_assign)
   10202      8405649 :     suppress_warning (result, OPT_Wparentheses);
   10203              : 
   10204     24134086 :  ret:
   10205     35991270 :   if (preeval)
   10206           39 :     result = build2 (COMPOUND_EXPR, TREE_TYPE (result), preeval, result);
   10207              :   return result;
   10208              : }
   10209              : 
   10210              : cp_expr
   10211     67912088 : build_x_modify_expr (location_t loc, tree lhs, enum tree_code modifycode,
   10212              :                      tree rhs, tree lookups, tsubst_flags_t complain)
   10213              : {
   10214     67912088 :   tree orig_lhs = lhs;
   10215     67912088 :   tree orig_rhs = rhs;
   10216     67912088 :   tree overload = NULL_TREE;
   10217              : 
   10218     67912088 :   if (lhs == error_mark_node || rhs == error_mark_node)
   10219         2129 :     return cp_expr (error_mark_node, loc);
   10220              : 
   10221     67909959 :   tree op = build_min (modifycode, void_type_node, NULL_TREE, NULL_TREE);
   10222              : 
   10223     67909959 :   if (processing_template_decl)
   10224              :     {
   10225     47746834 :       if (type_dependent_expression_p (lhs)
   10226     47746834 :           || type_dependent_expression_p (rhs))
   10227              :         {
   10228     35759855 :           tree rval = build_min_nt_loc (loc, MODOP_EXPR, lhs, op, rhs);
   10229     35759855 :           if (modifycode != NOP_EXPR)
   10230      6072988 :             TREE_TYPE (rval)
   10231     12145976 :               = build_dependent_operator_type (lookups, modifycode, true);
   10232     35759855 :           return rval;
   10233              :         }
   10234              :     }
   10235              : 
   10236     32150104 :   tree rval;
   10237     32150104 :   if (modifycode == NOP_EXPR)
   10238     24948711 :     rval = cp_build_modify_expr (loc, lhs, modifycode, rhs, complain);
   10239              :   else
   10240      7201393 :     rval = build_new_op (loc, MODIFY_EXPR, LOOKUP_NORMAL,
   10241              :                          lhs, rhs, op, lookups, &overload, complain);
   10242     32150104 :   if (rval == error_mark_node)
   10243         4409 :     return error_mark_node;
   10244     32145695 :   if (processing_template_decl)
   10245              :     {
   10246     11986958 :       if (overload != NULL_TREE)
   10247      1896059 :         return (build_min_non_dep_op_overload
   10248      1896059 :                 (MODIFY_EXPR, rval, overload, orig_lhs, orig_rhs));
   10249              : 
   10250     10090899 :       return (build_min_non_dep
   10251     10090899 :               (MODOP_EXPR, rval, orig_lhs, op, orig_rhs));
   10252              :     }
   10253     20158737 :   return rval;
   10254              : }
   10255              : 
   10256              : /* Helper function for get_delta_difference which assumes FROM is a base
   10257              :    class of TO.  Returns a delta for the conversion of pointer-to-member
   10258              :    of FROM to pointer-to-member of TO.  If the conversion is invalid and
   10259              :    tf_error is not set in COMPLAIN returns error_mark_node, otherwise
   10260              :    returns zero.  If FROM is not a base class of TO, returns NULL_TREE.
   10261              :    If C_CAST_P is true, this conversion is taking place as part of a
   10262              :    C-style cast.  */
   10263              : 
   10264              : static tree
   10265        28137 : get_delta_difference_1 (tree from, tree to, bool c_cast_p,
   10266              :                         tsubst_flags_t complain)
   10267              : {
   10268        28137 :   tree binfo;
   10269        28137 :   base_kind kind;
   10270              : 
   10271        56024 :   binfo = lookup_base (to, from, c_cast_p ? ba_unique : ba_check,
   10272              :                        &kind, complain);
   10273              : 
   10274        28137 :   if (binfo == error_mark_node)
   10275              :     {
   10276           51 :       if (!(complain & tf_error))
   10277              :         return error_mark_node;
   10278              : 
   10279           51 :       inform (input_location, "   in pointer to member function conversion");
   10280           51 :       return size_zero_node;
   10281              :     }
   10282        28086 :   else if (binfo)
   10283              :     {
   10284        27938 :       if (kind != bk_via_virtual)
   10285        27845 :         return BINFO_OFFSET (binfo);
   10286              :       else
   10287              :         /* FROM is a virtual base class of TO.  Issue an error or warning
   10288              :            depending on whether or not this is a reinterpret cast.  */
   10289              :         {
   10290           93 :           if (!(complain & tf_error))
   10291              :             return error_mark_node;
   10292              : 
   10293           78 :           error ("pointer to member conversion via virtual base %qT",
   10294           78 :                  BINFO_TYPE (binfo_from_vbase (binfo)));
   10295              : 
   10296           78 :           return size_zero_node;
   10297              :         }
   10298              :       }
   10299              :   else
   10300              :     return NULL_TREE;
   10301              : }
   10302              : 
   10303              : /* Get difference in deltas for different pointer to member function
   10304              :    types.  If the conversion is invalid and tf_error is not set in
   10305              :    COMPLAIN, returns error_mark_node, otherwise returns an integer
   10306              :    constant of type PTRDIFF_TYPE_NODE and its value is zero if the
   10307              :    conversion is invalid.  If ALLOW_INVERSE_P is true, then allow reverse
   10308              :    conversions as well.  If C_CAST_P is true this conversion is taking
   10309              :    place as part of a C-style cast.
   10310              : 
   10311              :    Note that the naming of FROM and TO is kind of backwards; the return
   10312              :    value is what we add to a TO in order to get a FROM.  They are named
   10313              :    this way because we call this function to find out how to convert from
   10314              :    a pointer to member of FROM to a pointer to member of TO.  */
   10315              : 
   10316              : static tree
   10317        87649 : get_delta_difference (tree from, tree to,
   10318              :                       bool allow_inverse_p,
   10319              :                       bool c_cast_p, tsubst_flags_t complain)
   10320              : {
   10321        87649 :   auto_diagnostic_group d;
   10322        87649 :   tree result;
   10323              : 
   10324        87649 :   if (same_type_ignoring_top_level_qualifiers_p (from, to))
   10325              :     /* Pointer to member of incomplete class is permitted*/
   10326        59660 :     result = size_zero_node;
   10327              :   else
   10328        27989 :     result = get_delta_difference_1 (from, to, c_cast_p, complain);
   10329              : 
   10330        87649 :   if (result == error_mark_node)
   10331              :     return error_mark_node;
   10332              : 
   10333        87634 :   if (!result)
   10334              :   {
   10335          148 :     if (!allow_inverse_p)
   10336              :       {
   10337            0 :         if (!(complain & tf_error))
   10338              :           return error_mark_node;
   10339              : 
   10340            0 :         error_not_base_type (from, to);
   10341            0 :         inform (input_location, "   in pointer to member conversion");
   10342            0 :         result = size_zero_node;
   10343              :       }
   10344              :     else
   10345              :       {
   10346          148 :         result = get_delta_difference_1 (to, from, c_cast_p, complain);
   10347              : 
   10348          148 :         if (result == error_mark_node)
   10349              :           return error_mark_node;
   10350              : 
   10351          148 :         if (result)
   10352          148 :           result = size_diffop_loc (input_location,
   10353              :                                     size_zero_node, result);
   10354              :         else
   10355              :           {
   10356            0 :             if (!(complain & tf_error))
   10357              :               return error_mark_node;
   10358              : 
   10359            0 :             error_not_base_type (from, to);
   10360            0 :             inform (input_location, "   in pointer to member conversion");
   10361            0 :             result = size_zero_node;
   10362              :           }
   10363              :       }
   10364              :   }
   10365              : 
   10366        87634 :   return convert_to_integer (ptrdiff_type_node, result);
   10367        87649 : }
   10368              : 
   10369              : /* Return a constructor for the pointer-to-member-function TYPE using
   10370              :    the other components as specified.  */
   10371              : 
   10372              : tree
   10373        59937 : build_ptrmemfunc1 (tree type, tree delta, tree pfn)
   10374              : {
   10375        59937 :   tree u = NULL_TREE;
   10376        59937 :   tree delta_field;
   10377        59937 :   tree pfn_field;
   10378        59937 :   vec<constructor_elt, va_gc> *v;
   10379              : 
   10380              :   /* Pull the FIELD_DECLs out of the type.  */
   10381        59937 :   pfn_field = TYPE_FIELDS (type);
   10382        59937 :   delta_field = DECL_CHAIN (pfn_field);
   10383              : 
   10384              :   /* Make sure DELTA has the type we want.  */
   10385        59937 :   delta = convert_and_check (input_location, delta_type_node, delta);
   10386              : 
   10387              :   /* Convert to the correct target type if necessary.  */
   10388        59937 :   pfn = fold_convert (TREE_TYPE (pfn_field), pfn);
   10389              : 
   10390              :   /* Finish creating the initializer.  */
   10391        59937 :   vec_alloc (v, 2);
   10392        59937 :   CONSTRUCTOR_APPEND_ELT(v, pfn_field, pfn);
   10393        59937 :   CONSTRUCTOR_APPEND_ELT(v, delta_field, delta);
   10394        59937 :   u = build_constructor (type, v);
   10395        59937 :   TREE_CONSTANT (u) = TREE_CONSTANT (pfn) & TREE_CONSTANT (delta);
   10396        59937 :   TREE_STATIC (u) = (TREE_CONSTANT (u)
   10397        59823 :                      && (initializer_constant_valid_p (pfn, TREE_TYPE (pfn))
   10398              :                          != NULL_TREE)
   10399       119760 :                      && (initializer_constant_valid_p (delta, TREE_TYPE (delta))
   10400              :                          != NULL_TREE));
   10401        59937 :   return u;
   10402              : }
   10403              : 
   10404              : /* Build a constructor for a pointer to member function.  It can be
   10405              :    used to initialize global variables, local variable, or used
   10406              :    as a value in expressions.  TYPE is the POINTER to METHOD_TYPE we
   10407              :    want to be.
   10408              : 
   10409              :    If FORCE is nonzero, then force this conversion, even if
   10410              :    we would rather not do it.  Usually set when using an explicit
   10411              :    cast.  A C-style cast is being processed iff C_CAST_P is true.
   10412              : 
   10413              :    Return error_mark_node, if something goes wrong.  */
   10414              : 
   10415              : tree
   10416        29408 : build_ptrmemfunc (tree type, tree pfn, int force, bool c_cast_p,
   10417              :                   tsubst_flags_t complain)
   10418              : {
   10419        29408 :   tree fn;
   10420        29408 :   tree pfn_type;
   10421        29408 :   tree to_type;
   10422              : 
   10423        29408 :   if (error_operand_p (pfn))
   10424            0 :     return error_mark_node;
   10425              : 
   10426        29408 :   pfn_type = TREE_TYPE (pfn);
   10427        29408 :   to_type = build_ptrmemfunc_type (type);
   10428              : 
   10429              :   /* Handle multiple conversions of pointer to member functions.  */
   10430        29408 :   if (TYPE_PTRMEMFUNC_P (pfn_type))
   10431              :     {
   10432        27692 :       tree delta = NULL_TREE;
   10433        27692 :       tree npfn = NULL_TREE;
   10434        27692 :       tree n;
   10435              : 
   10436        27692 :       if (!force
   10437        27692 :           && !can_convert_arg (to_type, TREE_TYPE (pfn), pfn,
   10438              :                                LOOKUP_NORMAL, complain))
   10439              :         {
   10440            0 :           if (complain & tf_error)
   10441            0 :             error ("invalid conversion to type %qT from type %qT",
   10442              :                    to_type, pfn_type);
   10443              :           else
   10444            0 :             return error_mark_node;
   10445              :         }
   10446              : 
   10447        27692 :       n = get_delta_difference (TYPE_PTRMEMFUNC_OBJECT_TYPE (pfn_type),
   10448        27692 :                                 TYPE_PTRMEMFUNC_OBJECT_TYPE (to_type),
   10449              :                                 force,
   10450              :                                 c_cast_p, complain);
   10451        27692 :       if (n == error_mark_node)
   10452              :         return error_mark_node;
   10453              : 
   10454        27683 :       STRIP_ANY_LOCATION_WRAPPER (pfn);
   10455              : 
   10456              :       /* We don't have to do any conversion to convert a
   10457              :          pointer-to-member to its own type.  But, we don't want to
   10458              :          just return a PTRMEM_CST if there's an explicit cast; that
   10459              :          cast should make the expression an invalid template argument.  */
   10460        27683 :       if (TREE_CODE (pfn) != PTRMEM_CST
   10461        27683 :           && same_type_p (to_type, pfn_type))
   10462              :         return pfn;
   10463              : 
   10464        27683 :       if (TREE_SIDE_EFFECTS (pfn))
   10465           14 :         pfn = save_expr (pfn);
   10466              : 
   10467              :       /* Obtain the function pointer and the current DELTA.  */
   10468        27683 :       if (TREE_CODE (pfn) == PTRMEM_CST)
   10469        27589 :         expand_ptrmemfunc_cst (pfn, &delta, &npfn);
   10470              :       else
   10471              :         {
   10472           94 :           npfn = build_ptrmemfunc_access_expr (pfn, pfn_identifier);
   10473           94 :           delta = build_ptrmemfunc_access_expr (pfn, delta_identifier);
   10474              :         }
   10475              : 
   10476              :       /* Just adjust the DELTA field.  */
   10477        27683 :       gcc_assert  (same_type_ignoring_top_level_qualifiers_p
   10478              :                    (TREE_TYPE (delta), ptrdiff_type_node));
   10479        27683 :       if (!integer_zerop (n))
   10480              :         {
   10481           50 :           if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_delta)
   10482              :             n = cp_build_binary_op (input_location,
   10483              :                                     LSHIFT_EXPR, n, integer_one_node,
   10484              :                                     complain);
   10485           50 :           delta = cp_build_binary_op (input_location,
   10486              :                                       PLUS_EXPR, delta, n, complain);
   10487              :         }
   10488        27683 :       return build_ptrmemfunc1 (to_type, delta, npfn);
   10489              :     }
   10490              : 
   10491              :   /* Handle null pointer to member function conversions.  */
   10492         1716 :   if (null_ptr_cst_p (pfn))
   10493              :     {
   10494          638 :       pfn = cp_build_c_cast (input_location,
   10495          638 :                              TYPE_PTRMEMFUNC_FN_TYPE_RAW (to_type),
   10496              :                              pfn, complain);
   10497          638 :       return build_ptrmemfunc1 (to_type,
   10498              :                                 integer_zero_node,
   10499          638 :                                 pfn);
   10500              :     }
   10501              : 
   10502         1078 :   if (type_unknown_p (pfn))
   10503            0 :     return instantiate_type (type, pfn, complain);
   10504              : 
   10505         1078 :   fn = TREE_OPERAND (pfn, 0);
   10506         1078 :   gcc_assert (TREE_CODE (fn) == FUNCTION_DECL
   10507              :               /* In a template, we will have preserved the
   10508              :                  OFFSET_REF.  */
   10509              :               || (processing_template_decl && TREE_CODE (fn) == OFFSET_REF));
   10510         1078 :   return make_ptrmem_cst (to_type, fn);
   10511              : }
   10512              : 
   10513              : /* Return the DELTA, IDX, PFN, and DELTA2 values for the PTRMEM_CST
   10514              :    given by CST.
   10515              : 
   10516              :    ??? There is no consistency as to the types returned for the above
   10517              :    values.  Some code acts as if it were a sizetype and some as if it were
   10518              :    integer_type_node.  */
   10519              : 
   10520              : void
   10521        59575 : expand_ptrmemfunc_cst (tree cst, tree *delta, tree *pfn)
   10522              : {
   10523        59575 :   tree type = TREE_TYPE (cst);
   10524        59575 :   tree fn = PTRMEM_CST_MEMBER (cst);
   10525        59575 :   tree ptr_class, fn_class;
   10526              : 
   10527        59575 :   gcc_assert (TREE_CODE (fn) == FUNCTION_DECL);
   10528              : 
   10529              :   /* The class that the function belongs to.  */
   10530        59575 :   fn_class = DECL_CONTEXT (fn);
   10531              : 
   10532              :   /* The class that we're creating a pointer to member of.  */
   10533        59575 :   ptr_class = TYPE_PTRMEMFUNC_OBJECT_TYPE (type);
   10534              : 
   10535              :   /* First, calculate the adjustment to the function's class.  */
   10536        59575 :   *delta = get_delta_difference (fn_class, ptr_class, /*force=*/0,
   10537              :                                  /*c_cast_p=*/0, tf_warning_or_error);
   10538              : 
   10539        59575 :   if (!DECL_VIRTUAL_P (fn))
   10540              :     {
   10541        58466 :       tree t = build_addr_func (fn, tf_warning_or_error);
   10542        58466 :       if (TREE_CODE (t) == ADDR_EXPR)
   10543        58466 :         SET_EXPR_LOCATION (t, PTRMEM_CST_LOCATION (cst));
   10544        58466 :       *pfn = convert (TYPE_PTRMEMFUNC_FN_TYPE (type), t);
   10545              :     }
   10546              :   else
   10547              :     {
   10548              :       /* If we're dealing with a virtual function, we have to adjust 'this'
   10549              :          again, to point to the base which provides the vtable entry for
   10550              :          fn; the call will do the opposite adjustment.  */
   10551         1109 :       tree orig_class = DECL_CONTEXT (fn);
   10552         1109 :       tree binfo = binfo_or_else (orig_class, fn_class);
   10553         1109 :       *delta = fold_build2 (PLUS_EXPR, TREE_TYPE (*delta),
   10554              :                             *delta, BINFO_OFFSET (binfo));
   10555              : 
   10556              :       /* We set PFN to the vtable offset at which the function can be
   10557              :          found, plus one (unless ptrmemfunc_vbit_in_delta, in which
   10558              :          case delta is shifted left, and then incremented).  */
   10559         1109 :       *pfn = DECL_VINDEX (fn);
   10560         1109 :       *pfn = fold_build2 (MULT_EXPR, integer_type_node, *pfn,
   10561              :                           TYPE_SIZE_UNIT (vtable_entry_type));
   10562              : 
   10563         1109 :       switch (TARGET_PTRMEMFUNC_VBIT_LOCATION)
   10564              :         {
   10565         1109 :         case ptrmemfunc_vbit_in_pfn:
   10566         1109 :           *pfn = fold_build2 (PLUS_EXPR, integer_type_node, *pfn,
   10567              :                               integer_one_node);
   10568         1109 :           break;
   10569              : 
   10570              :         case ptrmemfunc_vbit_in_delta:
   10571              :           *delta = fold_build2 (LSHIFT_EXPR, TREE_TYPE (*delta),
   10572              :                                 *delta, integer_one_node);
   10573              :           *delta = fold_build2 (PLUS_EXPR, TREE_TYPE (*delta),
   10574              :                                 *delta, integer_one_node);
   10575              :           break;
   10576              : 
   10577              :         default:
   10578              :           gcc_unreachable ();
   10579              :         }
   10580              : 
   10581         1109 :       *pfn = fold_convert (TYPE_PTRMEMFUNC_FN_TYPE (type), *pfn);
   10582              :     }
   10583        59575 : }
   10584              : 
   10585              : /* Return an expression for PFN from the pointer-to-member function
   10586              :    given by T.  */
   10587              : 
   10588              : static tree
   10589        84179 : pfn_from_ptrmemfunc (tree t)
   10590              : {
   10591        84179 :   if (TREE_CODE (t) == PTRMEM_CST)
   10592              :     {
   10593          185 :       tree delta;
   10594          185 :       tree pfn;
   10595              : 
   10596          185 :       expand_ptrmemfunc_cst (t, &delta, &pfn);
   10597          185 :       if (pfn)
   10598          185 :         return pfn;
   10599              :     }
   10600              : 
   10601        83994 :   return build_ptrmemfunc_access_expr (t, pfn_identifier);
   10602              : }
   10603              : 
   10604              : /* Return an expression for DELTA from the pointer-to-member function
   10605              :    given by T.  */
   10606              : 
   10607              : static tree
   10608        84179 : delta_from_ptrmemfunc (tree t)
   10609              : {
   10610        84179 :   if (TREE_CODE (t) == PTRMEM_CST)
   10611              :     {
   10612          185 :       tree delta;
   10613          185 :       tree pfn;
   10614              : 
   10615          185 :       expand_ptrmemfunc_cst (t, &delta, &pfn);
   10616          185 :       if (delta)
   10617          185 :         return delta;
   10618              :     }
   10619              : 
   10620        83994 :   return build_ptrmemfunc_access_expr (t, delta_identifier);
   10621              : }
   10622              : 
   10623              : /* Convert value RHS to type TYPE as preparation for an assignment to
   10624              :    an lvalue of type TYPE.  ERRTYPE indicates what kind of error the
   10625              :    implicit conversion is.  If FNDECL is non-NULL, we are doing the
   10626              :    conversion in order to pass the PARMNUMth argument of FNDECL.
   10627              :    If FNDECL is NULL, we are doing the conversion in function pointer
   10628              :    argument passing, conversion in initialization, etc. */
   10629              : 
   10630              : static tree
   10631    174440532 : convert_for_assignment (tree type, tree rhs,
   10632              :                         impl_conv_rhs errtype, tree fndecl, int parmnum,
   10633              :                         tsubst_flags_t complain, int flags)
   10634              : {
   10635    174440532 :   tree rhstype;
   10636    174440532 :   enum tree_code coder;
   10637              : 
   10638    174440532 :   location_t rhs_loc = cp_expr_loc_or_input_loc (rhs);
   10639    174440532 :   bool has_loc = EXPR_LOCATION (rhs) != UNKNOWN_LOCATION;
   10640              :   /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue,
   10641              :      but preserve location wrappers.  */
   10642    174440532 :   if (TREE_CODE (rhs) == NON_LVALUE_EXPR
   10643    174440532 :       && !location_wrapper_p (rhs))
   10644         8432 :     rhs = TREE_OPERAND (rhs, 0);
   10645              : 
   10646              :   /* Handle [dcl.init.list] direct-list-initialization from
   10647              :      single element of enumeration with a fixed underlying type.  */
   10648    174440532 :   if (is_direct_enum_init (type, rhs))
   10649              :     {
   10650           20 :       tree elt = CONSTRUCTOR_ELT (rhs, 0)->value;
   10651           20 :       if (check_narrowing (ENUM_UNDERLYING_TYPE (type), elt, complain))
   10652              :         {
   10653           11 :           warning_sentinel w (warn_useless_cast);
   10654           11 :           warning_sentinel w2 (warn_ignored_qualifiers);
   10655           11 :           rhs = cp_build_c_cast (rhs_loc, type, elt, complain);
   10656           11 :         }
   10657              :       else
   10658            9 :         rhs = error_mark_node;
   10659              :     }
   10660              : 
   10661    174440532 :   rhstype = TREE_TYPE (rhs);
   10662    174440532 :   coder = TREE_CODE (rhstype);
   10663              : 
   10664      1353707 :   if (VECTOR_TYPE_P (type) && coder == VECTOR_TYPE
   10665    175794133 :       && vector_types_convertible_p (type, rhstype, true))
   10666              :     {
   10667      1353592 :       rhs = mark_rvalue_use (rhs);
   10668      1353592 :       return convert (type, rhs);
   10669              :     }
   10670              : 
   10671    173086940 :   if (rhs == error_mark_node || rhstype == error_mark_node)
   10672              :     return error_mark_node;
   10673    173086931 :   if (TREE_CODE (rhs) == TREE_LIST && TREE_VALUE (rhs) == error_mark_node)
   10674              :     return error_mark_node;
   10675              : 
   10676              :   /* The RHS of an assignment cannot have void type.  */
   10677    173086931 :   if (coder == VOID_TYPE)
   10678              :     {
   10679           48 :       if (complain & tf_error)
   10680           30 :         error_at (rhs_loc, "void value not ignored as it ought to be");
   10681           48 :       return error_mark_node;
   10682              :     }
   10683              : 
   10684    173086883 :   if (c_dialect_objc ())
   10685              :     {
   10686            0 :       int parmno;
   10687            0 :       tree selector;
   10688            0 :       tree rname = fndecl;
   10689              : 
   10690            0 :       switch (errtype)
   10691              :         {
   10692              :           case ICR_ASSIGN:
   10693              :             parmno = -1;
   10694              :             break;
   10695            0 :           case ICR_INIT:
   10696            0 :             parmno = -2;
   10697            0 :             break;
   10698            0 :           default:
   10699            0 :             selector = objc_message_selector ();
   10700            0 :             parmno = parmnum;
   10701            0 :             if (selector && parmno > 1)
   10702              :               {
   10703            0 :                 rname = selector;
   10704            0 :                 parmno -= 1;
   10705              :               }
   10706              :         }
   10707              : 
   10708            0 :       if (objc_compare_types (type, rhstype, parmno, rname))
   10709              :         {
   10710            0 :           rhs = mark_rvalue_use (rhs);
   10711            0 :           return convert (type, rhs);
   10712              :         }
   10713              :     }
   10714              : 
   10715              :   /* [expr.ass]
   10716              : 
   10717              :      The expression is implicitly converted (clause _conv_) to the
   10718              :      cv-unqualified type of the left operand.
   10719              : 
   10720              :      We allow bad conversions here because by the time we get to this point
   10721              :      we are committed to doing the conversion.  If we end up doing a bad
   10722              :      conversion, convert_like will complain.  */
   10723    173086883 :   if (!can_convert_arg_bad (type, rhstype, rhs, flags, complain))
   10724              :     {
   10725              :       /* When -Wno-pmf-conversions is use, we just silently allow
   10726              :          conversions from pointers-to-members to plain pointers.  If
   10727              :          the conversion doesn't work, cp_convert will complain.  */
   10728         1539 :       if (!warn_pmf2ptr
   10729            9 :           && TYPE_PTR_P (type)
   10730         1548 :           && TYPE_PTRMEMFUNC_P (rhstype))
   10731            9 :         rhs = cp_convert (strip_top_quals (type), rhs, complain);
   10732              :       else
   10733              :         {
   10734         1530 :           if (complain & tf_error)
   10735              :             {
   10736         1280 :               auto_diagnostic_group d;
   10737              : 
   10738              :               /* If the right-hand side has unknown type, then it is an
   10739              :                  overloaded function.  Call instantiate_type to get error
   10740              :                  messages.  */
   10741         1280 :               if (rhstype == unknown_type_node)
   10742              :                 {
   10743          197 :                   tree r = instantiate_type (type, rhs, tf_warning_or_error);
   10744              :                   /* -fpermissive might allow this; recurse.  */
   10745          197 :                   if (!seen_error ())
   10746           15 :                     return convert_for_assignment (type, r, errtype, fndecl,
   10747              :                                                    parmnum, complain, flags);
   10748              :                 }
   10749         1083 :               else if (fndecl)
   10750           92 :                 complain_about_bad_argument (rhs_loc,
   10751              :                                              rhstype, type,
   10752              :                                              fndecl, parmnum);
   10753              :               else
   10754              :                 {
   10755          991 :                   range_label_for_type_mismatch label (rhstype, type);
   10756          991 :                   gcc_rich_location richloc
   10757              :                     (rhs_loc,
   10758              :                      has_loc ? &label : NULL,
   10759          991 :                      has_loc ? highlight_colors::percent_h : NULL);
   10760              : 
   10761          991 :                   switch (errtype)
   10762              :                     {
   10763            0 :                     case ICR_DEFAULT_ARGUMENT:
   10764            0 :                       error_at (&richloc,
   10765              :                                 "cannot convert %qH to %qI in default argument",
   10766              :                                 rhstype, type);
   10767            0 :                       break;
   10768            6 :                     case ICR_ARGPASS:
   10769            6 :                       error_at (&richloc,
   10770              :                                 "cannot convert %qH to %qI in argument passing",
   10771              :                                 rhstype, type);
   10772            6 :                       break;
   10773            0 :                     case ICR_CONVERTING:
   10774            0 :                       error_at (&richloc, "cannot convert %qH to %qI",
   10775              :                                 rhstype, type);
   10776            0 :                       break;
   10777          553 :                     case ICR_INIT:
   10778          553 :                       error_at (&richloc,
   10779              :                                 "cannot convert %qH to %qI in initialization",
   10780              :                                 rhstype, type);
   10781          553 :                       break;
   10782           18 :                     case ICR_RETURN:
   10783           18 :                       error_at (&richloc, "cannot convert %qH to %qI in return",
   10784              :                                 rhstype, type);
   10785           18 :                       break;
   10786          414 :                     case ICR_ASSIGN:
   10787          414 :                       error_at (&richloc,
   10788              :                                 "cannot convert %qH to %qI in assignment",
   10789              :                                 rhstype, type);
   10790          414 :                       break;
   10791            0 :                     default:
   10792            0 :                       gcc_unreachable();
   10793              :                   }
   10794          991 :                 }
   10795              : 
   10796              :               /* See if we can be more helpful.  */
   10797         1265 :               maybe_show_nonconverting_candidate (type, rhstype, rhs, flags);
   10798              : 
   10799         1265 :               if (TYPE_PTR_P (rhstype)
   10800          412 :                   && TYPE_PTR_P (type)
   10801          397 :                   && CLASS_TYPE_P (TREE_TYPE (rhstype))
   10802          279 :                   && CLASS_TYPE_P (TREE_TYPE (type))
   10803         1328 :                   && !COMPLETE_TYPE_P (TREE_TYPE (rhstype)))
   10804            3 :                 inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL
   10805              :                                               (TREE_TYPE (rhstype))),
   10806            3 :                         "class type %qT is incomplete", TREE_TYPE (rhstype));
   10807         1280 :             }
   10808         1515 :           return error_mark_node;
   10809              :         }
   10810              :     }
   10811    173085353 :   if (warn_suggest_attribute_format)
   10812              :     {
   10813         2383 :       const enum tree_code codel = TREE_CODE (type);
   10814         2383 :       if ((codel == POINTER_TYPE || codel == REFERENCE_TYPE)
   10815          596 :           && coder == codel
   10816          508 :           && check_missing_format_attribute (type, rhstype)
   10817         2401 :           && (complain & tf_warning))
   10818           18 :         switch (errtype)
   10819              :           {
   10820            0 :             case ICR_ARGPASS:
   10821            0 :             case ICR_DEFAULT_ARGUMENT:
   10822            0 :               if (fndecl)
   10823            0 :                 warning (OPT_Wsuggest_attribute_format,
   10824              :                          "parameter %qP of %qD might be a candidate "
   10825              :                          "for a format attribute", parmnum, fndecl);
   10826              :               else
   10827            0 :                 warning (OPT_Wsuggest_attribute_format,
   10828              :                          "parameter might be a candidate "
   10829              :                          "for a format attribute");
   10830              :               break;
   10831            0 :             case ICR_CONVERTING:
   10832            0 :               warning (OPT_Wsuggest_attribute_format,
   10833              :                        "target of conversion might be a candidate "
   10834              :                        "for a format attribute");
   10835            0 :               break;
   10836            6 :             case ICR_INIT:
   10837            6 :               warning (OPT_Wsuggest_attribute_format,
   10838              :                        "target of initialization might be a candidate "
   10839              :                        "for a format attribute");
   10840            6 :               break;
   10841            6 :             case ICR_RETURN:
   10842            6 :               warning (OPT_Wsuggest_attribute_format,
   10843              :                        "return type might be a candidate "
   10844              :                        "for a format attribute");
   10845            6 :               break;
   10846            6 :             case ICR_ASSIGN:
   10847            6 :               warning (OPT_Wsuggest_attribute_format,
   10848              :                        "left-hand side of assignment might be a candidate "
   10849              :                        "for a format attribute");
   10850            6 :               break;
   10851            0 :             default:
   10852            0 :               gcc_unreachable();
   10853              :           }
   10854              :     }
   10855              : 
   10856    173085353 :   if (TREE_CODE (type) == BOOLEAN_TYPE)
   10857     35500060 :     maybe_warn_unparenthesized_assignment (rhs, /*nested_p=*/true, complain);
   10858              : 
   10859    173085353 :   if (complain & tf_warning)
   10860    170700596 :     warn_for_address_of_packed_member (type, rhs);
   10861              : 
   10862    173085353 :   return perform_implicit_conversion_flags (strip_top_quals (type), rhs,
   10863    173085353 :                                             complain, flags);
   10864              : }
   10865              : 
   10866              : /* Convert RHS to be of type TYPE.
   10867              :    If EXP is nonzero, it is the target of the initialization.
   10868              :    ERRTYPE indicates what kind of error the implicit conversion is.
   10869              : 
   10870              :    Two major differences between the behavior of
   10871              :    `convert_for_assignment' and `convert_for_initialization'
   10872              :    are that references are bashed in the former, while
   10873              :    copied in the latter, and aggregates are assigned in
   10874              :    the former (operator=) while initialized in the
   10875              :    latter (X(X&)).
   10876              : 
   10877              :    If using constructor make sure no conversion operator exists, if one does
   10878              :    exist, an ambiguity exists.  */
   10879              : 
   10880              : tree
   10881    161389652 : convert_for_initialization (tree exp, tree type, tree rhs, int flags,
   10882              :                             impl_conv_rhs errtype, tree fndecl, int parmnum,
   10883              :                             tsubst_flags_t complain)
   10884              : {
   10885    161389652 :   enum tree_code codel = TREE_CODE (type);
   10886    161389652 :   tree rhstype;
   10887    161389652 :   enum tree_code coder;
   10888              : 
   10889              :   /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
   10890              :      Strip such NOP_EXPRs, since RHS is used in non-lvalue context.  */
   10891    161389652 :   if (TREE_CODE (rhs) == NOP_EXPR
   10892      5646443 :       && TREE_TYPE (rhs) == TREE_TYPE (TREE_OPERAND (rhs, 0))
   10893    161861393 :       && codel != REFERENCE_TYPE)
   10894       471741 :     rhs = TREE_OPERAND (rhs, 0);
   10895              : 
   10896    161389652 :   if (type == error_mark_node
   10897    161389609 :       || rhs == error_mark_node
   10898    322779199 :       || (TREE_CODE (rhs) == TREE_LIST && TREE_VALUE (rhs) == error_mark_node))
   10899              :     return error_mark_node;
   10900              : 
   10901    161389547 :   if (MAYBE_CLASS_TYPE_P (non_reference (type)))
   10902              :     ;
   10903    147820234 :   else if ((TREE_CODE (TREE_TYPE (rhs)) == ARRAY_TYPE
   10904      2008283 :             && TREE_CODE (type) != ARRAY_TYPE
   10905      2008283 :             && (!TYPE_REF_P (type)
   10906          726 :                 || TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE))
   10907    145812674 :            || (TREE_CODE (TREE_TYPE (rhs)) == FUNCTION_TYPE
   10908        24468 :                && !TYPE_REFFN_P (type))
   10909    293609335 :            || TREE_CODE (TREE_TYPE (rhs)) == METHOD_TYPE)
   10910      2031139 :     rhs = decay_conversion (rhs, complain);
   10911              : 
   10912    161389547 :   rhstype = TREE_TYPE (rhs);
   10913    161389547 :   coder = TREE_CODE (rhstype);
   10914              : 
   10915    161389547 :   if (coder == ERROR_MARK)
   10916            9 :     return error_mark_node;
   10917              : 
   10918              :   /* We accept references to incomplete types, so we can
   10919              :      return here before checking if RHS is of complete type.  */
   10920              : 
   10921    161389538 :   if (codel == REFERENCE_TYPE)
   10922              :     {
   10923      5834830 :       auto_diagnostic_group d;
   10924              :       /* This should eventually happen in convert_arguments.  */
   10925      5834830 :       int savew = 0, savee = 0;
   10926              : 
   10927      5834830 :       if (fndecl)
   10928       274636 :         savew = warningcount + werrorcount, savee = errorcount;
   10929      5834830 :       rhs = initialize_reference (type, rhs, flags, complain);
   10930              : 
   10931      5834830 :       if (fndecl
   10932      5834830 :           && (warningcount + werrorcount > savew || errorcount > savee))
   10933           36 :         inform (get_fndecl_argument_location (fndecl, parmnum),
   10934              :                 "in passing argument %P of %qD", parmnum, fndecl);
   10935      5834830 :       return rhs;
   10936      5834830 :     }
   10937              : 
   10938    155554708 :   if (exp != 0)
   10939      4057373 :     exp = require_complete_type (exp, complain);
   10940    155554708 :   if (exp == error_mark_node)
   10941              :     return error_mark_node;
   10942              : 
   10943    155554708 :   type = complete_type (type);
   10944              : 
   10945    155554708 :   if (DIRECT_INIT_EXPR_P (type, rhs))
   10946              :     /* Don't try to do copy-initialization if we already have
   10947              :        direct-initialization.  */
   10948              :     return rhs;
   10949              : 
   10950    155553564 :   if (MAYBE_CLASS_TYPE_P (type))
   10951      9596050 :     return perform_implicit_conversion_flags (type, rhs, complain, flags);
   10952              : 
   10953    145957514 :   return convert_for_assignment (type, rhs, errtype, fndecl, parmnum,
   10954    145957514 :                                  complain, flags);
   10955              : }
   10956              : 
   10957              : /* If RETVAL is the address of, or a reference to, a local variable or
   10958              :    temporary give an appropriate warning and return true.  */
   10959              : 
   10960              : static bool
   10961     41463294 : maybe_warn_about_returning_address_of_local (tree retval, location_t loc)
   10962              : {
   10963     41464093 :   tree valtype = TREE_TYPE (DECL_RESULT (current_function_decl));
   10964     41464093 :   tree whats_returned = fold_for_warn (retval);
   10965     41464093 :   if (!loc)
   10966     41464093 :     loc = cp_expr_loc_or_input_loc (retval);
   10967              : 
   10968     50591930 :   for (;;)
   10969              :     {
   10970     50591930 :       if (TREE_CODE (whats_returned) == COMPOUND_EXPR)
   10971       748384 :         whats_returned = TREE_OPERAND (whats_returned, 1);
   10972     49843546 :       else if (CONVERT_EXPR_P (whats_returned)
   10973     41480457 :                || TREE_CODE (whats_returned) == NON_LVALUE_EXPR)
   10974      8379453 :         whats_returned = TREE_OPERAND (whats_returned, 0);
   10975              :       else
   10976              :         break;
   10977              :     }
   10978              : 
   10979     41464093 :   if (TREE_CODE (whats_returned) == TARGET_EXPR
   10980     41464093 :       && is_std_init_list (TREE_TYPE (whats_returned)))
   10981              :     {
   10982           16 :       tree init = TARGET_EXPR_INITIAL (whats_returned);
   10983           16 :       if (TREE_CODE (init) == CONSTRUCTOR)
   10984              :         /* Pull out the array address.  */
   10985            7 :         whats_returned = CONSTRUCTOR_ELT (init, 0)->value;
   10986            9 :       else if (TREE_CODE (init) == INDIRECT_REF)
   10987              :         /* The source of a trivial copy looks like *(T*)&var.  */
   10988            6 :         whats_returned = TREE_OPERAND (init, 0);
   10989              :       else
   10990              :         return false;
   10991           13 :       STRIP_NOPS (whats_returned);
   10992              :     }
   10993              : 
   10994              :   /* As a special case, we handle a call to std::move or std::forward.  */
   10995     41464090 :   if (TREE_CODE (whats_returned) == CALL_EXPR
   10996     41464090 :       && (is_std_move_p (whats_returned)
   10997      9971099 :           || is_std_forward_p (whats_returned)))
   10998              :     {
   10999          787 :       tree arg = CALL_EXPR_ARG (whats_returned, 0);
   11000          787 :       return maybe_warn_about_returning_address_of_local (arg, loc);
   11001              :     }
   11002              : 
   11003     41463303 :   if (TREE_CODE (whats_returned) != ADDR_EXPR)
   11004              :     return false;
   11005       879166 :   whats_returned = TREE_OPERAND (whats_returned, 0);
   11006              : 
   11007       879166 :   while (TREE_CODE (whats_returned) == COMPONENT_REF
   11008      1716356 :          || TREE_CODE (whats_returned) == ARRAY_REF)
   11009       837190 :     whats_returned = TREE_OPERAND (whats_returned, 0);
   11010              : 
   11011       879166 :   if (TREE_CODE (whats_returned) == AGGR_INIT_EXPR
   11012       879166 :       || TREE_CODE (whats_returned) == TARGET_EXPR)
   11013              :     {
   11014           50 :       if (TYPE_REF_P (valtype))
   11015              :         /* P2748 made this an error in C++26.  */
   11016           72 :         emit_diagnostic ((cxx_dialect >= cxx26
   11017              :                           ? diagnostics::kind::permerror
   11018              :                           : diagnostics::kind::warning),
   11019           41 :                          loc, OPT_Wreturn_local_addr,
   11020              :                          "returning reference to temporary");
   11021            9 :       else if (TYPE_PTR_P (valtype))
   11022            3 :         warning_at (loc, OPT_Wreturn_local_addr,
   11023              :                     "returning pointer to temporary");
   11024            6 :       else if (is_std_init_list (valtype))
   11025            6 :         warning_at (loc, OPT_Winit_list_lifetime,
   11026              :                     "returning temporary %<initializer_list%> does not extend "
   11027              :                     "the lifetime of the underlying array");
   11028           50 :       return true;
   11029              :     }
   11030              : 
   11031       879116 :   STRIP_ANY_LOCATION_WRAPPER (whats_returned);
   11032              : 
   11033       879116 :   if (DECL_P (whats_returned)
   11034       108019 :       && DECL_NAME (whats_returned)
   11035       108019 :       && DECL_FUNCTION_SCOPE_P (whats_returned)
   11036        12038 :       && !is_capture_proxy (whats_returned)
   11037       891133 :       && !(TREE_STATIC (whats_returned)
   11038          146 :            || TREE_PUBLIC (whats_returned)))
   11039              :     {
   11040          106 :       if (DECL_DECOMPOSITION_P (whats_returned)
   11041           39 :           && !DECL_DECOMP_IS_BASE (whats_returned)
   11042          185 :           && DECL_HAS_VALUE_EXPR_P (whats_returned))
   11043              :         {
   11044              :           /* When returning address of a structured binding, if the structured
   11045              :              binding is not a reference, continue normally, if it is a
   11046              :              reference, recurse on the initializer of the structured
   11047              :              binding.  */
   11048           39 :           tree base = DECL_DECOMP_BASE (whats_returned);
   11049           39 :           if (TYPE_REF_P (TREE_TYPE (base)))
   11050              :             {
   11051           15 :               if (tree init = DECL_INITIAL (base))
   11052              :                 return maybe_warn_about_returning_address_of_local (init, loc);
   11053              :               else
   11054              :                 return false;
   11055              :             }
   11056              :         }
   11057          131 :       bool w = false;
   11058          131 :       auto_diagnostic_group d;
   11059          131 :       if (TYPE_REF_P (valtype))
   11060           81 :         w = warning_at (loc, OPT_Wreturn_local_addr,
   11061              :                         "reference to local variable %qD returned",
   11062              :                         whats_returned);
   11063           50 :       else if (is_std_init_list (valtype))
   11064            3 :         w = warning_at (loc, OPT_Winit_list_lifetime,
   11065              :                         "returning local %<initializer_list%> variable %qD "
   11066              :                         "does not extend the lifetime of the underlying array",
   11067              :                         whats_returned);
   11068           47 :       else if (POINTER_TYPE_P (valtype)
   11069           41 :                && TREE_CODE (whats_returned) == LABEL_DECL)
   11070            6 :         w = warning_at (loc, OPT_Wreturn_local_addr,
   11071              :                         "address of label %qD returned",
   11072              :                         whats_returned);
   11073           41 :       else if (POINTER_TYPE_P (valtype))
   11074           35 :         w = warning_at (loc, OPT_Wreturn_local_addr,
   11075              :                         "address of local variable %qD returned",
   11076              :                         whats_returned);
   11077          125 :       if (w)
   11078          103 :         inform (DECL_SOURCE_LOCATION (whats_returned),
   11079              :                 "declared here");
   11080          131 :       return true;
   11081          131 :     }
   11082              : 
   11083              :   return false;
   11084              : }
   11085              : 
   11086              : /* Returns true if DECL is in the std namespace.  */
   11087              : 
   11088              : bool
   11089    126680386 : decl_in_std_namespace_p (tree decl)
   11090              : {
   11091    150430267 :   while (decl)
   11092              :     {
   11093    149741782 :       decl = decl_namespace_context (decl);
   11094    149741782 :       if (DECL_NAMESPACE_STD_P (decl))
   11095              :         return true;
   11096              :       /* Allow inline namespaces inside of std namespace, e.g. with
   11097              :          --enable-symvers=gnu-versioned-namespace std::forward would be
   11098              :          actually std::_8::forward.  */
   11099     70647928 :       if (!DECL_NAMESPACE_INLINE_P (decl))
   11100              :         return false;
   11101     23749881 :       decl = CP_DECL_CONTEXT (decl);
   11102              :     }
   11103              :   return false;
   11104              : }
   11105              : 
   11106              : /* Returns true if FN, a CALL_EXPR, is a call to std::forward.  */
   11107              : 
   11108              : static bool
   11109      9971099 : is_std_forward_p (tree fn)
   11110              : {
   11111              :   /* std::forward only takes one argument.  */
   11112      9971099 :   if (call_expr_nargs (fn) != 1)
   11113              :     return false;
   11114              : 
   11115      4541333 :   tree fndecl = cp_get_callee_fndecl_nofold (fn);
   11116      4541333 :   if (!decl_in_std_namespace_p (fndecl))
   11117              :     return false;
   11118              : 
   11119      1703723 :   tree name = DECL_NAME (fndecl);
   11120      1703723 :   return name && id_equal (name, "forward");
   11121              : }
   11122              : 
   11123              : /* Returns true if FN, a CALL_EXPR, is a call to std::move.  */
   11124              : 
   11125              : static bool
   11126      9978408 : is_std_move_p (tree fn)
   11127              : {
   11128              :   /* std::move only takes one argument.  */
   11129      9978408 :   if (call_expr_nargs (fn) != 1)
   11130              :     return false;
   11131              : 
   11132      4547811 :   tree fndecl = cp_get_callee_fndecl_nofold (fn);
   11133      4547811 :   if (!decl_in_std_namespace_p (fndecl))
   11134              :     return false;
   11135              : 
   11136      1709723 :   tree name = DECL_NAME (fndecl);
   11137      1709723 :   return name && id_equal (name, "move");
   11138              : }
   11139              : 
   11140              : /* Returns true if RETVAL is a good candidate for the NRVO as per
   11141              :    [class.copy.elision].  FUNCTYPE is the type the function is declared
   11142              :    to return.  */
   11143              : 
   11144              : static bool
   11145     53762637 : can_do_nrvo_p (tree retval, tree functype)
   11146              : {
   11147     53762637 :   if (functype == error_mark_node)
   11148              :     return false;
   11149     53762591 :   if (retval)
   11150     52154737 :     STRIP_ANY_LOCATION_WRAPPER (retval);
   11151     53762591 :   tree result = DECL_RESULT (current_function_decl);
   11152     53762591 :   return (retval != NULL_TREE
   11153     52154737 :           && !processing_template_decl
   11154              :           /* Must be a local, automatic variable.  */
   11155     42950221 :           && VAR_P (retval)
   11156      3737425 :           && DECL_CONTEXT (retval) == current_function_decl
   11157      2719023 :           && !TREE_STATIC (retval)
   11158              :           /* And not a lambda or anonymous union proxy.  */
   11159      2716176 :           && !DECL_HAS_VALUE_EXPR_P (retval)
   11160      2715928 :           && (DECL_ALIGN (retval) <= DECL_ALIGN (result))
   11161              :           /* The cv-unqualified type of the returned value must be the
   11162              :              same as the cv-unqualified return type of the
   11163              :              function.  */
   11164      2715807 :           && same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (retval)),
   11165              :                           TYPE_MAIN_VARIANT (functype))
   11166              :           /* And the returned value must be non-volatile.  */
   11167     56456352 :           && !TYPE_VOLATILE (TREE_TYPE (retval)));
   11168              : }
   11169              : 
   11170              : /* True if we would like to perform NRVO, i.e. can_do_nrvo_p is true and we
   11171              :    would otherwise return in memory.  */
   11172              : 
   11173              : static bool
   11174     53762267 : want_nrvo_p (tree retval, tree functype)
   11175              : {
   11176     53762267 :   return (can_do_nrvo_p (retval, functype)
   11177     53762267 :           && aggregate_value_p (functype, current_function_decl));
   11178              : }
   11179              : 
   11180              : /* Like can_do_nrvo_p, but we check if we're trying to move a class
   11181              :    prvalue.  */
   11182              : 
   11183              : static bool
   11184         1399 : can_elide_copy_prvalue_p (tree retval, tree functype)
   11185              : {
   11186         1399 :   if (functype == error_mark_node)
   11187              :     return false;
   11188         1399 :   if (retval)
   11189         1399 :     STRIP_ANY_LOCATION_WRAPPER (retval);
   11190         1399 :   return (retval != NULL_TREE
   11191         1399 :           && !glvalue_p (retval)
   11192          135 :           && same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (retval)),
   11193              :                           TYPE_MAIN_VARIANT (functype))
   11194         1507 :           && !TYPE_VOLATILE (TREE_TYPE (retval)));
   11195              : }
   11196              : 
   11197              : /* If we should treat RETVAL, an expression being returned, as if it were
   11198              :    designated by an rvalue, returns it adjusted accordingly; otherwise, returns
   11199              :    NULL_TREE.  See [class.copy.elision].  RETURN_P is true if this is a return
   11200              :    context (rather than throw).  */
   11201              : 
   11202              : tree
   11203     10386086 : treat_lvalue_as_rvalue_p (tree expr, bool return_p)
   11204              : {
   11205     10386086 :   if (cxx_dialect == cxx98)
   11206              :     return NULL_TREE;
   11207              : 
   11208     10377123 :   tree retval = expr;
   11209     10377123 :   STRIP_ANY_LOCATION_WRAPPER (retval);
   11210     10377123 :   if (REFERENCE_REF_P (retval))
   11211       452920 :     retval = TREE_OPERAND (retval, 0);
   11212              : 
   11213              :   /* An implicitly movable entity is a variable of automatic storage duration
   11214              :      that is either a non-volatile object or (C++20) an rvalue reference to a
   11215              :      non-volatile object type.  */
   11216     10377123 :   if (!(((VAR_P (retval) && !DECL_HAS_VALUE_EXPR_P (retval))
   11217      9279534 :          || TREE_CODE (retval) == PARM_DECL)
   11218      1616770 :         && !TREE_STATIC (retval)
   11219      1532921 :         && !CP_TYPE_VOLATILE_P (non_reference (TREE_TYPE (retval)))
   11220      1532916 :         && (TREE_CODE (TREE_TYPE (retval)) != REFERENCE_TYPE
   11221       109204 :             || (cxx_dialect >= cxx20
   11222       108663 :                 && TYPE_REF_IS_RVALUE (TREE_TYPE (retval))))))
   11223      8952838 :     return NULL_TREE;
   11224              : 
   11225              :   /* If the expression in a return or co_return statement is a (possibly
   11226              :      parenthesized) id-expression that names an implicitly movable entity
   11227              :      declared in the body or parameter-declaration-clause of the innermost
   11228              :      enclosing function or lambda-expression, */
   11229      1424285 :   if (return_p)
   11230              :     {
   11231      1415126 :       if (DECL_CONTEXT (retval) != current_function_decl)
   11232              :         return NULL_TREE;
   11233      1415059 :       expr = move (expr);
   11234      1415059 :       if (expr == error_mark_node)
   11235              :         return NULL_TREE;
   11236      1415057 :       return set_implicit_rvalue_p (expr);
   11237              :     }
   11238              : 
   11239              :   /* if the id-expression (possibly parenthesized) is the operand of
   11240              :      a throw-expression, and names an implicitly movable entity that belongs
   11241              :      to a scope that does not contain the compound-statement of the innermost
   11242              :      lambda-expression, try-block, or function-try-block (if any) whose
   11243              :      compound-statement or ctor-initializer contains the throw-expression.  */
   11244              : 
   11245              :   /* C++20 added move on throw of parms.  */
   11246         9159 :   if (TREE_CODE (retval) == PARM_DECL && cxx_dialect < cxx20)
   11247              :     return NULL_TREE;
   11248              : 
   11249              :   /* We don't check for lambda-expression here, because we should not get past
   11250              :      the DECL_HAS_VALUE_EXPR_P check above.  */
   11251         9146 :   for (cp_binding_level *b = current_binding_level;
   11252         9240 :        b->kind != sk_namespace; b = b->level_chain)
   11253              :     {
   11254         9238 :       for (tree decl = b->names; decl; decl = TREE_CHAIN (decl))
   11255          101 :         if (decl == retval)
   11256           89 :           return set_implicit_rvalue_p (move (expr));
   11257         9137 :       if (b->kind == sk_try)
   11258              :         return NULL_TREE;
   11259              :     }
   11260              : 
   11261           14 :   return set_implicit_rvalue_p (move (expr));
   11262              : }
   11263              : 
   11264              : /* Warn about dubious usage of std::move (in a return statement, if RETURN_P
   11265              :    is true).  EXPR is the std::move expression; TYPE is the type of the object
   11266              :    being initialized.  */
   11267              : 
   11268              : void
   11269    147367195 : maybe_warn_pessimizing_move (tree expr, tree type, bool return_p)
   11270              : {
   11271    147367195 :   if (!(warn_pessimizing_move || warn_redundant_move))
   11272              :     return;
   11273              : 
   11274      4548009 :   const location_t loc = cp_expr_loc_or_input_loc (expr);
   11275              : 
   11276              :   /* C++98 doesn't know move.  */
   11277      4548009 :   if (cxx_dialect < cxx11)
   11278              :     return;
   11279              : 
   11280              :   /* Wait until instantiation time, since we can't gauge if we should do
   11281              :      the NRVO until then.  */
   11282      4485578 :   if (processing_template_decl)
   11283              :     return;
   11284              : 
   11285              :   /* This is only interesting for class types.  */
   11286      4396945 :   if (!CLASS_TYPE_P (type))
   11287              :     return;
   11288              : 
   11289       107758 :   bool wrapped_p = false;
   11290              :   /* A a = std::move (A());  */
   11291       107758 :   if (TREE_CODE (expr) == TREE_LIST)
   11292              :     {
   11293         8900 :       if (list_length (expr) == 1)
   11294              :         {
   11295         5975 :           expr = TREE_VALUE (expr);
   11296         5975 :           wrapped_p = true;
   11297              :         }
   11298              :       else
   11299              :         return;
   11300              :     }
   11301              :   /* A a = {std::move (A())};
   11302              :      A a{std::move (A())};  */
   11303        98858 :   else if (TREE_CODE (expr) == CONSTRUCTOR)
   11304              :     {
   11305         7408 :       if (CONSTRUCTOR_NELTS (expr) == 1)
   11306              :         {
   11307          875 :           expr = CONSTRUCTOR_ELT (expr, 0)->value;
   11308          875 :           wrapped_p = true;
   11309              :         }
   11310              :       else
   11311              :         return;
   11312              :     }
   11313              : 
   11314              :   /* First, check if this is a call to std::move.  */
   11315         6795 :   if (!REFERENCE_REF_P (expr)
   11316       103042 :       || TREE_CODE (TREE_OPERAND (expr, 0)) != CALL_EXPR)
   11317              :     return;
   11318         2657 :   tree fn = TREE_OPERAND (expr, 0);
   11319         2657 :   if (!is_std_move_p (fn))
   11320              :     return;
   11321         2042 :   tree arg = CALL_EXPR_ARG (fn, 0);
   11322         2042 :   if (TREE_CODE (arg) != NOP_EXPR)
   11323              :     return;
   11324              :   /* If we're looking at *std::move<T&> ((T &) &arg), do the pessimizing N/RVO
   11325              :      and implicitly-movable warnings.  */
   11326         2042 :   if (TREE_CODE (TREE_OPERAND (arg, 0)) == ADDR_EXPR)
   11327              :     {
   11328         1399 :       arg = TREE_OPERAND (arg, 0);
   11329         1399 :       arg = TREE_OPERAND (arg, 0);
   11330         1399 :       arg = convert_from_reference (arg);
   11331         1399 :       if (can_elide_copy_prvalue_p (arg, type))
   11332              :         {
   11333          108 :           auto_diagnostic_group d;
   11334          108 :           if (warning_at (loc, OPT_Wpessimizing_move,
   11335              :                           "moving a temporary object prevents copy elision"))
   11336          108 :             inform (loc, "remove %<std::move%> call");
   11337          108 :         }
   11338              :       /* The rest of the warnings is only relevant for when we are returning
   11339              :          from a function.  */
   11340         1399 :       if (!return_p)
   11341              :         return;
   11342              : 
   11343          370 :       tree moved;
   11344              :       /* Warn if we could do copy elision were it not for the move.  */
   11345          370 :       if (can_do_nrvo_p (arg, type))
   11346              :         {
   11347           48 :           auto_diagnostic_group d;
   11348           48 :           if (!warning_suppressed_p (expr, OPT_Wpessimizing_move)
   11349           48 :               && warning_at (loc, OPT_Wpessimizing_move,
   11350              :                              "moving a local object in a return statement "
   11351              :                              "prevents copy elision"))
   11352           42 :             inform (loc, "remove %<std::move%> call");
   11353           48 :         }
   11354              :       /* Warn if the move is redundant.  It is redundant when we would
   11355              :          do maybe-rvalue overload resolution even without std::move.  */
   11356          322 :       else if (warn_redundant_move
   11357              :                /* This doesn't apply for return {std::move (t)};.  */
   11358          224 :                && !wrapped_p
   11359          221 :                && !warning_suppressed_p (expr, OPT_Wredundant_move)
   11360          418 :                && (moved = treat_lvalue_as_rvalue_p (arg, /*return*/true)))
   11361              :         {
   11362              :           /* Make sure that overload resolution would actually succeed
   11363              :              if we removed the std::move call.  */
   11364           54 :           tree t = convert_for_initialization (NULL_TREE, type,
   11365              :                                                moved,
   11366              :                                                (LOOKUP_NORMAL
   11367              :                                                 | LOOKUP_ONLYCONVERTING),
   11368              :                                                ICR_RETURN, NULL_TREE, 0,
   11369              :                                                tf_none);
   11370              :           /* If this worked, implicit rvalue would work, so the call to
   11371              :              std::move is redundant.  */
   11372           54 :           if (t != error_mark_node)
   11373              :             {
   11374           54 :               auto_diagnostic_group d;
   11375           54 :               if (warning_at (loc, OPT_Wredundant_move,
   11376              :                               "redundant move in return statement"))
   11377           54 :                 inform (loc, "remove %<std::move%> call");
   11378           54 :             }
   11379              :         }
   11380              :      }
   11381              :   /* Also try to warn about redundant std::move in code such as
   11382              :       T f (const T& t)
   11383              :       {
   11384              :         return std::move(t);
   11385              :       }
   11386              :     for which EXPR will be something like
   11387              :       *std::move<const T&> ((const struct T &) (const struct T *) t)
   11388              :      and where the std::move does nothing if T does not have a T(const T&&)
   11389              :      constructor, because the argument is const.  It will not use T(T&&)
   11390              :      because that would mean losing the const.  */
   11391          643 :   else if (warn_redundant_move
   11392          521 :            && !warning_suppressed_p (expr, OPT_Wredundant_move)
   11393           66 :            && TYPE_REF_P (TREE_TYPE (arg))
   11394          709 :            && CP_TYPE_CONST_P (TREE_TYPE (TREE_TYPE (arg))))
   11395              :     {
   11396           18 :       tree rtype = TREE_TYPE (TREE_TYPE (arg));
   11397           18 :       if (!same_type_ignoring_top_level_qualifiers_p (rtype, type))
   11398            9 :         return;
   11399              :       /* Check for the unlikely case there's T(const T&&) (we don't care if
   11400              :          it's deleted).  */
   11401           54 :       for (tree fn : ovl_range (CLASSTYPE_CONSTRUCTORS (rtype)))
   11402           30 :         if (move_fn_p (fn))
   11403              :           {
   11404           15 :             tree t = TREE_VALUE (FUNCTION_FIRST_USER_PARMTYPE (fn));
   11405           15 :             if (UNLIKELY (CP_TYPE_CONST_P (TREE_TYPE (t))))
   11406            6 :               return;
   11407              :           }
   11408            9 :       auto_diagnostic_group d;
   11409           18 :       if (return_p
   11410            9 :           ? warning_at (loc, OPT_Wredundant_move,
   11411              :                         "redundant move in return statement")
   11412            9 :           : warning_at (loc, OPT_Wredundant_move,
   11413              :                         "redundant move in initialization"))
   11414            9 :         inform (loc, "remove %<std::move%> call");
   11415            9 :     }
   11416              : }
   11417              : 
   11418              : /* Check that returning RETVAL from the current function is valid.
   11419              :    Return an expression explicitly showing all conversions required to
   11420              :    change RETVAL into the function return type, and to assign it to
   11421              :    the DECL_RESULT for the function.  Set *NO_WARNING to true if
   11422              :    code reaches end of non-void function warning shouldn't be issued
   11423              :    on this RETURN_EXPR.  Set *DANGLING to true if code returns the
   11424              :    address of a local variable.  */
   11425              : 
   11426              : tree
   11427    124415217 : check_return_expr (tree retval, bool *no_warning, bool *dangling)
   11428              : {
   11429    124415217 :   tree result;
   11430              :   /* The type actually returned by the function.  */
   11431    124415217 :   tree valtype;
   11432              :   /* The type the function is declared to return, or void if
   11433              :      the declared type is incomplete.  */
   11434    124415217 :   tree functype;
   11435    124415217 :   int fn_returns_value_p;
   11436    124415217 :   location_t loc = cp_expr_loc_or_input_loc (retval);
   11437              : 
   11438    124415217 :   *no_warning = false;
   11439    124415217 :   *dangling = false;
   11440              : 
   11441              :   /* A `volatile' function is one that isn't supposed to return, ever.
   11442              :      (This is a G++ extension, used to get better code for functions
   11443              :      that call the `volatile' function.)  */
   11444    124415217 :   if (TREE_THIS_VOLATILE (current_function_decl))
   11445           12 :     warning (0, "function declared %<noreturn%> has a %<return%> statement");
   11446              : 
   11447              :   /* Check for various simple errors.  */
   11448    248830434 :   if (DECL_DESTRUCTOR_P (current_function_decl))
   11449              :     {
   11450         2291 :       if (retval)
   11451            3 :         error_at (loc, "returning a value from a destructor");
   11452              : 
   11453         2291 :       if (targetm.cxx.cdtor_returns_this () && !processing_template_decl)
   11454            0 :         retval = current_class_ptr;
   11455              :       else
   11456              :         return NULL_TREE;
   11457              :     }
   11458    124412926 :   else if (DECL_CONSTRUCTOR_P (current_function_decl))
   11459              :     {
   11460        61278 :       if (in_function_try_handler)
   11461              :         /* If a return statement appears in a handler of the
   11462              :            function-try-block of a constructor, the program is ill-formed.  */
   11463            0 :         error ("cannot return from a handler of a function-try-block of a constructor");
   11464        61278 :       else if (retval)
   11465              :         /* You can't return a value from a constructor.  */
   11466            3 :         error_at (loc, "returning a value from a constructor");
   11467              : 
   11468        61278 :       if (targetm.cxx.cdtor_returns_this () && !processing_template_decl)
   11469            0 :         retval = current_class_ptr;
   11470              :       else
   11471              :         return NULL_TREE;
   11472              :     }
   11473              : 
   11474    124351648 :   const tree saved_retval = retval;
   11475              : 
   11476    124351648 :   if (processing_template_decl)
   11477              :     {
   11478     80775256 :       current_function_returns_value = 1;
   11479              : 
   11480     80775256 :       if (check_for_bare_parameter_packs (retval))
   11481           14 :         return error_mark_node;
   11482              : 
   11483              :       /* If one of the types might be void, we can't tell whether we're
   11484              :          returning a value.  */
   11485     80775242 :       if ((WILDCARD_TYPE_P (TREE_TYPE (DECL_RESULT (current_function_decl)))
   11486     34057772 :            && !FNDECL_USED_AUTO (current_function_decl))
   11487     46717479 :           || (retval != NULL_TREE
   11488     45597411 :               && (TREE_TYPE (retval) == NULL_TREE
   11489     31651050 :                   || WILDCARD_TYPE_P (TREE_TYPE (retval)))))
   11490     54819226 :         goto dependent;
   11491              :     }
   11492              : 
   11493     69532408 :   functype = TREE_TYPE (TREE_TYPE (current_function_decl));
   11494              : 
   11495              :   /* Deduce auto return type from a return statement.  */
   11496     69532408 :   if (FNDECL_USED_AUTO (current_function_decl))
   11497              :     {
   11498       942534 :       tree pattern = DECL_SAVED_AUTO_RETURN_TYPE (current_function_decl);
   11499       942534 :       tree auto_node;
   11500       942534 :       tree type;
   11501              : 
   11502       942534 :       if (!retval && !is_auto (pattern))
   11503              :         {
   11504              :           /* Give a helpful error message.  */
   11505            3 :           auto_diagnostic_group d;
   11506            3 :           error ("return-statement with no value, in function returning %qT",
   11507              :                  pattern);
   11508            3 :           inform (input_location, "only plain %<auto%> return type can be "
   11509              :                   "deduced to %<void%>");
   11510            3 :           type = error_mark_node;
   11511            3 :         }
   11512       942531 :       else if (retval && BRACE_ENCLOSED_INITIALIZER_P (retval))
   11513              :         {
   11514            6 :           error ("returning initializer list");
   11515            6 :           type = error_mark_node;
   11516              :         }
   11517              :       else
   11518              :         {
   11519       942525 :           if (!retval)
   11520         1928 :             retval = void_node;
   11521       942525 :           auto_node = type_uses_auto (pattern);
   11522       942525 :           type = do_auto_deduction (pattern, retval, auto_node,
   11523              :                                     tf_warning_or_error, adc_return_type);
   11524              :         }
   11525              : 
   11526       942534 :       if (type == error_mark_node)
   11527              :         /* Leave it.  */;
   11528       942320 :       else if (functype == pattern)
   11529       766883 :         apply_deduced_return_type (current_function_decl, type);
   11530       175437 :       else if (!same_type_p (type, functype))
   11531              :         {
   11532           24 :           if (LAMBDA_FUNCTION_P (current_function_decl))
   11533            6 :             error_at (loc, "inconsistent types %qT and %qT deduced for "
   11534              :                       "lambda return type", functype, type);
   11535              :           else
   11536           12 :             error_at (loc, "inconsistent deduction for auto return type: "
   11537              :                       "%qT and then %qT", functype, type);
   11538              :         }
   11539              :       functype = type;
   11540              :     }
   11541              : 
   11542     69532408 :   result = DECL_RESULT (current_function_decl);
   11543     69532408 :   valtype = TREE_TYPE (result);
   11544     69532408 :   gcc_assert (valtype != NULL_TREE);
   11545     69532408 :   fn_returns_value_p = !VOID_TYPE_P (valtype);
   11546              : 
   11547              :   /* Check for a return statement with no return value in a function
   11548              :      that's supposed to return a value.  */
   11549     69532408 :   if (!retval && fn_returns_value_p)
   11550              :     {
   11551           33 :       if (functype != error_mark_node)
   11552           30 :         permerror (input_location, "return-statement with no value, in "
   11553              :                    "function returning %qT", valtype);
   11554              :       /* Remember that this function did return.  */
   11555           33 :       current_function_returns_value = 1;
   11556              :       /* But suppress NRV  .*/
   11557           33 :       current_function_return_value = error_mark_node;
   11558              :       /* And signal caller that TREE_NO_WARNING should be set on the
   11559              :          RETURN_EXPR to avoid control reaches end of non-void function
   11560              :          warnings in tree-cfg.cc.  */
   11561           33 :       *no_warning = true;
   11562              :     }
   11563              :   /* Check for a return statement with a value in a function that
   11564              :      isn't supposed to return a value.  */
   11565     69532375 :   else if (retval && !fn_returns_value_p)
   11566              :     {
   11567       147173 :       if (VOID_TYPE_P (TREE_TYPE (retval)))
   11568              :         /* You can return a `void' value from a function of `void'
   11569              :            type.  In that case, we have to evaluate the expression for
   11570              :            its side-effects.  */
   11571       147138 :         finish_expr_stmt (retval);
   11572           35 :       else if (retval != error_mark_node)
   11573           32 :         permerror (loc, "return-statement with a value, in function "
   11574              :                    "returning %qT", valtype);
   11575       147173 :       current_function_returns_null = 1;
   11576              : 
   11577              :       /* There's really no value to return, after all.  */
   11578       147173 :       return NULL_TREE;
   11579              :     }
   11580     69385202 :   else if (!retval)
   11581              :     /* Remember that this function can sometimes return without a
   11582              :        value.  */
   11583      1607839 :     current_function_returns_null = 1;
   11584              :   else
   11585              :     /* Remember that this function did return a value.  */
   11586     67777363 :     current_function_returns_value = 1;
   11587              : 
   11588              :   /* Check for erroneous operands -- but after giving ourselves a
   11589              :      chance to provide an error about returning a value from a void
   11590              :      function.  */
   11591     69385235 :   if (error_operand_p (retval))
   11592              :     {
   11593          994 :       current_function_return_value = error_mark_node;
   11594          994 :       return error_mark_node;
   11595              :     }
   11596              : 
   11597              :   /* Only operator new(...) throw(), can return NULL [expr.new/13].  */
   11598    138768482 :   if (IDENTIFIER_NEW_OP_P (DECL_NAME (current_function_decl))
   11599        30418 :       && !TYPE_NOTHROW_P (TREE_TYPE (current_function_decl))
   11600         2330 :       && ! flag_check_new
   11601     69386562 :       && retval && null_ptr_cst_p (retval))
   11602           24 :     warning (0, "%<operator new%> must not return NULL unless it is "
   11603              :              "declared %<throw()%> (or %<-fcheck-new%> is in effect)");
   11604              : 
   11605              :   /* Effective C++ rule 15.  See also start_function.  */
   11606     69384241 :   if (warn_ecpp
   11607           42 :       && DECL_NAME (current_function_decl) == assign_op_identifier
   11608     69384271 :       && !type_dependent_expression_p (retval))
   11609              :     {
   11610           27 :       bool warn = true;
   11611              : 
   11612              :       /* The function return type must be a reference to the current
   11613              :         class.  */
   11614           27 :       if (TYPE_REF_P (valtype)
   11615           45 :           && same_type_ignoring_top_level_qualifiers_p
   11616           18 :               (TREE_TYPE (valtype), TREE_TYPE (current_class_ref)))
   11617              :         {
   11618              :           /* Returning '*this' is obviously OK.  */
   11619           18 :           if (retval == current_class_ref)
   11620              :             warn = false;
   11621              :           /* If we are calling a function whose return type is the same of
   11622              :              the current class reference, it is ok.  */
   11623            6 :           else if (INDIRECT_REF_P (retval)
   11624            6 :                    && TREE_CODE (TREE_OPERAND (retval, 0)) == CALL_EXPR)
   11625              :             warn = false;
   11626              :         }
   11627              : 
   11628              :       if (warn)
   11629            9 :         warning_at (loc, OPT_Weffc__,
   11630              :                     "%<operator=%> should return a reference to %<*this%>");
   11631              :     }
   11632              : 
   11633     69384241 :   if (dependent_type_p (functype)
   11634     69384241 :       || type_dependent_expression_p (retval))
   11635              :     {
   11636     70441200 :     dependent:
   11637              :       /* We should not have changed the return value.  */
   11638     70441200 :       gcc_assert (retval == saved_retval);
   11639              :       /* We don't know if this is an lvalue or rvalue use, but
   11640              :          either way we can mark it as read.  */
   11641     70441200 :       mark_exp_read (retval);
   11642     70441200 :       return retval;
   11643              :     }
   11644              : 
   11645              :   /* The fabled Named Return Value optimization, as per [class.copy]/15:
   11646              : 
   11647              :      [...]      For  a function with a class return type, if the expression
   11648              :      in the return statement is the name of a local  object,  and  the  cv-
   11649              :      unqualified  type  of  the  local  object  is the same as the function
   11650              :      return type, an implementation is permitted to omit creating the  tem-
   11651              :      porary  object  to  hold  the function return value [...]
   11652              : 
   11653              :      So, if this is a value-returning function that always returns the same
   11654              :      local variable, remember it.
   11655              : 
   11656              :      We choose the first suitable variable even if the function sometimes
   11657              :      returns something else, but only if the variable is out of scope at the
   11658              :      other return sites, or else we run the risk of clobbering the variable we
   11659              :      chose if the other returned expression uses the chosen variable somehow.
   11660              : 
   11661              :      We don't currently do this if the first return is a non-variable, as it
   11662              :      would be complicated to determine whether an NRV selected later was in
   11663              :      scope at the point of the earlier return.  We also don't currently support
   11664              :      multiple variables with non-overlapping scopes (53637).
   11665              : 
   11666              :      See finish_function and finalize_nrv for the rest of this optimization.  */
   11667     53762267 :   tree bare_retval = NULL_TREE;
   11668     53762267 :   if (retval)
   11669              :     {
   11670     52154410 :       retval = maybe_undo_parenthesized_ref (retval);
   11671     52154410 :       bare_retval = tree_strip_any_location_wrapper (retval);
   11672              :     }
   11673              : 
   11674     53762267 :   bool named_return_value_okay_p = want_nrvo_p (bare_retval, functype);
   11675     53762267 :   if (fn_returns_value_p && flag_elide_constructors
   11676     52154387 :       && current_function_return_value != bare_retval)
   11677              :     {
   11678     52149607 :       if (named_return_value_okay_p
   11679       255525 :           && current_function_return_value == NULL_TREE)
   11680       216297 :         current_function_return_value = bare_retval;
   11681     51933310 :       else if (current_function_return_value
   11682     10338310 :                && VAR_P (current_function_return_value)
   11683          200 :                && DECL_NAME (current_function_return_value)
   11684     51933510 :                && !decl_in_scope_p (current_function_return_value))
   11685              :         {
   11686              :           /* The earlier NRV is out of scope at this point, so it's safe to
   11687          137 :              leave it alone; the current return can't refer to it.  */;
   11688          137 :           if (named_return_value_okay_p
   11689          137 :               && !warning_suppressed_p (current_function_decl, OPT_Wnrvo))
   11690              :             {
   11691           12 :               warning (OPT_Wnrvo, "not eliding copy on return from %qD",
   11692              :                        bare_retval);
   11693           12 :               suppress_warning (current_function_decl, OPT_Wnrvo);
   11694              :             }
   11695              :         }
   11696              :       else
   11697              :         {
   11698     51933173 :           if ((named_return_value_okay_p
   11699     51893959 :                || (current_function_return_value
   11700     10298959 :                    && current_function_return_value != error_mark_node))
   11701     51933214 :               && !warning_suppressed_p (current_function_decl, OPT_Wnrvo))
   11702              :             {
   11703        39192 :               warning (OPT_Wnrvo, "not eliding copy on return in %qD",
   11704              :                        current_function_decl);
   11705        39192 :               suppress_warning (current_function_decl, OPT_Wnrvo);
   11706              :             }
   11707     51933173 :           current_function_return_value = error_mark_node;
   11708              :         }
   11709              :     }
   11710              : 
   11711              :   /* We don't need to do any conversions when there's nothing being
   11712              :      returned.  */
   11713     53762267 :   if (!retval)
   11714              :     return NULL_TREE;
   11715              : 
   11716     52154410 :   if (!named_return_value_okay_p)
   11717     51894105 :     maybe_warn_pessimizing_move (retval, functype, /*return_p*/true);
   11718              : 
   11719              :   /* Do any required conversions.  */
   11720    104308820 :   if (bare_retval == result || DECL_CONSTRUCTOR_P (current_function_decl))
   11721              :     /* No conversions are required.  */
   11722              :     ;
   11723              :   else
   11724              :     {
   11725     52154410 :       int flags = LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING;
   11726              : 
   11727              :       /* The functype's return type will have been set to void, if it
   11728              :          was an incomplete type.  Just treat this as 'return;' */
   11729     52154410 :       if (VOID_TYPE_P (functype))
   11730            6 :         return error_mark_node;
   11731              : 
   11732              :       /* Under C++11 [12.8/32 class.copy], a returned lvalue is sometimes
   11733              :          treated as an rvalue for the purposes of overload resolution to
   11734              :          favor move constructors over copy constructors.
   11735              : 
   11736              :          Note that these conditions are similar to, but not as strict as,
   11737              :          the conditions for the named return value optimization.  */
   11738     52154404 :       bool converted = false;
   11739     52154404 :       tree moved;
   11740              :       /* Until C++23, this was only interesting for class type, but in C++23,
   11741              :          we should do the below when we're converting from/to a class/reference
   11742              :          (a non-scalar type).  */
   11743     52154404 :         if ((cxx_dialect < cxx23
   11744      7764438 :              ? CLASS_TYPE_P (functype)
   11745      6787542 :              : !SCALAR_TYPE_P (functype) || !SCALAR_TYPE_P (TREE_TYPE (retval)))
   11746     61967491 :             && (moved = treat_lvalue_as_rvalue_p (retval, /*return*/true)))
   11747              :           /* In C++20 and earlier we treat the return value as an rvalue
   11748              :              that can bind to lvalue refs.  In C++23, such an expression is just
   11749              :              an xvalue (see reference_binding).  */
   11750              :           retval = moved;
   11751              : 
   11752              :       /* The call in a (lambda) thunk needs no conversions.  */
   11753     52154404 :       if (TREE_CODE (retval) == CALL_EXPR
   11754     52154404 :           && call_from_lambda_thunk_p (retval))
   11755              :         converted = true;
   11756              : 
   11757              :       /* Don't check copy-initialization for NRV in a coroutine ramp; we
   11758              :          implement this case as NRV, but it's specified as directly
   11759              :          initializing the return value from get_return_object().  */
   11760     52154404 :       if (DECL_RAMP_P (current_function_decl) && named_return_value_okay_p)
   11761              :         converted = true;
   11762              : 
   11763              :       /* First convert the value to the function's return type, then
   11764              :          to the type of return value's location to handle the
   11765              :          case that functype is smaller than the valtype.  */
   11766     52154155 :       if (!converted)
   11767     52105433 :         retval = convert_for_initialization
   11768     52105433 :           (NULL_TREE, functype, retval, flags, ICR_RETURN, NULL_TREE, 0,
   11769              :            tf_warning_or_error);
   11770     52154404 :       retval = convert (valtype, retval);
   11771              : 
   11772              :       /* If the conversion failed, treat this just like `return;'.  */
   11773     52154404 :       if (retval == error_mark_node)
   11774              :         {
   11775              :           /* And suppress NRV.  */
   11776          197 :           current_function_return_value = error_mark_node;
   11777          197 :           return retval;
   11778              :         }
   11779              :       /* We can't initialize a register from a AGGR_INIT_EXPR.  */
   11780     52154207 :       else if (! cfun->returns_struct
   11781     50113707 :                && TREE_CODE (retval) == TARGET_EXPR
   11782     58314145 :                && TREE_CODE (TARGET_EXPR_INITIAL (retval)) == AGGR_INIT_EXPR)
   11783      1486409 :         retval = build2 (COMPOUND_EXPR, TREE_TYPE (retval), retval,
   11784      1486409 :                          TARGET_EXPR_SLOT (retval));
   11785     50667798 :       else if (!processing_template_decl
   11786     41463294 :                && maybe_warn_about_returning_address_of_local (retval, loc)
   11787     50667979 :                && INDIRECT_TYPE_P (valtype))
   11788          166 :         *dangling = true;
   11789              :     }
   11790              : 
   11791     52154207 :   if (check_out_of_consteval_use (retval))
   11792              :     {
   11793            6 :       current_function_return_value = error_mark_node;
   11794            6 :       return error_mark_node;
   11795              :     }
   11796              : 
   11797              :   /* A naive attempt to reduce the number of -Wdangling-reference false
   11798              :      positives: if we know that this function can return a variable with
   11799              :      static storage duration rather than one of its parameters, suppress
   11800              :      the warning.  */
   11801     52154201 :   if (warn_dangling_reference
   11802       411726 :       && TYPE_REF_P (functype)
   11803        27635 :       && bare_retval
   11804        27635 :       && VAR_P (bare_retval)
   11805           50 :       && TREE_STATIC (bare_retval))
   11806           50 :     suppress_warning (current_function_decl, OPT_Wdangling_reference);
   11807              : 
   11808     52154201 :   if (processing_template_decl)
   11809              :     return saved_retval;
   11810              : 
   11811              :   /* Actually copy the value returned into the appropriate location.  */
   11812     42949698 :   if (retval && retval != result)
   11813     42949698 :     retval = cp_build_init_expr (result, retval);
   11814              : 
   11815     42949698 :   if (current_function_return_value == bare_retval)
   11816       221071 :     INIT_EXPR_NRV_P (retval) = true;
   11817              : 
   11818     42949698 :   if (tree set = maybe_set_retval_sentinel ())
   11819       123884 :     retval = build2 (COMPOUND_EXPR, void_type_node, retval, set);
   11820              : 
   11821              :   return retval;
   11822              : }
   11823              : 
   11824              : 
   11825              : /* Returns nonzero if the pointer-type FROM can be converted to the
   11826              :    pointer-type TO via a qualification conversion.  If CONSTP is -1,
   11827              :    then we return nonzero if the pointers are similar, and the
   11828              :    cv-qualification signature of FROM is a proper subset of that of TO.
   11829              : 
   11830              :    If CONSTP is positive, then all outer pointers have been
   11831              :    const-qualified.  */
   11832              : 
   11833              : static bool
   11834    191071411 : comp_ptr_ttypes_real (tree to, tree from, int constp)
   11835              : {
   11836    191071411 :   bool to_more_cv_qualified = false;
   11837    191071411 :   bool is_opaque_pointer = false;
   11838              : 
   11839       720157 :   for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from))
   11840              :     {
   11841    191791568 :       if (TREE_CODE (to) != TREE_CODE (from))
   11842              :         return false;
   11843              : 
   11844    130377710 :       if (TREE_CODE (from) == OFFSET_TYPE
   11845    130377710 :           && !same_type_p (TYPE_OFFSET_BASETYPE (from),
   11846              :                            TYPE_OFFSET_BASETYPE (to)))
   11847              :         return false;
   11848              : 
   11849              :       /* Const and volatile mean something different for function and
   11850              :          array types, so the usual checks are not appropriate.  We'll
   11851              :          check the array type elements in further iterations.  */
   11852    130377710 :       if (!FUNC_OR_METHOD_TYPE_P (to) && TREE_CODE (to) != ARRAY_TYPE)
   11853              :         {
   11854    130142200 :           if (!at_least_as_qualified_p (to, from))
   11855              :             return false;
   11856              : 
   11857    115535397 :           if (!at_least_as_qualified_p (from, to))
   11858              :             {
   11859     76268271 :               if (constp == 0)
   11860              :                 return false;
   11861              :               to_more_cv_qualified = true;
   11862              :             }
   11863              : 
   11864    115535134 :           if (constp > 0)
   11865    115531075 :             constp &= TYPE_READONLY (to);
   11866              :         }
   11867              : 
   11868    115770644 :       if (VECTOR_TYPE_P (to))
   11869         8507 :         is_opaque_pointer = vector_targets_convertible_p (to, from);
   11870              : 
   11871              :       /* P0388R4 allows a conversion from int[N] to int[] but not the
   11872              :          other way round.  When both arrays have bounds but they do
   11873              :          not match, then no conversion is possible.  */
   11874    115770644 :       if (TREE_CODE (to) == ARRAY_TYPE
   11875    115770644 :           && !comp_array_types (to, from, bounds_first, /*strict=*/false))
   11876              :         return false;
   11877              : 
   11878    115770088 :       if (!TYPE_PTR_P (to)
   11879              :           && !TYPE_PTRDATAMEM_P (to)
   11880              :           /* CWG 330 says we need to look through arrays.  */
   11881              :           && TREE_CODE (to) != ARRAY_TYPE)
   11882    115049931 :         return ((constp >= 0 || to_more_cv_qualified)
   11883    115049931 :                 && (is_opaque_pointer
   11884    115049401 :                     || same_type_ignoring_top_level_qualifiers_p (to, from)));
   11885              :     }
   11886              : }
   11887              : 
   11888              : /* When comparing, say, char ** to char const **, this function takes
   11889              :    the 'char *' and 'char const *'.  Do not pass non-pointer/reference
   11890              :    types to this function.  */
   11891              : 
   11892              : int
   11893    191070783 : comp_ptr_ttypes (tree to, tree from)
   11894              : {
   11895    191070783 :   return comp_ptr_ttypes_real (to, from, 1);
   11896              : }
   11897              : 
   11898              : /* Returns true iff FNTYPE is a non-class type that involves
   11899              :    error_mark_node.  We can get FUNCTION_TYPE with buried error_mark_node
   11900              :    if a parameter type is ill-formed.  */
   11901              : 
   11902              : bool
   11903       679343 : error_type_p (const_tree type)
   11904              : {
   11905       718043 :   tree t;
   11906              : 
   11907       718043 :   switch (TREE_CODE (type))
   11908              :     {
   11909              :     case ERROR_MARK:
   11910              :       return true;
   11911              : 
   11912        38611 :     case POINTER_TYPE:
   11913        38611 :     case REFERENCE_TYPE:
   11914        38611 :     case OFFSET_TYPE:
   11915        38611 :       return error_type_p (TREE_TYPE (type));
   11916              : 
   11917         2854 :     case FUNCTION_TYPE:
   11918         2854 :     case METHOD_TYPE:
   11919         2854 :       if (error_type_p (TREE_TYPE (type)))
   11920              :         return true;
   11921         7652 :       for (t = TYPE_ARG_TYPES (type); t; t = TREE_CHAIN (t))
   11922         4804 :         if (error_type_p (TREE_VALUE (t)))
   11923              :           return true;
   11924              :       return false;
   11925              : 
   11926       184465 :     case RECORD_TYPE:
   11927       184465 :       if (TYPE_PTRMEMFUNC_P (type))
   11928           89 :         return error_type_p (TYPE_PTRMEMFUNC_FN_TYPE (type));
   11929              :       return false;
   11930              : 
   11931              :     default:
   11932              :       return false;
   11933              :     }
   11934              : }
   11935              : 
   11936              : /* Returns true if to and from are (possibly multi-level) pointers to the same
   11937              :    type or inheritance-related types, regardless of cv-quals.  */
   11938              : 
   11939              : bool
   11940    137997246 : ptr_reasonably_similar (const_tree to, const_tree from)
   11941              : {
   11942         1207 :   for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from))
   11943              :     {
   11944              :       /* Any target type is similar enough to void.  */
   11945    137998453 :       if (VOID_TYPE_P (to))
   11946         1341 :         return !error_type_p (from);
   11947    137997112 :       if (VOID_TYPE_P (from))
   11948       668326 :         return !error_type_p (to);
   11949              : 
   11950    137328786 :       if (TREE_CODE (to) != TREE_CODE (from))
   11951              :         return false;
   11952              : 
   11953     76444387 :       if (TREE_CODE (from) == OFFSET_TYPE
   11954     76444387 :           && comptypes (TYPE_OFFSET_BASETYPE (to),
   11955            3 :                         TYPE_OFFSET_BASETYPE (from),
   11956              :                         COMPARE_BASE | COMPARE_DERIVED))
   11957            3 :         continue;
   11958              : 
   11959     76444381 :       if (VECTOR_TYPE_P (to)
   11960     76444381 :           && vector_types_convertible_p (to, from, false))
   11961              :         return true;
   11962              : 
   11963     76444297 :       if (TREE_CODE (to) == INTEGER_TYPE
   11964     76444297 :           && TYPE_PRECISION (to) == TYPE_PRECISION (from))
   11965              :         return true;
   11966              : 
   11967     76266646 :       if (TREE_CODE (to) == FUNCTION_TYPE)
   11968         1009 :         return !error_type_p (to) && !error_type_p (from);
   11969              : 
   11970     76265637 :       if (!TYPE_PTR_P (to))
   11971              :         {
   11972              :           /* When either type is incomplete avoid DERIVED_FROM_P,
   11973              :              which may call complete_type (c++/57942).  */
   11974     76264433 :           bool b = !COMPLETE_TYPE_P (to) || !COMPLETE_TYPE_P (from);
   11975              :           return comptypes
   11976     76264433 :             (TYPE_MAIN_VARIANT (to), TYPE_MAIN_VARIANT (from),
   11977     76264433 :              b ? COMPARE_STRICT : COMPARE_BASE | COMPARE_DERIVED);
   11978              :         }
   11979         1207 :     }
   11980              : }
   11981              : 
   11982              : /* Return true if TO and FROM (both of which are POINTER_TYPEs or
   11983              :    pointer-to-member types) are the same, ignoring cv-qualification at
   11984              :    all levels.  CB says how we should behave when comparing array bounds.  */
   11985              : 
   11986              : bool
   11987      1051531 : comp_ptr_ttypes_const (tree to, tree from, compare_bounds_t cb)
   11988              : {
   11989      1051531 :   bool is_opaque_pointer = false;
   11990              : 
   11991      1053119 :   for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from))
   11992              :     {
   11993      2104650 :       if (TREE_CODE (to) != TREE_CODE (from))
   11994              :         return false;
   11995              : 
   11996      1774988 :       if (TREE_CODE (from) == OFFSET_TYPE
   11997      1773984 :           && same_type_p (TYPE_OFFSET_BASETYPE (from),
   11998              :                           TYPE_OFFSET_BASETYPE (to)))
   11999         1004 :           continue;
   12000              : 
   12001      1772980 :       if (VECTOR_TYPE_P (to))
   12002         8706 :         is_opaque_pointer = vector_targets_convertible_p (to, from);
   12003              : 
   12004      1772980 :       if (TREE_CODE (to) == ARRAY_TYPE
   12005              :           /* Ignore cv-qualification, but if we see e.g. int[3] and int[4],
   12006              :              we must fail.  */
   12007      1772980 :           && !comp_array_types (to, from, cb, /*strict=*/false))
   12008              :         return false;
   12009              : 
   12010              :       /* CWG 330 says we need to look through arrays.  */
   12011      1771193 :       if (!TYPE_PTR_P (to) && TREE_CODE (to) != ARRAY_TYPE)
   12012       719078 :         return (is_opaque_pointer
   12013       719078 :                 || same_type_ignoring_top_level_qualifiers_p (to, from));
   12014              :     }
   12015              : }
   12016              : 
   12017              : /* Returns the type qualifiers for this type, including the qualifiers on the
   12018              :    elements for an array type.  */
   12019              : 
   12020              : int
   12021  60917326938 : cp_type_quals (const_tree type)
   12022              : {
   12023  60917326938 :   int quals;
   12024              :   /* This CONST_CAST is okay because strip_array_types returns its
   12025              :      argument unmodified and we assign it to a const_tree.  */
   12026  60917326938 :   type = strip_array_types (const_cast<tree> (type));
   12027  60917326938 :   if (type == error_mark_node
   12028              :       /* Quals on a FUNCTION_TYPE are memfn quals.  */
   12029  60880852623 :       || TREE_CODE (type) == FUNCTION_TYPE)
   12030              :     return TYPE_UNQUALIFIED;
   12031  60812559002 :   quals = TYPE_QUALS (type);
   12032              :   /* METHOD and REFERENCE_TYPEs should never have quals.  */
   12033  60812559002 :   gcc_assert ((TREE_CODE (type) != METHOD_TYPE
   12034              :                && !TYPE_REF_P (type))
   12035              :               || ((quals & (TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE))
   12036              :                   == TYPE_UNQUALIFIED));
   12037              :   return quals;
   12038              : }
   12039              : 
   12040              : /* Returns the function-ref-qualifier for TYPE */
   12041              : 
   12042              : cp_ref_qualifier
   12043   3354356791 : type_memfn_rqual (const_tree type)
   12044              : {
   12045   3354356791 :   gcc_assert (FUNC_OR_METHOD_TYPE_P (type));
   12046              : 
   12047   3354356791 :   if (!FUNCTION_REF_QUALIFIED (type))
   12048              :     return REF_QUAL_NONE;
   12049     30927581 :   else if (FUNCTION_RVALUE_QUALIFIED (type))
   12050              :     return REF_QUAL_RVALUE;
   12051              :   else
   12052     15371131 :     return REF_QUAL_LVALUE;
   12053              : }
   12054              : 
   12055              : /* Returns the function-cv-quals for TYPE, which must be a FUNCTION_TYPE or
   12056              :    METHOD_TYPE.  */
   12057              : 
   12058              : int
   12059   1076750168 : type_memfn_quals (const_tree type)
   12060              : {
   12061   1076750168 :   if (TREE_CODE (type) == FUNCTION_TYPE)
   12062    107988875 :     return TYPE_QUALS (type);
   12063    968761293 :   else if (TREE_CODE (type) == METHOD_TYPE)
   12064    968761293 :     return cp_type_quals (class_of_this_parm (type));
   12065              :   else
   12066            0 :     gcc_unreachable ();
   12067              : }
   12068              : 
   12069              : /* Returns the FUNCTION_TYPE TYPE with its function-cv-quals changed to
   12070              :    MEMFN_QUALS and its ref-qualifier to RQUAL. */
   12071              : 
   12072              : tree
   12073     72008690 : apply_memfn_quals (tree type, cp_cv_quals memfn_quals, cp_ref_qualifier rqual)
   12074              : {
   12075              :   /* Could handle METHOD_TYPE here if necessary.  */
   12076     72008690 :   gcc_assert (TREE_CODE (type) == FUNCTION_TYPE);
   12077     72008690 :   if (TYPE_QUALS (type) == memfn_quals
   12078     72008690 :       && type_memfn_rqual (type) == rqual)
   12079              :     return type;
   12080              : 
   12081              :   /* This should really have a different TYPE_MAIN_VARIANT, but that gets
   12082              :      complex.  */
   12083       580275 :   tree result = build_qualified_type (type, memfn_quals);
   12084       580275 :   return build_ref_qualified_type (result, rqual);
   12085              : }
   12086              : 
   12087              : /* Returns nonzero if TYPE is const or volatile.  */
   12088              : 
   12089              : bool
   12090   1191590273 : cv_qualified_p (const_tree type)
   12091              : {
   12092   1191590273 :   int quals = cp_type_quals (type);
   12093   1191590273 :   return (quals & (TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE)) != 0;
   12094              : }
   12095              : 
   12096              : /* Returns nonzero if the TYPE contains a mutable member.  */
   12097              : 
   12098              : bool
   12099    920688287 : cp_has_mutable_p (const_tree type)
   12100              : {
   12101              :   /* This CONST_CAST is okay because strip_array_types returns its
   12102              :      argument unmodified and we assign it to a const_tree.  */
   12103    920688287 :   type = strip_array_types (const_cast<tree> (type));
   12104              : 
   12105    920688287 :   return CLASS_TYPE_P (type) && CLASSTYPE_HAS_MUTABLE (type);
   12106              : }
   12107              : 
   12108              : /* Set TREE_READONLY and TREE_VOLATILE on DECL as indicated by the
   12109              :    TYPE_QUALS.  For a VAR_DECL, this may be an optimistic
   12110              :    approximation.  In particular, consider:
   12111              : 
   12112              :      int f();
   12113              :      struct S { int i; };
   12114              :      const S s = { f(); }
   12115              : 
   12116              :    Here, we will make "s" as TREE_READONLY (because it is declared
   12117              :    "const") -- only to reverse ourselves upon seeing that the
   12118              :    initializer is non-constant.  */
   12119              : 
   12120              : void
   12121    993453523 : cp_apply_type_quals_to_decl (int type_quals, tree decl)
   12122              : {
   12123    993453523 :   tree type = TREE_TYPE (decl);
   12124              : 
   12125    993453523 :   if (type == error_mark_node)
   12126              :     return;
   12127              : 
   12128    993452862 :   if (TREE_CODE (decl) == TYPE_DECL)
   12129              :     return;
   12130              : 
   12131    876072418 :   gcc_assert (!(TREE_CODE (type) == FUNCTION_TYPE
   12132              :                 && type_quals != TYPE_UNQUALIFIED));
   12133              : 
   12134              :   /* Avoid setting TREE_READONLY incorrectly.  */
   12135              :   /* We used to check TYPE_NEEDS_CONSTRUCTING here, but now a constexpr
   12136              :      constructor can produce constant init, so rely on cp_finish_decl to
   12137              :      clear TREE_READONLY if the variable has non-constant init.  */
   12138              : 
   12139              :   /* If the type has (or might have) a mutable component, that component
   12140              :      might be modified.  */
   12141    876072418 :   if (TYPE_HAS_MUTABLE_P (type) || !COMPLETE_TYPE_P (type))
   12142     80340563 :     type_quals &= ~TYPE_QUAL_CONST;
   12143              : 
   12144    876072418 :   c_apply_type_quals_to_decl (type_quals, decl);
   12145              : }
   12146              : 
   12147              : /* Subroutine of casts_away_constness.  Make T1 and T2 point at
   12148              :    exemplar types such that casting T1 to T2 is casting away constness
   12149              :    if and only if there is no implicit conversion from T1 to T2.  */
   12150              : 
   12151              : static void
   12152      1235325 : casts_away_constness_r (tree *t1, tree *t2, tsubst_flags_t complain)
   12153              : {
   12154      1235325 :   int quals1;
   12155      1235325 :   int quals2;
   12156              : 
   12157              :   /* [expr.const.cast]
   12158              : 
   12159              :      For multi-level pointer to members and multi-level mixed pointers
   12160              :      and pointers to members (conv.qual), the "member" aspect of a
   12161              :      pointer to member level is ignored when determining if a const
   12162              :      cv-qualifier has been cast away.  */
   12163              :   /* [expr.const.cast]
   12164              : 
   12165              :      For  two  pointer types:
   12166              : 
   12167              :             X1 is T1cv1,1 * ... cv1,N *   where T1 is not a pointer type
   12168              :             X2 is T2cv2,1 * ... cv2,M *   where T2 is not a pointer type
   12169              :             K is min(N,M)
   12170              : 
   12171              :      casting from X1 to X2 casts away constness if, for a non-pointer
   12172              :      type T there does not exist an implicit conversion (clause
   12173              :      _conv_) from:
   12174              : 
   12175              :             Tcv1,(N-K+1) * cv1,(N-K+2) * ... cv1,N *
   12176              : 
   12177              :      to
   12178              : 
   12179              :             Tcv2,(M-K+1) * cv2,(M-K+2) * ... cv2,M *.  */
   12180      1235325 :   if ((!TYPE_PTR_P (*t1) && !TYPE_PTRDATAMEM_P (*t1))
   12181       618013 :       || (!TYPE_PTR_P (*t2) && !TYPE_PTRDATAMEM_P (*t2)))
   12182              :     {
   12183       617490 :       *t1 = cp_build_qualified_type (void_type_node,
   12184              :                                      cp_type_quals (*t1));
   12185       617490 :       *t2 = cp_build_qualified_type (void_type_node,
   12186              :                                      cp_type_quals (*t2));
   12187       617490 :       return;
   12188              :     }
   12189              : 
   12190       617835 :   quals1 = cp_type_quals (*t1);
   12191       617835 :   quals2 = cp_type_quals (*t2);
   12192              : 
   12193       617835 :   if (TYPE_PTRDATAMEM_P (*t1))
   12194            0 :     *t1 = TYPE_PTRMEM_POINTED_TO_TYPE (*t1);
   12195              :   else
   12196       617835 :     *t1 = TREE_TYPE (*t1);
   12197       617835 :   if (TYPE_PTRDATAMEM_P (*t2))
   12198            0 :     *t2 = TYPE_PTRMEM_POINTED_TO_TYPE (*t2);
   12199              :   else
   12200       617835 :     *t2 = TREE_TYPE (*t2);
   12201              : 
   12202       617835 :   casts_away_constness_r (t1, t2, complain);
   12203       617835 :   *t1 = build_pointer_type (*t1);
   12204       617835 :   *t2 = build_pointer_type (*t2);
   12205       617835 :   *t1 = cp_build_qualified_type (*t1, quals1);
   12206       617835 :   *t2 = cp_build_qualified_type (*t2, quals2);
   12207              : }
   12208              : 
   12209              : /* Returns nonzero if casting from TYPE1 to TYPE2 casts away
   12210              :    constness.
   12211              : 
   12212              :    ??? This function returns non-zero if casting away qualifiers not
   12213              :    just const.  We would like to return to the caller exactly which
   12214              :    qualifiers are casted away to give more accurate diagnostics.
   12215              : */
   12216              : 
   12217              : static bool
   12218       617562 : casts_away_constness (tree t1, tree t2, tsubst_flags_t complain)
   12219              : {
   12220       617562 :   if (TYPE_REF_P (t2))
   12221              :     {
   12222              :       /* [expr.const.cast]
   12223              : 
   12224              :          Casting from an lvalue of type T1 to an lvalue of type T2
   12225              :          using a reference cast casts away constness if a cast from an
   12226              :          rvalue of type "pointer to T1" to the type "pointer to T2"
   12227              :          casts away constness.  */
   12228            0 :       t1 = (TYPE_REF_P (t1) ? TREE_TYPE (t1) : t1);
   12229            0 :       return casts_away_constness (build_pointer_type (t1),
   12230            0 :                                    build_pointer_type (TREE_TYPE (t2)),
   12231            0 :                                    complain);
   12232              :     }
   12233              : 
   12234       617562 :   if (TYPE_PTRDATAMEM_P (t1) && TYPE_PTRDATAMEM_P (t2))
   12235              :     /* [expr.const.cast]
   12236              : 
   12237              :        Casting from an rvalue of type "pointer to data member of X
   12238              :        of type T1" to the type "pointer to data member of Y of type
   12239              :        T2" casts away constness if a cast from an rvalue of type
   12240              :        "pointer to T1" to the type "pointer to T2" casts away
   12241              :        constness.  */
   12242           48 :     return casts_away_constness
   12243           48 :       (build_pointer_type (TYPE_PTRMEM_POINTED_TO_TYPE (t1)),
   12244           48 :        build_pointer_type (TYPE_PTRMEM_POINTED_TO_TYPE (t2)),
   12245           48 :        complain);
   12246              : 
   12247              :   /* Casting away constness is only something that makes sense for
   12248              :      pointer or reference types.  */
   12249       617514 :   if (!TYPE_PTR_P (t1) || !TYPE_PTR_P (t2))
   12250              :     return false;
   12251              : 
   12252              :   /* Top-level qualifiers don't matter.  */
   12253       617490 :   t1 = TYPE_MAIN_VARIANT (t1);
   12254       617490 :   t2 = TYPE_MAIN_VARIANT (t2);
   12255       617490 :   casts_away_constness_r (&t1, &t2, complain);
   12256       617490 :   if (!can_convert (t2, t1, complain))
   12257              :     return true;
   12258              : 
   12259              :   return false;
   12260              : }
   12261              : 
   12262              : /* If T is a REFERENCE_TYPE return the type to which T refers.
   12263              :    Otherwise, return T itself.  */
   12264              : 
   12265              : tree
   12266   4268240588 : non_reference (tree t)
   12267              : {
   12268   4268240588 :   if (t && TYPE_REF_P (t))
   12269    394672265 :     t = TREE_TYPE (t);
   12270   4268240588 :   return t;
   12271              : }
   12272              : 
   12273              : 
   12274              : /* Return nonzero if REF is an lvalue valid for this language;
   12275              :    otherwise, print an error message and return zero.  USE says
   12276              :    how the lvalue is being used and so selects the error message.  */
   12277              : 
   12278              : int
   12279     40971945 : lvalue_or_else (tree ref, enum lvalue_use use, tsubst_flags_t complain)
   12280              : {
   12281     40971945 :   cp_lvalue_kind kind = lvalue_kind (ref);
   12282              : 
   12283     40971945 :   if (kind == clk_none)
   12284              :     {
   12285          380 :       if (complain & tf_error)
   12286          122 :         lvalue_error (cp_expr_loc_or_input_loc (ref), use);
   12287          380 :       return 0;
   12288              :     }
   12289     40971565 :   else if (kind & (clk_rvalueref|clk_class))
   12290              :     {
   12291          143 :       if (!(complain & tf_error))
   12292              :         return 0;
   12293              :       /* Make this a permerror because we used to accept it.  */
   12294           18 :       permerror (cp_expr_loc_or_input_loc (ref),
   12295              :                  "using rvalue as lvalue");
   12296              :     }
   12297              :   return 1;
   12298              : }
   12299              : 
   12300              : /* Return true if a user-defined literal operator is a raw operator.  */
   12301              : 
   12302              : bool
   12303       112462 : check_raw_literal_operator (const_tree decl)
   12304              : {
   12305       112462 :   tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl));
   12306       112462 :   tree argtype;
   12307       112462 :   int arity;
   12308       112462 :   bool maybe_raw_p = false;
   12309              : 
   12310              :   /* Count the number and type of arguments and check for ellipsis.  */
   12311       112462 :   for (argtype = argtypes, arity = 0;
   12312       168710 :        argtype && argtype != void_list_node;
   12313        56248 :        ++arity, argtype = TREE_CHAIN (argtype))
   12314              :     {
   12315        56248 :       tree t = TREE_VALUE (argtype);
   12316              : 
   12317        56248 :       if (same_type_p (t, const_string_type_node))
   12318            9 :         maybe_raw_p = true;
   12319              :     }
   12320       112462 :   if (!argtype)
   12321              :     return false; /* Found ellipsis.  */
   12322              : 
   12323       112462 :   if (!maybe_raw_p || arity != 1)
   12324       112456 :     return false;
   12325              : 
   12326              :   return true;
   12327              : }
   12328              : 
   12329              : 
   12330              : /* Return true if a user-defined literal operator has one of the allowed
   12331              :    argument types.  */
   12332              : 
   12333              : bool
   12334       303471 : check_literal_operator_args (const_tree decl,
   12335              :                              bool *long_long_unsigned_p, bool *long_double_p)
   12336              : {
   12337       303471 :   tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl));
   12338              : 
   12339       303471 :   *long_long_unsigned_p = false;
   12340       303471 :   *long_double_p = false;
   12341       303471 :   if (processing_template_decl || processing_specialization)
   12342        56364 :     return argtypes == void_list_node;
   12343              :   else
   12344              :     {
   12345              :       tree argtype;
   12346              :       int arity;
   12347              :       int max_arity = 2;
   12348              : 
   12349              :       /* Count the number and type of arguments and check for ellipsis.  */
   12350       246998 :       for (argtype = argtypes, arity = 0;
   12351       494105 :            argtype && argtype != void_list_node;
   12352       246998 :            argtype = TREE_CHAIN (argtype))
   12353              :         {
   12354       247113 :           tree t = TREE_VALUE (argtype);
   12355       247113 :           ++arity;
   12356              : 
   12357       247113 :           if (TYPE_PTR_P (t))
   12358              :             {
   12359       117794 :               bool maybe_raw_p = false;
   12360       117794 :               t = TREE_TYPE (t);
   12361       117794 :               if (cp_type_quals (t) != TYPE_QUAL_CONST)
   12362              :                 return false;
   12363       117791 :               t = TYPE_MAIN_VARIANT (t);
   12364       117791 :               if ((maybe_raw_p = same_type_p (t, char_type_node))
   12365        94059 :                   || same_type_p (t, wchar_type_node)
   12366        70494 :                   || same_type_p (t, char8_type_node)
   12367        47142 :                   || same_type_p (t, char16_type_node)
   12368       141362 :                   || same_type_p (t, char32_type_node))
   12369              :                 {
   12370       117788 :                   argtype = TREE_CHAIN (argtype);
   12371       117788 :                   if (!argtype)
   12372              :                     return false;
   12373       117788 :                   t = TREE_VALUE (argtype);
   12374       117788 :                   if (maybe_raw_p && argtype == void_list_node)
   12375              :                     return true;
   12376       117700 :                   else if (same_type_p (t, size_type_node))
   12377              :                     {
   12378       117694 :                       ++arity;
   12379       117694 :                       continue;
   12380              :                     }
   12381              :                   else
   12382              :                     return false;
   12383              :                 }
   12384              :             }
   12385       129319 :           else if (same_type_p (t, long_long_unsigned_type_node))
   12386              :             {
   12387        45530 :               max_arity = 1;
   12388        45530 :               *long_long_unsigned_p = true;
   12389              :             }
   12390        83789 :           else if (same_type_p (t, long_double_type_node))
   12391              :             {
   12392        83689 :               max_arity = 1;
   12393        83689 :               *long_double_p = true;
   12394              :             }
   12395          100 :           else if (same_type_p (t, char_type_node))
   12396              :             max_arity = 1;
   12397           56 :           else if (same_type_p (t, wchar_type_node))
   12398              :             max_arity = 1;
   12399           45 :           else if (same_type_p (t, char8_type_node))
   12400              :             max_arity = 1;
   12401           40 :           else if (same_type_p (t, char16_type_node))
   12402              :             max_arity = 1;
   12403           29 :           else if (same_type_p (t, char32_type_node))
   12404              :             max_arity = 1;
   12405              :           else
   12406              :             return false;
   12407              :         }
   12408       246992 :       if (!argtype)
   12409              :         return false; /* Found ellipsis.  */
   12410              : 
   12411       246989 :       if (arity != max_arity)
   12412              :         return false;
   12413              : 
   12414              :       return true;
   12415              :     }
   12416              : }
   12417              : 
   12418              : /* Always returns false since unlike C90, C++ has no concept of implicit
   12419              :    function declarations.  */
   12420              : 
   12421              : bool
   12422          395 : c_decl_implicit (const_tree)
   12423              : {
   12424          395 :   return false;
   12425              : }
        

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.