LCOV - code coverage report
Current view: top level - gcc/cp - typeck.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 92.3 % 5549 5119
Test Date: 2026-05-30 15:37:04 Functions: 97.7 % 177 173
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    137940840 : require_complete_type (tree value,
      75              :                        tsubst_flags_t complain /* = tf_warning_or_error */)
      76              : {
      77    137940840 :   tree type;
      78              : 
      79    137940840 :   if (processing_template_decl || value == error_mark_node)
      80              :     return value;
      81              : 
      82    127682017 :   if (TREE_CODE (value) == OVERLOAD)
      83            0 :     type = unknown_type_node;
      84              :   else
      85    127682017 :     type = TREE_TYPE (value);
      86              : 
      87    127682017 :   if (type == error_mark_node)
      88              :     return error_mark_node;
      89              : 
      90              :   /* First, detect a valid value with a complete type.  */
      91    127682005 :   if (COMPLETE_TYPE_P (type))
      92              :     return value;
      93              : 
      94       142235 :   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  14987470638 : complete_type (tree type)
     107              : {
     108  14987470638 :   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  14987470638 :   if (type == error_mark_node || COMPLETE_TYPE_P (type))
     114              :     ;
     115   4913342710 :   else if (TREE_CODE (type) == ARRAY_TYPE)
     116              :     {
     117       775172 :       tree t = complete_type (TREE_TYPE (type));
     118       775172 :       unsigned int needs_constructing, has_nontrivial_dtor;
     119       775172 :       if (COMPLETE_TYPE_P (t) && !dependent_type_p (type))
     120       756919 :         layout_type (type);
     121       775172 :       needs_constructing
     122       775172 :         = TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (t));
     123       775172 :       has_nontrivial_dtor
     124       775172 :         = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TYPE_MAIN_VARIANT (t));
     125      2554957 :       for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
     126              :         {
     127      1779785 :           TYPE_NEEDS_CONSTRUCTING (t) = needs_constructing;
     128      1779785 :           TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = has_nontrivial_dtor;
     129              :         }
     130              :     }
     131   4912567538 :   else if (CLASS_TYPE_P (type))
     132              :     {
     133   4821625890 :       if (modules_p ())
     134              :         /* TYPE could be a class member we've not loaded the definition of.  */
     135     18413264 :         lazy_load_pendings (TYPE_NAME (TYPE_MAIN_VARIANT (type)));
     136              : 
     137   4821625890 :       if (CLASSTYPE_TEMPLATE_INSTANTIATION (type))
     138    919615491 :         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   1597885361 : complete_type_or_maybe_complain (tree type, tree value, tsubst_flags_t complain)
     150              : {
     151   1597885361 :   type = complete_type (type);
     152   1597885358 :   if (type == error_mark_node)
     153              :     /* We already issued an error.  */
     154              :     return NULL_TREE;
     155   1597885151 :   else if (!COMPLETE_TYPE_P (type))
     156              :     {
     157         3811 :       if (complain & tf_error)
     158          472 :         cxx_incomplete_type_diagnostic (value, type, diagnostics::kind::error);
     159         3811 :       note_failed_type_completion (type, complain);
     160         3811 :       return NULL_TREE;
     161              :     }
     162              :   else
     163              :     return type;
     164              : }
     165              : 
     166              : tree
     167    163816578 : complete_type_or_else (tree type, tree value)
     168              : {
     169    163816578 :   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      4157803 : commonparms (tree p1, tree p2)
     182              : {
     183      4157803 :   tree oldargs = p1, newargs, n;
     184      4157803 :   int i, len;
     185      4157803 :   int any_change = 0;
     186              : 
     187      4157803 :   len = list_length (p1);
     188      4157803 :   newargs = tree_last (p1);
     189              : 
     190      4157803 :   if (newargs == void_list_node)
     191              :     i = 1;
     192              :   else
     193              :     {
     194        39105 :       i = 0;
     195        39105 :       newargs = 0;
     196              :     }
     197              : 
     198     13762776 :   for (; i < len; i++)
     199      9604973 :     newargs = tree_cons (NULL_TREE, NULL_TREE, newargs);
     200              : 
     201              :   n = newargs;
     202              : 
     203     17881474 :   for (i = 0; p1;
     204     13723671 :        p1 = TREE_CHAIN (p1), p2 = TREE_CHAIN (p2), n = TREE_CHAIN (n), i++)
     205              :     {
     206     13723874 :       if (TREE_PURPOSE (p1) && !TREE_PURPOSE (p2))
     207              :         {
     208          170 :           TREE_PURPOSE (n) = TREE_PURPOSE (p1);
     209          170 :           any_change = 1;
     210              :         }
     211     13723501 :       else if (! TREE_PURPOSE (p1))
     212              :         {
     213     13723468 :           if (TREE_PURPOSE (p2))
     214              :             {
     215       417409 :               TREE_PURPOSE (n) = TREE_PURPOSE (p2);
     216       417409 :               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     13723671 :       if (TREE_VALUE (p1) != TREE_VALUE (p2))
     226              :         {
     227      3840364 :           any_change = 1;
     228      3840364 :           TREE_VALUE (n) = merge_types (TREE_VALUE (p1), TREE_VALUE (p2));
     229              :         }
     230              :       else
     231      9883307 :         TREE_VALUE (n) = TREE_VALUE (p1);
     232              :     }
     233      4157803 :   if (! any_change)
     234      1401382 :     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     32554366 : original_type (tree t)
     243              : {
     244     32554366 :   int quals = cp_type_quals (t);
     245     32554366 :   while (t != error_mark_node
     246     33684062 :          && TYPE_NAME (t) != NULL_TREE)
     247              :     {
     248     11369988 :       tree x = TYPE_NAME (t);
     249     11369988 :       if (TREE_CODE (x) != TYPE_DECL)
     250              :         break;
     251     11369988 :       x = DECL_ORIGINAL_TYPE (x);
     252     11369988 :       if (x == NULL_TREE)
     253              :         break;
     254              :       t = x;
     255              :     }
     256     32554366 :   return cp_build_qualified_type (t, quals);
     257              : }
     258              : 
     259              : /* Merge the attributes of type OTHER_TYPE into the attributes of type TYPE
     260              :    and return a variant of TYPE with the merged attributes.  */
     261              : 
     262              : static tree
     263        59984 : merge_type_attributes_from (tree type, tree other_type)
     264              : {
     265        59984 :   tree attrs = targetm.merge_type_attributes (type, other_type);
     266        59984 :   attrs = restrict_type_identity_attributes_to (attrs, TYPE_ATTRIBUTES (type));
     267        59984 :   return cp_build_type_attribute_variant (type, attrs);
     268              : }
     269              : 
     270              : /* Compare floating point conversion ranks and subranks of T1 and T2
     271              :    types.  If T1 and T2 have unordered conversion ranks, return 3.
     272              :    If T1 has greater conversion rank than T2, return 2.
     273              :    If T2 has greater conversion rank than T1, return -2.
     274              :    If T1 has equal conversion rank as T2, return -1, 0 or 1 depending
     275              :    on if T1 has smaller, equal or greater conversion subrank than
     276              :    T2.  */
     277              : 
     278              : int
     279      5340258 : cp_compare_floating_point_conversion_ranks (tree t1, tree t2)
     280              : {
     281      5340258 :   tree mv1 = TYPE_MAIN_VARIANT (t1);
     282      5340258 :   tree mv2 = TYPE_MAIN_VARIANT (t2);
     283      5340258 :   int extended1 = 0;
     284      5340258 :   int extended2 = 0;
     285              : 
     286      5340258 :   if (mv1 == mv2)
     287              :     return 0;
     288              : 
     289     42710744 :   for (int i = 0; i < NUM_FLOATN_NX_TYPES; ++i)
     290              :     {
     291     37371901 :       if (mv1 == FLOATN_NX_TYPE_NODE (i))
     292      2412111 :         extended1 = i + 1;
     293     37371901 :       if (mv2 == FLOATN_NX_TYPE_NODE (i))
     294      2004790 :         extended2 = i + 1;
     295              :     }
     296      5338843 :   if (mv1 == bfloat16_type_node)
     297       555986 :     extended1 = true;
     298      5338843 :   if (mv2 == bfloat16_type_node)
     299       444023 :     extended2 = true;
     300      5338843 :   if (extended2 && !extended1)
     301              :     {
     302      2339398 :       int ret = cp_compare_floating_point_conversion_ranks (t2, t1);
     303      2339398 :       return ret == 3 ? 3 : -ret;
     304              :     }
     305              : 
     306      2999445 :   const struct real_format *fmt1 = REAL_MODE_FORMAT (TYPE_MODE (t1));
     307      2999445 :   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      2999445 :   gcc_assert (fmt1->b == 2);
     313      2999445 :   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      2999412 :   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     23995296 :   int p1 = (MODE_COMPOSITE_P (TYPE_MODE (t1))
     338      5998824 :             ? fmt1->emax - fmt1->emin + fmt1->p - 1 : fmt1->p);
     339     23995296 :   int p2 = (MODE_COMPOSITE_P (TYPE_MODE (t2))
     340      5998824 :             ? 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      2999412 :   if ((p1 > p2 && fmt1->emax >= fmt2->emax)
     345      2340157 :        || (p1 == p2 && fmt1->emax > fmt2->emax))
     346              :     return 2;
     347      2340157 :   if ((p1 < p2 && fmt1->emax <= fmt2->emax)
     348       804990 :        || (p1 == p2 && fmt1->emax < fmt2->emax))
     349              :     return -2;
     350       804990 :   if ((p1 > p2 && fmt1->emax < fmt2->emax)
     351       800276 :        || (p1 < p2 && fmt1->emax > fmt2->emax))
     352              :     return 3;
     353       795562 :   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       795562 :   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      3182232 :   for (p = &float_type_node; p <= &long_double_type_node; ++p)
     398              :     {
     399      2386674 :       const struct real_format *fmt3 = REAL_MODE_FORMAT (TYPE_MODE (*p));
     400      2386674 :       gcc_assert (fmt3->b == 2);
     401     19093392 :       int p3 = (MODE_COMPOSITE_P (TYPE_MODE (*p))
     402      4773348 :                 ? fmt3->emax - fmt3->emin + fmt3->p - 1 : fmt3->p);
     403      2386674 :       if (p1 == p3 && fmt1->emax == fmt3->emax)
     404       697314 :         ++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       795558 :   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    109570056 : cp_common_type (tree t1, tree t2)
     436              : {
     437    109570056 :   enum tree_code code1 = TREE_CODE (t1);
     438    109570056 :   enum tree_code code2 = TREE_CODE (t2);
     439    109570056 :   tree attributes;
     440    109570056 :   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    109570056 :   attributes = (*targetm.merge_type_attributes) (t1, t2);
     447              : 
     448    109570056 :   if (SCOPED_ENUM_P (t1) || SCOPED_ENUM_P (t2))
     449              :     {
     450      1989187 :       if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
     451      1989187 :         return build_type_attribute_variant (t1, attributes);
     452              :       else
     453              :         return NULL_TREE;
     454              :     }
     455              : 
     456              :   /* FIXME: Attributes.  */
     457    107580869 :   gcc_assert (ARITHMETIC_TYPE_P (t1)
     458              :               || VECTOR_TYPE_P (t1)
     459              :               || UNSCOPED_ENUM_P (t1));
     460    107580869 :   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    107580869 :   if (code1 == COMPLEX_TYPE || code2 == COMPLEX_TYPE)
     468              :     {
     469       217486 :       tree subtype1 = code1 == COMPLEX_TYPE ? TREE_TYPE (t1) : t1;
     470       217486 :       tree subtype2 = code2 == COMPLEX_TYPE ? TREE_TYPE (t2) : t2;
     471       217486 :       tree subtype
     472       217486 :         = type_after_usual_arithmetic_conversions (subtype1, subtype2);
     473              : 
     474       217486 :       if (subtype == error_mark_node)
     475              :         return subtype;
     476       217486 :       if (code1 == COMPLEX_TYPE && TREE_TYPE (t1) == subtype)
     477       184078 :         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    107363383 :   if (code1 == VECTOR_TYPE)
     486              :     {
     487              :       /* When we get here we should have two vectors of the same size.
     488              :          Just prefer the unsigned one if present.  */
     489        59984 :       if (TYPE_UNSIGNED (t1))
     490        12931 :         return merge_type_attributes_from (t1, t2);
     491              :       else
     492        47053 :         return merge_type_attributes_from (t2, t1);
     493              :     }
     494              : 
     495              :   /* If only one is real, use it as the result.  */
     496    107303399 :   if (code1 == REAL_TYPE && code2 != REAL_TYPE)
     497      1147350 :     return build_type_attribute_variant (t1, attributes);
     498    106156049 :   if (code2 == REAL_TYPE && code1 != REAL_TYPE)
     499      1007731 :     return build_type_attribute_variant (t2, attributes);
     500              : 
     501    105148318 :   if (code1 == REAL_TYPE
     502    105148318 :       && (extended_float_type_p (t1) || extended_float_type_p (t2)))
     503              :     {
     504       103732 :       tree mv1 = TYPE_MAIN_VARIANT (t1);
     505       103732 :       tree mv2 = TYPE_MAIN_VARIANT (t2);
     506       103732 :       if (mv1 == mv2)
     507       101476 :         return build_type_attribute_variant (t1, attributes);
     508              : 
     509         2256 :       int cmpret = cp_compare_floating_point_conversion_ranks (mv1, mv2);
     510         2256 :       if (cmpret == 3)
     511            6 :         return error_mark_node;
     512         2250 :       else if (cmpret >= 0)
     513         1974 :         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    105044586 :   if (TYPE_PRECISION (t1) > TYPE_PRECISION (t2))
     520     16410603 :     return build_type_attribute_variant (t1, attributes);
     521     88633983 :   else if (TYPE_PRECISION (t2) > TYPE_PRECISION (t1))
     522      1881140 :     return build_type_attribute_variant (t2, attributes);
     523              : 
     524              :   /* The types are the same; no need to do anything fancy.  */
     525     86752843 :   if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
     526     79597056 :     return build_type_attribute_variant (t1, attributes);
     527              : 
     528      7155787 :   if (code1 != REAL_TYPE)
     529              :     {
     530              :       /* If one is unsigned long long, then convert the other to unsigned
     531              :          long long.  */
     532      7155784 :       if (same_type_p (TYPE_MAIN_VARIANT (t1), long_long_unsigned_type_node)
     533      7155784 :           || same_type_p (TYPE_MAIN_VARIANT (t2), long_long_unsigned_type_node))
     534       152019 :         return build_type_attribute_variant (long_long_unsigned_type_node,
     535       152019 :                                              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      7003765 :       if (same_type_p (TYPE_MAIN_VARIANT (t1), long_long_integer_type_node)
     547      7003765 :           || 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      7003096 :       if (same_type_p (TYPE_MAIN_VARIANT (t1), long_unsigned_type_node)
     557      7003096 :           || same_type_p (TYPE_MAIN_VARIANT (t2), long_unsigned_type_node))
     558       892134 :         return build_type_attribute_variant (long_unsigned_type_node,
     559       892134 :                                              attributes);
     560      6110962 :       if (same_type_p (TYPE_MAIN_VARIANT (t1), long_integer_type_node)
     561      6110962 :           || same_type_p (TYPE_MAIN_VARIANT (t2), long_integer_type_node))
     562              :         {
     563        75719 :           tree t = ((TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
     564        75719 :                     ? long_unsigned_type_node : long_integer_type_node);
     565        38334 :           return build_type_attribute_variant (t, attributes);
     566              :         }
     567              : 
     568              :       /* For __intN types, either the type is __int128 (and is lower
     569              :          priority than the types checked above, but higher than other
     570              :          128-bit types) or it's known to not be the same size as other
     571              :          types (enforced in toplev.cc).  Prefer the unsigned type. */
     572     12145224 :       for (i = 0; i < NUM_INT_N_ENTS; i ++)
     573              :         {
     574      6072628 :           if (int_n_enabled_p [i]
     575      6072628 :               && (same_type_p (TYPE_MAIN_VARIANT (t1), int_n_trees[i].signed_type)
     576      5984125 :                   || same_type_p (TYPE_MAIN_VARIANT (t2), int_n_trees[i].signed_type)
     577      5984121 :                   || same_type_p (TYPE_MAIN_VARIANT (t1), int_n_trees[i].unsigned_type)
     578      5984121 :                   || 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      6072596 :       if (TYPE_UNSIGNED (t1))
     589      4902203 :         return build_type_attribute_variant (t1, attributes);
     590              :       else
     591      1170393 :         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      1161633 : type_after_usual_arithmetic_conversions (tree t1, tree t2)
     623              : {
     624      1161633 :   gcc_assert (ARITHMETIC_TYPE_P (t1)
     625              :               || VECTOR_TYPE_P (t1)
     626              :               || UNSCOPED_ENUM_P (t1));
     627      1161633 :   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      1161633 :   if (INTEGRAL_OR_ENUMERATION_TYPE_P (t1)
     633       943736 :       && INTEGRAL_OR_ENUMERATION_TYPE_P (t2))
     634              :     {
     635       943473 :       t1 = type_promotes_to (t1);
     636       943473 :       t2 = type_promotes_to (t2);
     637              :     }
     638              : 
     639      1161633 :   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      5861868 : 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      5861868 :   tree pointee1;
     683      5861868 :   tree pointee2;
     684      5861868 :   tree result_type;
     685      5861868 :   tree attributes;
     686              : 
     687              :   /* Determine the types pointed to by T1 and T2.  */
     688      5861868 :   if (TYPE_PTR_P (t1))
     689              :     {
     690      5861330 :       pointee1 = TREE_TYPE (t1);
     691      5861330 :       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      5861868 :   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      5861791 :   const int q1 = cp_type_quals (pointee1);
     723      5861791 :   const int q2 = cp_type_quals (pointee2);
     724      5861791 :   const int quals = q1 | q2;
     725      5861791 :   result_type = cp_build_qualified_type (result_type,
     726      5861791 :                                          (quals | (*add_const
     727      5861791 :                                                    ? 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      5861791 :   if (quals != q1 || quals != q2)
     733       714533 :     *add_const = true;
     734              :   /* If the original types were pointers to members, so is the
     735              :      result.  */
     736      5861791 :   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      5861267 :     result_type = build_pointer_type (result_type);
     752              : 
     753              :   /* Merge the attributes.  */
     754      5861791 :   attributes = (*targetm.merge_type_attributes) (t1, t2);
     755      5861791 :   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      6320613 : 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      6320613 :   tree class1;
     773      6320613 :   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      6320613 :   if (null_ptr_cst_p (arg1))
     780              :     return t2;
     781      6320450 :   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      6299375 :   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      6299375 :   if (TYPE_PTR_P (t1) && VOID_TYPE_P (TREE_TYPE (t1)))
     799              :     {
     800       437435 :       tree attributes;
     801       437435 :       tree result_type;
     802              : 
     803       437435 :       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       437433 :       result_type
     833       437433 :         = cp_build_qualified_type (void_type_node,
     834       437433 :                                    (cp_type_quals (TREE_TYPE (t1))
     835       437433 :                                     | cp_type_quals (TREE_TYPE (t2))));
     836       437433 :       result_type = build_pointer_type (result_type);
     837              :       /* Merge the attributes.  */
     838       437433 :       attributes = (*targetm.merge_type_attributes) (t1, t2);
     839       437433 :       return build_type_attribute_variant (result_type, attributes);
     840              :     }
     841              : 
     842      5861940 :   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      5861940 :   if (fnptr_conv_p (t1, t2))
     853              :     return t1;
     854      5861905 :   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      5861315 :   if (TYPE_PTR_P (t1) && TYPE_PTR_P (t2)
     860      5861315 :       && CLASS_TYPE_P (TREE_TYPE (t1))
     861       925733 :       && CLASS_TYPE_P (TREE_TYPE (t2))
     862      6787604 :       && !same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (t1),
     863       925730 :                                                      TREE_TYPE (t2)))
     864              :     {
     865        29474 :       class1 = TREE_TYPE (t1);
     866        29474 :       class2 = TREE_TYPE (t2);
     867              : 
     868        29474 :       if (DERIVED_FROM_P (class1, class2))
     869         3140 :         t2 = (build_pointer_type
     870         1570 :               (cp_build_qualified_type (class1, cp_type_quals (class2))));
     871        27904 :       else if (DERIVED_FROM_P (class2, class1))
     872        55772 :         t1 = (build_pointer_type
     873        27886 :               (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      5831980 :   else if (TYPE_PTRMEM_P (t1)
     885      5832539 :            && !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      5861835 :   bool add_const = false;
     923      5861835 :   return composite_pointer_type_r (location, t1, t2, &add_const, operation,
     924      5861835 :                                    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     29720747 : merge_types (tree t1, tree t2)
     936              : {
     937     29720747 :   enum tree_code code1;
     938     29720747 :   enum tree_code code2;
     939     29720747 :   tree attributes;
     940              : 
     941              :   /* Save time if the two types are the same.  */
     942     29720747 :   if (t1 == t2)
     943              :     return t1;
     944     16277183 :   if (original_type (t1) == original_type (t2))
     945              :     return t1;
     946              : 
     947              :   /* If one type is nonsense, use the other.  */
     948     16157223 :   if (t1 == error_mark_node)
     949              :     return t2;
     950     16157223 :   if (t2 == error_mark_node)
     951              :     return t1;
     952              : 
     953              :   /* Handle merging an auto redeclaration with a previous deduced
     954              :      return type.  */
     955     16157223 :   if (is_auto (t1))
     956              :     return t2;
     957              : 
     958              :   /* Merge the attributes.  */
     959     16148094 :   attributes = (*targetm.merge_type_attributes) (t1, t2);
     960              : 
     961     16148094 :   if (TYPE_PTRMEMFUNC_P (t1))
     962           15 :     t1 = TYPE_PTRMEMFUNC_FN_TYPE (t1);
     963     16148094 :   if (TYPE_PTRMEMFUNC_P (t2))
     964           15 :     t2 = TYPE_PTRMEMFUNC_FN_TYPE (t2);
     965              : 
     966     16148094 :   code1 = TREE_CODE (t1);
     967     16148094 :   code2 = TREE_CODE (t2);
     968     16148094 :   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     16148094 :   switch (code1)
     984              :     {
     985      2750372 :     case POINTER_TYPE:
     986      2750372 :     case REFERENCE_TYPE:
     987              :       /* For two pointers, do this recursively on the target type.  */
     988      2750372 :       {
     989      2750372 :         tree target = merge_types (TREE_TYPE (t1), TREE_TYPE (t2));
     990      2750372 :         int quals = cp_type_quals (t1);
     991              : 
     992      2750372 :         if (code1 == POINTER_TYPE)
     993              :           {
     994       749295 :             t1 = build_pointer_type (target);
     995       749295 :             if (TREE_CODE (target) == METHOD_TYPE)
     996           15 :               t1 = build_ptrmemfunc_type (t1);
     997              :           }
     998              :         else
     999      2001077 :           t1 = cp_build_reference_type (target, TYPE_REF_IS_RVALUE (t1));
    1000      2750372 :         t1 = build_type_attribute_variant (t1, attributes);
    1001      2750372 :         t1 = cp_build_qualified_type (t1, quals);
    1002              : 
    1003      2750372 :         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        10318 :     case ARRAY_TYPE:
    1020        10318 :       {
    1021        10318 :         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        20636 :         if (elt == TREE_TYPE (t1) && TYPE_DOMAIN (t1))
    1024        10293 :           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      4302692 :     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      4302692 :       {
    1037      4302692 :         tree valtype = merge_types (TREE_TYPE (t1), TREE_TYPE (t2));
    1038      4302692 :         tree p1 = TYPE_ARG_TYPES (t1);
    1039      4302692 :         tree p2 = TYPE_ARG_TYPES (t2);
    1040      4302692 :         tree parms;
    1041              : 
    1042              :         /* Save space: see if the result is identical to one of the args.  */
    1043      4302692 :         if (valtype == TREE_TYPE (t1) && ! p2)
    1044            0 :           return cp_build_type_attribute_variant (t1, attributes);
    1045      4302692 :         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      8605384 :         if (p1 == NULL_TREE || TREE_VALUE (p1) == void_type_node)
    1050              :           parms = p2;
    1051      8315606 :         else if (p2 == NULL_TREE || TREE_VALUE (p2) == void_type_node)
    1052              :           parms = p1;
    1053              :         else
    1054      4157803 :           parms = commonparms (p1, p2);
    1055              : 
    1056      4302692 :         cp_cv_quals quals = type_memfn_quals (t1);
    1057      4302692 :         cp_ref_qualifier rqual = type_memfn_rqual (t1);
    1058      4302692 :         gcc_assert (quals == type_memfn_quals (t2));
    1059      4302692 :         gcc_assert (rqual == type_memfn_rqual (t2));
    1060              : 
    1061      4302692 :         tree rval = cp_build_function_type (valtype, parms);
    1062      4302692 :         rval = apply_memfn_quals (rval, quals);
    1063      4302692 :         tree raises = merge_exception_specifiers (TYPE_RAISES_EXCEPTIONS (t1),
    1064      4302692 :                                                   TYPE_RAISES_EXCEPTIONS (t2));
    1065      4302692 :         bool late_return_type_p = TYPE_HAS_LATE_RETURN_TYPE (t1);
    1066      4302692 :         t1 = build_cp_fntype_variant (rval, rqual, raises, late_return_type_p);
    1067      4302692 :         break;
    1068              :       }
    1069              : 
    1070      3913451 :     case METHOD_TYPE:
    1071      3913451 :       {
    1072              :         /* Get this value the long way, since TYPE_METHOD_BASETYPE
    1073              :            is just the main variant of this.  */
    1074      3913451 :         tree basetype = class_of_this_parm (t2);
    1075      3913451 :         tree raises = merge_exception_specifiers (TYPE_RAISES_EXCEPTIONS (t1),
    1076      3913451 :                                                   TYPE_RAISES_EXCEPTIONS (t2));
    1077      3913451 :         cp_ref_qualifier rqual = type_memfn_rqual (t1);
    1078      3913451 :         tree t3;
    1079      3913451 :         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      3913451 :         t1 = cp_build_function_type (TREE_TYPE (t1),
    1085      3913451 :                                      TREE_CHAIN (TYPE_ARG_TYPES (t1)));
    1086      3913451 :         t2 = cp_build_function_type (TREE_TYPE (t2),
    1087      3913451 :                                      TREE_CHAIN (TYPE_ARG_TYPES (t2)));
    1088      3913451 :         t3 = merge_types (t1, t2);
    1089      3913451 :         t3 = build_method_type_directly (basetype, TREE_TYPE (t3),
    1090      3913451 :                                          TYPE_ARG_TYPES (t3));
    1091      3913451 :         t1 = build_cp_fntype_variant (t3, rqual, raises, late_return_type_1_p);
    1092      3913451 :         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      5161294 :     default:;
    1102      5161294 :       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      8216161 :   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       621955 : common_type (tree t1, tree t2)
    1135              : {
    1136              :   /* If one type is nonsense, use the other  */
    1137       621955 :   if (t1 == error_mark_node)
    1138              :     return t2;
    1139       621955 :   if (t2 == error_mark_node)
    1140              :     return t1;
    1141              : 
    1142       621955 :   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      1447072 : common_pointer_type (tree t1, tree t2)
    1154              : {
    1155      1447072 :   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      1447072 :   return composite_pointer_type (input_location, t1, t2,
    1160              :                                  error_mark_node, error_mark_node,
    1161      1447072 :                                  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         1766 : comp_except_types (tree a, tree b, bool exact)
    1182              : {
    1183         1766 :   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   1612190466 : comp_except_specs (const_tree t1, const_tree t2, int exact)
    1218              : {
    1219   1612190466 :   const_tree probe;
    1220   1612190466 :   const_tree base;
    1221   1612190466 :   int  length = 0;
    1222              : 
    1223   1612190466 :   if (t1 == t2)
    1224              :     return true;
    1225              : 
    1226              :   /* First handle noexcept.  */
    1227    657153255 :   if (exact < ce_exact)
    1228              :     {
    1229      9264575 :       if (exact == ce_type
    1230     18486236 :           && (canonical_eh_spec (const_cast<tree> (t1))
    1231      9221661 :               == 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      9244917 :       if (t1 == noexcept_false_spec)
    1237          168 :         return t2 == NULL_TREE || exact == ce_derived;
    1238              :       /* Even a derived noexcept(false) is compatible with no
    1239              :          exception-specification.  */
    1240      9244749 :       if (t2 == noexcept_false_spec)
    1241          941 :         return t1 == NULL_TREE;
    1242              : 
    1243              :       /* Otherwise, if we aren't looking for an exact match, noexcept is
    1244              :          equivalent to throw().  */
    1245      9243808 :       if (t1 == noexcept_true_spec)
    1246       691599 :         t1 = empty_except_spec;
    1247      9243808 :       if (t2 == noexcept_true_spec)
    1248      8370858 :         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    628473314 :   if ((t1 && TREE_PURPOSE (t1))
    1255    688684808 :       || (t2 && TREE_PURPOSE (t2)))
    1256    645697522 :     return (t1 && t2
    1257    645697522 :             && (exact == ce_exact
    1258     80125002 :                 ? TREE_PURPOSE (t1) == TREE_PURPOSE (t2)
    1259       178392 :                 : cp_tree_equal (TREE_PURPOSE (t1), TREE_PURPOSE (t2))));
    1260              : 
    1261     11434966 :   if (t1 == NULL_TREE)                     /* T1 is ...  */
    1262      8604154 :     return t2 == NULL_TREE || exact == ce_derived;
    1263      2830812 :   if (!TREE_VALUE (t1))                    /* t1 is EMPTY */
    1264      2796922 :     return t2 != NULL_TREE && !TREE_VALUE (t2);
    1265        35218 :   if (t2 == NULL_TREE)                     /* T2 is ...  */
    1266              :     return false;
    1267         1644 :   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         2831 :   for (base = t1; t2 != NULL_TREE; t2 = TREE_CHAIN (t2))
    1275              :     {
    1276         2162 :       for (probe = base; probe != NULL_TREE; probe = TREE_CHAIN (probe))
    1277              :         {
    1278         1766 :           tree a = TREE_VALUE (probe);
    1279         1766 :           tree b = TREE_VALUE (t2);
    1280              : 
    1281         1766 :           if (comp_except_types (a, b, exact))
    1282              :             {
    1283         1263 :               if (probe == base && exact > ce_derived)
    1284         1228 :                 base = TREE_CHAIN (probe);
    1285         1263 :               length++;
    1286         1263 :               break;
    1287              :             }
    1288              :         }
    1289         1263 :       if (probe == NULL_TREE)
    1290              :         return false;
    1291              :     }
    1292         1172 :   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      1801372 : comp_array_types (const_tree t1, const_tree t2, compare_bounds_t cb,
    1303              :                   bool strict)
    1304              : {
    1305      1801372 :   tree d1;
    1306      1801372 :   tree d2;
    1307      1801372 :   tree max1, max2;
    1308              : 
    1309      1801372 :   if (t1 == t2)
    1310              :     return true;
    1311              : 
    1312              :   /* The type of the array elements must be the same.  */
    1313      1800886 :   if (strict
    1314      1800886 :       ? !same_type_p (TREE_TYPE (t1), TREE_TYPE (t2))
    1315         8594 :       : !similar_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
    1316              :     return false;
    1317              : 
    1318      1171508 :   d1 = TYPE_DOMAIN (t1);
    1319      1171508 :   d2 = TYPE_DOMAIN (t2);
    1320              : 
    1321      1171508 :   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       653063 :   if (!d1 && d2)
    1337         5146 :     return cb >= bounds_either;
    1338       647917 :   else if (d1 && !d2)
    1339         8045 :     return cb == bounds_either;
    1340              : 
    1341              :   /* Check that the dimensions are the same.  */
    1342              : 
    1343       639872 :   if (!cp_tree_equal (TYPE_MIN_VALUE (d1), TYPE_MIN_VALUE (d2)))
    1344              :     return false;
    1345       639851 :   max1 = TYPE_MAX_VALUE (d1);
    1346       639851 :   max2 = TYPE_MAX_VALUE (d2);
    1347              : 
    1348       639851 :   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   1820022337 : comp_template_parms_position (tree t1, tree t2)
    1361              : {
    1362   1820022337 :   tree index1, index2;
    1363   1820022337 :   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   1820022337 :   index1 = TEMPLATE_TYPE_PARM_INDEX (TYPE_MAIN_VARIANT (t1));
    1370   1820022337 :   index2 = TEMPLATE_TYPE_PARM_INDEX (TYPE_MAIN_VARIANT (t2));
    1371              : 
    1372              :   /* Then compare their relative position.  */
    1373   1820022337 :   if (TEMPLATE_PARM_IDX (index1) != TEMPLATE_PARM_IDX (index2)
    1374   1268419008 :       || TEMPLATE_PARM_LEVEL (index1) != TEMPLATE_PARM_LEVEL (index2)
    1375   2666646383 :       || (TEMPLATE_PARM_PARAMETER_PACK (index1)
    1376    846624046 :           != 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    758412540 :   if (cxx_dialect >= cxx14 && (is_auto (t1) || is_auto (t2)))
    1382    207274298 :     return TYPE_IDENTIFIER (t1) == TYPE_IDENTIFIER (t2);
    1383              : 
    1384              :   return true;
    1385              : }
    1386              : 
    1387              : /* Heuristic check if two parameter types can be considered ABI-equivalent.  */
    1388              : 
    1389              : static bool
    1390          512 : cxx_safe_arg_type_equiv_p (tree t1, tree t2)
    1391              : {
    1392          512 :   t1 = TYPE_MAIN_VARIANT (t1);
    1393          512 :   t2 = TYPE_MAIN_VARIANT (t2);
    1394              : 
    1395          512 :   if (TYPE_PTR_P (t1)
    1396          141 :       && TYPE_PTR_P (t2))
    1397              :     return true;
    1398              : 
    1399              :   /* Only the precision of the parameter matters.  This check should
    1400              :      make sure that the callee does not see undefined values in argument
    1401              :      registers.  */
    1402          377 :   if (INTEGRAL_TYPE_P (t1)
    1403           68 :       && INTEGRAL_TYPE_P (t2)
    1404          424 :       && TYPE_PRECISION (t1) == TYPE_PRECISION (t2))
    1405              :     return true;
    1406              : 
    1407          333 :   return same_type_p (t1, t2);
    1408              : }
    1409              : 
    1410              : /* Check if a type cast between two function types can be considered safe.  */
    1411              : 
    1412              : static bool
    1413          345 : cxx_safe_function_type_cast_p (tree t1, tree t2)
    1414              : {
    1415          345 :   if (TREE_TYPE (t1) == void_type_node &&
    1416          272 :       TYPE_ARG_TYPES (t1) == void_list_node)
    1417              :     return true;
    1418              : 
    1419          301 :   if (TREE_TYPE (t2) == void_type_node &&
    1420           95 :       TYPE_ARG_TYPES (t2) == void_list_node)
    1421              :     return true;
    1422              : 
    1423          273 :   if (!cxx_safe_arg_type_equiv_p (TREE_TYPE (t1), TREE_TYPE (t2)))
    1424              :     return false;
    1425              : 
    1426          112 :   for (t1 = TYPE_ARG_TYPES (t1), t2 = TYPE_ARG_TYPES (t2);
    1427          315 :        t1 && t2;
    1428          203 :        t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2))
    1429          239 :     if (!cxx_safe_arg_type_equiv_p (TREE_VALUE (t1), TREE_VALUE (t2)))
    1430              :       return false;
    1431              : 
    1432              :   return true;
    1433              : }
    1434              : 
    1435              : /* Subroutine in comptypes.  */
    1436              : 
    1437              : static bool
    1438  15762931270 : structural_comptypes (tree t1, tree t2, int strict)
    1439              : {
    1440              :   /* Both should be types that are not obviously the same.  */
    1441  15762931270 :   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  15762931270 :   if (!comparing_specializations)
    1446              :     {
    1447              :       /* TYPENAME_TYPEs should be resolved if the qualifying scope is the
    1448              :          current instantiation.  */
    1449  12544495683 :       if (TREE_CODE (t1) == TYPENAME_TYPE)
    1450     97785364 :         t1 = resolve_typename_type (t1, /*only_current_p=*/true);
    1451              : 
    1452  12544495683 :       if (TREE_CODE (t2) == TYPENAME_TYPE)
    1453    126498713 :         t2 = resolve_typename_type (t2, /*only_current_p=*/true);
    1454              :     }
    1455              : 
    1456  15762931270 :   if (TYPE_PTRMEMFUNC_P (t1))
    1457     25345959 :     t1 = TYPE_PTRMEMFUNC_FN_TYPE (t1);
    1458  15762931270 :   if (TYPE_PTRMEMFUNC_P (t2))
    1459     28566475 :     t2 = TYPE_PTRMEMFUNC_FN_TYPE (t2);
    1460              : 
    1461              :   /* Different classes of types can't be compatible.  */
    1462  15762931270 :   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  10402089188 :   if (TREE_CODE (t1) != ARRAY_TYPE
    1468  10402089188 :       && cp_type_quals (t1) != cp_type_quals (t2))
    1469              :     return false;
    1470   9768009764 :   if (TREE_CODE (t1) == FUNCTION_TYPE
    1471   9768009764 :       && 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   9767946854 :   if (FUNC_OR_METHOD_TYPE_P (t1))
    1476              :     {
    1477     36840649 :       if (type_memfn_rqual (t1) != type_memfn_rqual (t2))
    1478              :         return false;
    1479     22010079 :       if (flag_noexcept_type
    1480     43941267 :           && !comp_except_specs (TYPE_RAISES_EXCEPTIONS (t1),
    1481     21931188 :                                  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   9744053844 :   if (TREE_CODE (t1) != ARRAY_TYPE
    1490   9744053844 :       && TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
    1491    443828124 :     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   9300225720 :   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    764761461 :     case OPAQUE_TYPE:
    1504    764761461 :     case INTEGER_TYPE:
    1505    764761461 :     case FIXED_POINT_TYPE:
    1506    764761461 :     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    764761461 :       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      1616948 :     case TEMPLATE_TEMPLATE_PARM:
    1528      1616948 :     case BOUND_TEMPLATE_TEMPLATE_PARM:
    1529      1616948 :       if (!comp_template_parms_position (t1, t2))
    1530              :         return false;
    1531      1248315 :       if (!comp_template_parms
    1532      2496630 :           (DECL_TEMPLATE_PARMS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (t1)),
    1533      3531797 :            DECL_TEMPLATE_PARMS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (t2))))
    1534              :         return false;
    1535       861244 :       if (TREE_CODE (t1) == TEMPLATE_TEMPLATE_PARM)
    1536              :         break;
    1537              :       /* Don't check inheritance.  */
    1538              :       strict = COMPARE_STRICT;
    1539              :       /* Fall through.  */
    1540              : 
    1541   4350505408 :     case RECORD_TYPE:
    1542   4350505408 :     case UNION_TYPE:
    1543   7640527555 :       if (TYPE_TEMPLATE_INFO (t1) && TYPE_TEMPLATE_INFO (t2)
    1544   2718332382 :           && (TYPE_TI_TEMPLATE (t1) == TYPE_TI_TEMPLATE (t2)
    1545   1941595152 :               || TREE_CODE (t1) == BOUND_TEMPLATE_TEMPLATE_PARM)
    1546   5127312464 :           && comp_template_args (TYPE_TI_ARGS (t1), TYPE_TI_ARGS (t2)))
    1547              :         break;
    1548              : 
    1549   4291067159 :       if ((strict & COMPARE_BASE) && DERIVED_FROM_P (t1, t2))
    1550              :         break;
    1551   4291067126 :       else if ((strict & COMPARE_DERIVED) && DERIVED_FROM_P (t2, t1))
    1552              :         break;
    1553              : 
    1554              :       return false;
    1555              : 
    1556        50435 :     case OFFSET_TYPE:
    1557        50435 :       if (!comptypes (TYPE_OFFSET_BASETYPE (t1), TYPE_OFFSET_BASETYPE (t2),
    1558              :                       strict & ~COMPARE_REDECLARATION))
    1559              :         return false;
    1560        48353 :       if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
    1561              :         return false;
    1562              :       break;
    1563              : 
    1564   1315301808 :     case REFERENCE_TYPE:
    1565   1315301808 :       if (TYPE_REF_IS_RVALUE (t1) != TYPE_REF_IS_RVALUE (t2))
    1566              :         return false;
    1567              :       /* fall through to checks for pointer types */
    1568   1653205630 :       gcc_fallthrough ();
    1569              : 
    1570   1653205630 :     case POINTER_TYPE:
    1571   1653205630 :       if (TYPE_MODE (t1) != TYPE_MODE (t2)
    1572   1653205630 :           || !same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
    1573   1511415924 :         return false;
    1574              :       break;
    1575              : 
    1576      5497588 :     case FUNCTION_TYPE:
    1577      5497588 :       if (TYPE_NO_NAMED_ARGS_STDARG_P (t1) != TYPE_NO_NAMED_ARGS_STDARG_P (t2))
    1578              :         return false;
    1579              :       /* FALLTHRU */
    1580     12658559 :     case METHOD_TYPE:
    1581              :       /* Exception specs and memfn_rquals were checked above.  */
    1582     12658559 :       if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
    1583              :         return false;
    1584     12053036 :       if (!compparms (TYPE_ARG_TYPES (t1), TYPE_ARG_TYPES (t2)))
    1585              :         return false;
    1586              :       break;
    1587              : 
    1588      1792292 :     case ARRAY_TYPE:
    1589              :       /* Target types must match incl. qualifiers.  */
    1590      1792292 :       if (!comp_array_types (t1, t2, ((strict & COMPARE_REDECLARATION)
    1591      1792292 :                                       ? bounds_either : bounds_none),
    1592              :                              /*strict=*/true))
    1593              :         return false;
    1594              :       break;
    1595              : 
    1596   1818405389 :     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   1818405389 :       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   1218417194 :       if (!cp_tree_equal (CLASS_PLACEHOLDER_TEMPLATE (t1),
    1604    609208597 :                           CLASS_PLACEHOLDER_TEMPLATE (t2)))
    1605              :         return false;
    1606              :       /* Constrained 'auto's are distinct from parms that don't have the same
    1607              :          constraints.  */
    1608    584539455 :       if (!equivalent_placeholder_constraints (t1, t2))
    1609              :         return false;
    1610              :       break;
    1611              : 
    1612    265046690 :     case TYPENAME_TYPE:
    1613    530093380 :       if (!cp_tree_equal (TYPENAME_TYPE_FULLNAME (t1),
    1614    265046690 :                           TYPENAME_TYPE_FULLNAME (t2)))
    1615              :         return false;
    1616              :       /* Qualifiers don't matter on scopes.  */
    1617    232474521 :       if (!same_type_ignoring_top_level_qualifiers_p (TYPE_CONTEXT (t1),
    1618    232474521 :                                                       TYPE_CONTEXT (t2)))
    1619              :         return false;
    1620              :       break;
    1621              : 
    1622        26997 :     case UNBOUND_CLASS_TEMPLATE:
    1623        26997 :       if (!cp_tree_equal (TYPE_IDENTIFIER (t1), TYPE_IDENTIFIER (t2)))
    1624              :         return false;
    1625        26997 :       if (!same_type_p (TYPE_CONTEXT (t1), TYPE_CONTEXT (t2)))
    1626              :         return false;
    1627              :       break;
    1628              : 
    1629      2130783 :     case COMPLEX_TYPE:
    1630      2130783 :       if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
    1631              :         return false;
    1632              :       break;
    1633              : 
    1634     12722507 :     case VECTOR_TYPE:
    1635     12722507 :       if (gnu_vector_type_p (t1) != gnu_vector_type_p (t2)
    1636     23755341 :           || maybe_ne (TYPE_VECTOR_SUBPARTS (t1), TYPE_VECTOR_SUBPARTS (t2))
    1637     23811846 :           || !same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
    1638      1689673 :         return false;
    1639              :       break;
    1640              : 
    1641      7409111 :     case TYPE_PACK_EXPANSION:
    1642      7409111 :       return (same_type_p (PACK_EXPANSION_PATTERN (t1),
    1643              :                            PACK_EXPANSION_PATTERN (t2))
    1644     14658416 :               && comp_template_args (PACK_EXPANSION_EXTRA_ARGS (t1),
    1645      7249305 :                                      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     29032702 :     case DECLTYPE_TYPE:
    1654     58065404 :       if (DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t1)
    1655     29032702 :           != DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t2))
    1656              :         return false;
    1657     29007395 :       if (DECLTYPE_FOR_LAMBDA_CAPTURE (t1) != DECLTYPE_FOR_LAMBDA_CAPTURE (t2))
    1658              :         return false;
    1659     29007395 :       if (DECLTYPE_FOR_LAMBDA_PROXY (t1) != DECLTYPE_FOR_LAMBDA_PROXY (t2))
    1660              :         return false;
    1661     29007395 :       if (!cp_tree_equal (DECLTYPE_TYPE_EXPR (t1), DECLTYPE_TYPE_EXPR (t2)))
    1662              :         return false;
    1663              :       break;
    1664              : 
    1665       720351 :     case TRAIT_TYPE:
    1666       720351 :       if (TRAIT_TYPE_KIND (t1) != TRAIT_TYPE_KIND (t2))
    1667              :         return false;
    1668         1435 :       if (!cp_tree_equal (TRAIT_TYPE_TYPE1 (t1), TRAIT_TYPE_TYPE1 (t2))
    1669         2870 :           || !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    811811074 :   if (!comp_type_attributes (t1, t2))
    1686              :     return false;
    1687              : 
    1688    811809887 :  check_alias:
    1689   1255647328 :   if (comparing_dependent_aliases
    1690   1255647328 :       && (typedef_variant_p (t1) || typedef_variant_p (t2)))
    1691              :     {
    1692      4245783 :       tree dep1 = dependent_opaque_alias_p (t1) ? t1 : NULL_TREE;
    1693      4245783 :       tree dep2 = dependent_opaque_alias_p (t2) ? t2 : NULL_TREE;
    1694      4245783 :       if ((dep1 || dep2)
    1695      4245783 :           && (!(dep1 && dep2)
    1696            0 :               || !comp_type_attributes (DECL_ATTRIBUTES (TYPE_NAME (dep1)),
    1697            0 :                                         DECL_ATTRIBUTES (TYPE_NAME (dep2)))))
    1698           39 :         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      4245744 :       ++processing_template_decl;
    1707      4245744 :       dep1 = dependent_alias_template_spec_p (t1, nt_transparent);
    1708      4245744 :       dep2 = dependent_alias_template_spec_p (t2, nt_transparent);
    1709      4245744 :       --processing_template_decl;
    1710      4245744 :       if ((dep1 || dep2) && dep1 != dep2)
    1711              :         return false;
    1712              :     }
    1713              : 
    1714              :   return true;
    1715              : }
    1716              : 
    1717              : /* C++ implementation of compatible_types_for_indirection_note_p.  */
    1718              : 
    1719              : bool
    1720         1611 : compatible_types_for_indirection_note_p (tree type1, tree type2)
    1721              : {
    1722         1611 :   return same_type_p (type1, type2);
    1723              : }
    1724              : 
    1725              : /* Return true if T1 and T2 are related as allowed by STRICT.  STRICT
    1726              :    is a bitwise-or of the COMPARE_* flags.  */
    1727              : 
    1728              : bool
    1729  23878993744 : comptypes (tree t1, tree t2, int strict)
    1730              : {
    1731  23878993744 :   gcc_checking_assert (t1 && t2);
    1732              : 
    1733              :   /* TYPE_ARGUMENT_PACKS are not really types.  */
    1734  23878993744 :   gcc_checking_assert (TREE_CODE (t1) != TYPE_ARGUMENT_PACK
    1735              :                        && TREE_CODE (t2) != TYPE_ARGUMENT_PACK);
    1736              : 
    1737  23878993744 :   if (t1 == t2)
    1738              :     return true;
    1739              : 
    1740              :   /* Suppress errors caused by previously reported errors.  */
    1741  15762932434 :   if (t1 == error_mark_node || t2 == error_mark_node)
    1742              :     return false;
    1743              : 
    1744  15762932273 :   if (strict == COMPARE_STRICT)
    1745              :     {
    1746  14155612808 :       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   1594996682 :         return structural_comptypes (t1, t2, strict);
    1750              : 
    1751  12560616126 :       if (flag_checking && param_use_canonical_types)
    1752              :         {
    1753  12560615123 :           bool result = structural_comptypes (t1, t2, strict);
    1754              : 
    1755  12560615123 :           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  12560615123 :           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   1607319465 :   else if (strict == COMPARE_STRUCTURAL)
    1778   1544037703 :     return structural_comptypes (t1, t2, COMPARE_STRICT);
    1779              :   else
    1780     63281762 :     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   3862940440 : same_type_ignoring_top_level_qualifiers_p (tree type1, tree type2)
    1788              : {
    1789   3862940440 :   if (type1 == error_mark_node || type2 == error_mark_node)
    1790              :     return false;
    1791   3862939721 :   if (type1 == type2)
    1792              :     return true;
    1793              : 
    1794   2192168862 :   type1 = cp_build_qualified_type (type1, TYPE_UNQUALIFIED);
    1795   2192168862 :   type2 = cp_build_qualified_type (type2, TYPE_UNQUALIFIED);
    1796   2192168862 :   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    321258887 : similar_type_p (tree type1, tree type2)
    1803              : {
    1804    321258887 :   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    321258887 :   if (same_type_ignoring_top_level_qualifiers_p (type1, type2))
    1816              :     return true;
    1817              : 
    1818    147161756 :   if ((TYPE_PTR_P (type1) && TYPE_PTR_P (type2))
    1819    146940414 :       || (TYPE_PTRDATAMEM_P (type1) && TYPE_PTRDATAMEM_P (type2))
    1820    146939481 :       || (TREE_CODE (type1) == ARRAY_TYPE && TREE_CODE (type2) == ARRAY_TYPE))
    1821       224100 :     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    239149744 : at_least_as_qualified_p (const_tree type1, const_tree type2)
    2086              : {
    2087    239149744 :   int q1 = cp_type_quals (type1);
    2088    239149744 :   int q2 = cp_type_quals (type2);
    2089              : 
    2090              :   /* All qualifiers for TYPE2 must also appear in TYPE1.  */
    2091    239149744 :   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     14427300 : comp_cv_qualification (int q1, int q2)
    2099              : {
    2100     14427300 :   if (q1 == q2)
    2101              :     return 0;
    2102              : 
    2103      3487391 :   if ((q1 & q2) == q2)
    2104              :     return 1;
    2105       349889 :   else if ((q1 & q2) == q1)
    2106       349304 :     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   1033782184 : compparms (const_tree parms1, const_tree parms2)
    2143              : {
    2144   1033782184 :   const_tree t1, t2;
    2145              : 
    2146              :   /* An unspecified parmlist matches any specified parmlist
    2147              :      whose argument types don't need default promotions.  */
    2148              : 
    2149   1033782184 :   for (t1 = parms1, t2 = parms2;
    2150   1658325448 :        t1 || t2;
    2151    624543264 :        t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2))
    2152              :     {
    2153              :       /* If one parmlist is shorter than the other,
    2154              :          they fail to match.  */
    2155   1550398504 :       if (!t1 || !t2)
    2156              :         return false;
    2157   1549823706 :       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     27329143 : cxx_sizeof_or_alignof_type (location_t loc, tree type, enum tree_code op,
    2171              :                             bool std_alignof, bool complain)
    2172              : {
    2173     27329143 :   gcc_assert (op == SIZEOF_EXPR || op == ALIGNOF_EXPR);
    2174     27329143 :   if (type == error_mark_node)
    2175              :     return error_mark_node;
    2176              : 
    2177     27329141 :   type = non_reference (type);
    2178     27329141 :   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     27329141 :   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     27329129 :   bool dependent_p = dependent_type_p (type);
    2199     27329129 :   if (!dependent_p)
    2200              :     {
    2201     22541053 :       complete_type (type);
    2202     22541053 :       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     22541053 :   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     22541053 :       || (processing_template_decl
    2216      2031441 :           && COMPLETE_TYPE_P (type)
    2217      2031435 :           && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST))
    2218              :     {
    2219      4788076 :       tree value = build_min (op, size_type_node, type);
    2220      4788076 :       TREE_READONLY (value) = 1;
    2221      4788076 :       if (op == ALIGNOF_EXPR && std_alignof)
    2222       561397 :         ALIGNOF_EXPR_STD_P (value) = true;
    2223      4788076 :       SET_EXPR_LOCATION (value, loc);
    2224      4788076 :       return value;
    2225              :     }
    2226              : 
    2227     22541053 :   return c_sizeof_or_alignof_type (loc, complete_type (type),
    2228              :                                    op == SIZEOF_EXPR, std_alignof,
    2229     22541053 :                                    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      2717710 : cxx_sizeof_nowarn (tree type)
    2238              : {
    2239      2717710 :   if (TREE_CODE (type) == FUNCTION_TYPE
    2240      2717710 :       || VOID_TYPE_P (type)
    2241      2717628 :       || TREE_CODE (type) == ERROR_MARK)
    2242           82 :     return size_one_node;
    2243      2717628 :   else if (!COMPLETE_TYPE_P (type))
    2244           19 :     return size_zero_node;
    2245              :   else
    2246      2717609 :     return cxx_sizeof_or_alignof_type (input_location, type,
    2247      2717609 :                                        SIZEOF_EXPR, false, false);
    2248              : }
    2249              : 
    2250              : /* Process a sizeof expression where the operand is an expression.  */
    2251              : 
    2252              : static tree
    2253      1216872 : cxx_sizeof_expr (location_t loc, tree e, tsubst_flags_t complain)
    2254              : {
    2255      1216872 :   if (e == error_mark_node)
    2256              :     return error_mark_node;
    2257              : 
    2258      1216138 :   if (instantiation_dependent_uneval_expression_p (e))
    2259              :     {
    2260       344980 :       e = build_min (SIZEOF_EXPR, size_type_node, e);
    2261       344980 :       TREE_SIDE_EFFECTS (e) = 0;
    2262       344980 :       TREE_READONLY (e) = 1;
    2263       344980 :       SET_EXPR_LOCATION (e, loc);
    2264              : 
    2265       344980 :       return e;
    2266              :     }
    2267              : 
    2268       871158 :   location_t e_loc = cp_expr_loc_or_loc (e, loc);
    2269       871158 :   STRIP_ANY_LOCATION_WRAPPER (e);
    2270              : 
    2271       871158 :   if (TREE_CODE (e) == PARM_DECL
    2272        25859 :       && DECL_ARRAY_PARAMETER_P (e)
    2273       871535 :       && (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       871158 :   e = mark_type_use (e);
    2283              : 
    2284       871158 :   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       871146 :   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       871113 :   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       871113 :     e = TREE_TYPE (e);
    2312              : 
    2313       871131 :   return cxx_sizeof_or_alignof_type (loc, e, SIZEOF_EXPR, false,
    2314       871131 :                                      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       100371 : cxx_alignof_expr (location_t loc, tree e, bool std_alignof,
    2325              :                   tsubst_flags_t complain)
    2326              : {
    2327       100371 :   tree t;
    2328              : 
    2329       100371 :   if (e == error_mark_node)
    2330              :     return error_mark_node;
    2331              : 
    2332       100363 :   if (processing_template_decl)
    2333              :     {
    2334        18658 :       e = build_min (ALIGNOF_EXPR, size_type_node, e);
    2335        18658 :       TREE_SIDE_EFFECTS (e) = 0;
    2336        18658 :       TREE_READONLY (e) = 1;
    2337        18658 :       SET_EXPR_LOCATION (e, loc);
    2338        18658 :       ALIGNOF_EXPR_STD_P (e) = std_alignof;
    2339              : 
    2340        18658 :       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      1317243 : cxx_sizeof_or_alignof_expr (location_t loc, tree e, enum tree_code op,
    2402              :                             bool std_alignof, bool complain)
    2403              : {
    2404      1317243 :   gcc_assert (op == SIZEOF_EXPR || op == ALIGNOF_EXPR);
    2405      1317243 :   if (op == SIZEOF_EXPR)
    2406      1777079 :     return cxx_sizeof_expr (loc, e, complain? tf_warning_or_error : tf_none);
    2407              :   else
    2408       100398 :     return cxx_alignof_expr (loc, e, std_alignof,
    2409       100371 :                              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       268842 : cxx_alignas_expr (tree e)
    2421              : {
    2422       268842 :   if (e == NULL_TREE || e == error_mark_node
    2423       537684 :       || (!TYPE_P (e) && !require_potential_rvalue_constant_expression (e)))
    2424            0 :     return e;
    2425              : 
    2426       268842 :   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       141213 :     return cxx_sizeof_or_alignof_type (input_location,
    2434              :                                        e, ALIGNOF_EXPR,
    2435              :                                        /*std_alignof=*/true,
    2436       141213 :                                        /*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       127629 :   if (value_dependent_expression_p (e))
    2443              :     /* Leave value-dependent expression alone for now. */
    2444              :     return e;
    2445              : 
    2446        65769 :   e = instantiate_non_dependent_expr (e);
    2447        65769 :   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        65769 :   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        65751 :   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   1436781891 : invalid_nonstatic_memfn_p (location_t loc, tree expr, tsubst_flags_t complain)
    2482              : {
    2483   1436781891 :   if (expr == NULL_TREE)
    2484              :     return false;
    2485              :   /* Don't enforce this in MS mode.  */
    2486   1436780451 :   if (flag_ms_extensions)
    2487              :     return false;
    2488   1436772390 :   if (is_overloaded_fn (expr) && !really_overloaded_fn (expr))
    2489    114660502 :     expr = get_first_fn (expr);
    2490   1436772390 :   if (TREE_TYPE (expr)
    2491   1436772390 :       && 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   3440649484 : is_bitfield_expr_with_lowered_type (const_tree exp)
    2517              : {
    2518   4707230080 :   switch (TREE_CODE (exp))
    2519              :     {
    2520      8308578 :     case COND_EXPR:
    2521     16617156 :       if (!is_bitfield_expr_with_lowered_type (TREE_OPERAND (exp, 1)
    2522      8308552 :                                                ? 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       884043 :     case COMPOUND_EXPR:
    2528       884043 :       return is_bitfield_expr_with_lowered_type (TREE_OPERAND (exp, 1));
    2529              : 
    2530    405006775 :     case MODIFY_EXPR:
    2531    405006775 :     case SAVE_EXPR:
    2532    405006775 :     case UNARY_PLUS_EXPR:
    2533    405006775 :     case PREDECREMENT_EXPR:
    2534    405006775 :     case PREINCREMENT_EXPR:
    2535    405006775 :     case POSTDECREMENT_EXPR:
    2536    405006775 :     case POSTINCREMENT_EXPR:
    2537    405006775 :     case NEGATE_EXPR:
    2538    405006775 :     case NON_LVALUE_EXPR:
    2539    405006775 :     case BIT_NOT_EXPR:
    2540    405006775 :     case CLEANUP_POINT_EXPR:
    2541    405006775 :       return is_bitfield_expr_with_lowered_type (TREE_OPERAND (exp, 0));
    2542              : 
    2543    248416675 :     case COMPONENT_REF:
    2544    248416675 :       {
    2545    248416675 :         tree field;
    2546              : 
    2547    248416675 :         field = TREE_OPERAND (exp, 1);
    2548    248416675 :         if (TREE_CODE (field) != FIELD_DECL || !DECL_BIT_FIELD_TYPE (field))
    2549              :           return NULL_TREE;
    2550     17587753 :         if (same_type_ignoring_top_level_qualifiers_p
    2551     17587753 :             (TREE_TYPE (exp), DECL_BIT_FIELD_TYPE (field)))
    2552              :           return NULL_TREE;
    2553     17419846 :         return DECL_BIT_FIELD_TYPE (field);
    2554              :       }
    2555              : 
    2556    650887583 :     case VAR_DECL:
    2557    650887583 :       if (DECL_HAS_VALUE_EXPR_P (exp))
    2558      1036258 :         return is_bitfield_expr_with_lowered_type (DECL_VALUE_EXPR
    2559      1036258 :                                                    (const_cast<tree> (exp)));
    2560              :       return NULL_TREE;
    2561              : 
    2562    866603005 :     case VIEW_CONVERT_EXPR:
    2563    866603005 :       if (location_wrapper_p (exp))
    2564    859653379 :         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   1633719693 : unlowered_expr_type (const_tree exp)
    2579              : {
    2580   1633719693 :   tree type;
    2581   1633719693 :   tree etype = TREE_TYPE (exp);
    2582              : 
    2583   1633719693 :   type = is_bitfield_expr_with_lowered_type (exp);
    2584   1633719693 :   if (type)
    2585     13868304 :     type = cp_build_qualified_type (type, cp_type_quals (etype));
    2586              :   else
    2587              :     type = etype;
    2588              : 
    2589   1633719693 :   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   1141056883 : decay_conversion (tree exp,
    2606              :                   tsubst_flags_t complain,
    2607              :                   bool reject_builtin /* = true */)
    2608              : {
    2609   1141056883 :   tree type;
    2610   1141056883 :   enum tree_code code;
    2611   1141056883 :   location_t loc = cp_expr_loc_or_input_loc (exp);
    2612              : 
    2613   1141056883 :   type = TREE_TYPE (exp);
    2614   1141056883 :   if (type == error_mark_node)
    2615              :     return error_mark_node;
    2616              : 
    2617   1141056671 :   exp = resolve_nondeduced_context_or_error (exp, complain);
    2618              : 
    2619   1141056671 :   code = TREE_CODE (type);
    2620              : 
    2621   1141056671 :   if (error_operand_p (exp))
    2622           90 :     return error_mark_node;
    2623              : 
    2624   1141056581 :   if (NULLPTR_TYPE_P (type) && !TREE_SIDE_EFFECTS (exp))
    2625              :     {
    2626      1696596 :       mark_rvalue_use (exp, loc, reject_builtin);
    2627      1696596 :       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   1139359985 :   if (code == VOID_TYPE)
    2633              :     {
    2634         5768 :       if (complain & tf_error)
    2635            3 :         error_at (loc, "void value not ignored as it ought to be");
    2636         5768 :       return error_mark_node;
    2637              :     }
    2638   1139354217 :   if (invalid_nonstatic_memfn_p (loc, exp, complain))
    2639            6 :     return error_mark_node;
    2640   1139354211 :   if (code == FUNCTION_TYPE || is_overloaded_fn (exp))
    2641              :     {
    2642    119895990 :       exp = mark_lvalue_use (exp);
    2643    119895990 :       if (reject_builtin && reject_gcc_builtin (exp, loc))
    2644          109 :         return error_mark_node;
    2645    119895881 :       return cp_build_addr_expr (exp, complain);
    2646              :     }
    2647   1019458221 :   if (code == ARRAY_TYPE)
    2648              :     {
    2649      6150203 :       tree adr;
    2650      6150203 :       tree ptrtype;
    2651              : 
    2652      6150203 :       exp = mark_lvalue_use (exp);
    2653              : 
    2654      6150203 :       if (INDIRECT_REF_P (exp))
    2655       160087 :         return build_nop (build_pointer_type (TREE_TYPE (type)),
    2656       320174 :                           TREE_OPERAND (exp, 0));
    2657              : 
    2658      5990116 :       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      5990113 :       if (!obvalue_p (exp)
    2668      5990113 :           && ! (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      5990113 :       ptrtype = build_pointer_type (TREE_TYPE (type));
    2676              : 
    2677      5990113 :       if (VAR_P (exp))
    2678              :         {
    2679       553214 :           if (!cxx_mark_addressable (exp))
    2680            0 :             return error_mark_node;
    2681       553214 :           adr = build_nop (ptrtype, build_address (exp));
    2682       553214 :           return adr;
    2683              :         }
    2684              :       /* This way is better for a COMPONENT_REF since it can
    2685              :          simplify the offset for a component.  */
    2686      5436899 :       adr = cp_build_addr_expr (exp, complain);
    2687      5436899 :       return cp_convert (ptrtype, adr, complain);
    2688              :     }
    2689              : 
    2690              :   /* Otherwise, it's the lvalue-to-rvalue conversion.  */
    2691   1013308018 :   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   1013308018 :   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   1013308018 :   type = TREE_TYPE (exp);
    2709   1013308018 :   if (!CLASS_TYPE_P (type) && cv_qualified_p (type))
    2710    316796110 :     exp = build_nop (cv_unqualified (type), exp);
    2711              : 
    2712   1013308018 :   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    304151043 : cp_default_conversion (tree exp, tsubst_flags_t complain)
    2733              : {
    2734              :   /* Check for target-specific promotions.  */
    2735    304151043 :   tree promoted_type = targetm.promoted_type (TREE_TYPE (exp));
    2736    304151043 :   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    304151043 :   else if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (exp)))
    2742    210585311 :     exp = cp_perform_integral_promotions (exp, complain);
    2743              :   /* Perform the other conversions.  */
    2744    304151043 :   exp = decay_conversion (exp, complain);
    2745              : 
    2746    304151043 :   return exp;
    2747              : }
    2748              : 
    2749              : /* C version.  */
    2750              : 
    2751              : tree
    2752     40743506 : default_conversion (tree exp)
    2753              : {
    2754     40743506 :   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    216344459 : cp_perform_integral_promotions (tree expr, tsubst_flags_t complain)
    2763              : {
    2764    216344459 :   tree type;
    2765    216344459 :   tree promoted_type;
    2766              : 
    2767    216344459 :   expr = mark_rvalue_use (expr);
    2768    216344459 :   if (error_operand_p (expr))
    2769            6 :     return error_mark_node;
    2770              : 
    2771    216344453 :   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    216344453 :   tree bitfield_type = is_bitfield_expr_with_lowered_type (expr);
    2783    216344453 :   if (bitfield_type
    2784    216344453 :       && (TREE_CODE (bitfield_type) == ENUMERAL_TYPE
    2785       508424 :           || TYPE_PRECISION (type) > TYPE_PRECISION (integer_type_node)))
    2786              :     type = bitfield_type;
    2787              : 
    2788    216344453 :   gcc_assert (INTEGRAL_OR_ENUMERATION_TYPE_P (type));
    2789              :   /* Scoped enums don't promote.  */
    2790    216344453 :   if (SCOPED_ENUM_P (type))
    2791              :     return expr;
    2792    215914449 :   promoted_type = type_promotes_to (type);
    2793    215914449 :   if (type != promoted_type)
    2794     64660555 :     expr = cp_convert (promoted_type, expr, complain);
    2795    151253894 :   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      1498780 : perform_integral_promotions (tree expr)
    2805              : {
    2806      1498780 :   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      3649381 : string_conv_p (const_tree totype, const_tree exp, int warn)
    2814              : {
    2815      3649381 :   tree t;
    2816              : 
    2817      3649381 :   if (!TYPE_PTR_P (totype))
    2818              :     return 0;
    2819              : 
    2820      3648910 :   t = TREE_TYPE (totype);
    2821      3648910 :   if (!same_type_p (t, char_type_node)
    2822      3503604 :       && !same_type_p (t, char8_type_node)
    2823      3443632 :       && !same_type_p (t, char16_type_node)
    2824      3394759 :       && !same_type_p (t, char32_type_node)
    2825      6994797 :       && !same_type_p (t, wchar_type_node))
    2826              :     return 0;
    2827              : 
    2828       341625 :   location_t loc = EXPR_LOC_OR_LOC (exp, input_location);
    2829              : 
    2830       341625 :   STRIP_ANY_LOCATION_WRAPPER (exp);
    2831              : 
    2832       341625 :   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       341517 :       t = build_pointer_type (cp_build_qualified_type (t, TYPE_QUAL_CONST));
    2842       341517 :       if (!same_type_p (TREE_TYPE (exp), t))
    2843              :         return 0;
    2844        14017 :       STRIP_NOPS (exp);
    2845        14017 :       if (TREE_CODE (exp) != ADDR_EXPR
    2846        14017 :           || 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        76277 : rationalize_conditional_expr (enum tree_code code, tree t,
    2874              :                               tsubst_flags_t complain)
    2875              : {
    2876        76277 :   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        76277 :   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        76277 :   tree op1 = TREE_OPERAND (t, 1);
    2905        76277 :   if (TREE_CODE (op1) != THROW_EXPR)
    2906        76274 :     op1 = cp_build_unary_op (code, op1, false, complain);
    2907        76277 :   tree op2 = TREE_OPERAND (t, 2);
    2908        76277 :   if (TREE_CODE (op2) != THROW_EXPR)
    2909        76271 :     op2 = cp_build_unary_op (code, op2, false, complain);
    2910              : 
    2911        76277 :   return
    2912        76277 :     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      1416774 : lookup_anon_field (tree, tree type)
    2922              : {
    2923      1416774 :   tree field;
    2924              : 
    2925      1416774 :   type = TYPE_MAIN_VARIANT (type);
    2926      1416774 :   field = ANON_AGGR_TYPE_FIELD (type);
    2927      1416774 :   gcc_assert (field);
    2928      1416774 :   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    116904226 : build_class_member_access_expr (cp_expr object, tree member,
    2945              :                                 tree access_path, bool preserve_reference,
    2946              :                                 tsubst_flags_t complain)
    2947              : {
    2948    116904226 :   tree object_type;
    2949    116904226 :   tree member_scope;
    2950    116904226 :   tree result = NULL_TREE;
    2951    116904226 :   tree using_decl = NULL_TREE;
    2952              : 
    2953    116904226 :   if (error_operand_p (object) || error_operand_p (member))
    2954           58 :     return error_mark_node;
    2955              : 
    2956    116904168 :   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    116904168 :   object_type = TREE_TYPE (object);
    2963    116904168 :   if (!currently_open_class (object_type)
    2964    116904168 :       && !complete_type_or_maybe_complain (object_type, object, complain))
    2965            0 :     return error_mark_node;
    2966    116904168 :   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    116904168 :   if (DECL_P (member))
    2986              :     {
    2987     50114341 :       member_scope = DECL_CLASS_CONTEXT (member);
    2988     50114341 :       if (!mark_used (member, complain) && !(complain & tf_error))
    2989            0 :         return error_mark_node;
    2990              : 
    2991     50114341 :       if (TREE_UNAVAILABLE (member))
    2992           30 :         error_unavailable_use (member, NULL_TREE);
    2993     50114311 :       else if (TREE_DEPRECATED (member))
    2994           30 :         warn_deprecated_use (member, NULL_TREE);
    2995              :     }
    2996              :   else
    2997     66789827 :     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    118324538 :   while ((ANON_AGGR_TYPE_P (member_scope) || UNSCOPED_ENUM_P (member_scope))
    3002    119745391 :          && !same_type_ignoring_top_level_qualifiers_p (member_scope,
    3003              :                                                         object_type))
    3004      1420370 :     member_scope = TYPE_CONTEXT (member_scope);
    3005    116904168 :   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    116904157 :   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    116904157 :   if (VAR_P (member))
    3032              :     {
    3033              :       /* A static data member.  */
    3034        73163 :       result = member;
    3035        73163 :       mark_exp_read (object);
    3036              : 
    3037        73163 :       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        73163 :       if (TREE_SIDE_EFFECTS (object))
    3044         2558 :         result = build2 (COMPOUND_EXPR, TREE_TYPE (result), object, result);
    3045              :     }
    3046    116830994 :   else if (TREE_CODE (member) == FIELD_DECL)
    3047              :     {
    3048              :       /* A non-static data member.  */
    3049     50040963 :       bool null_object_p;
    3050     50040963 :       int type_quals;
    3051     50040963 :       tree member_type;
    3052              : 
    3053     50040963 :       if (INDIRECT_REF_P (object))
    3054     38395628 :         null_object_p =
    3055     38395628 :           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     50040963 :       if (!same_type_p (TYPE_MAIN_VARIANT (object_type),
    3061              :                         TYPE_MAIN_VARIANT (member_scope)))
    3062              :         {
    3063      1937921 :           tree binfo;
    3064      1937921 :           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      1937921 :           if (!cp_unevaluated_operand
    3070      1937458 :               && !dependent_type_p (object_type)
    3071      3595876 :               && !complete_type_or_maybe_complain (object_type, object,
    3072              :                                                    complain))
    3073           13 :             return error_mark_node;
    3074              : 
    3075      2636108 :           binfo = lookup_base (access_path ? access_path : object_type,
    3076              :                                member_scope, ba_unique, &kind, complain);
    3077      1937918 :           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      1937914 :           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      1937908 :           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      1937908 :           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    100081900 :       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     51458068 :           && (!same_type_ignoring_top_level_qualifiers_p
    3113      1417118 :               (TREE_TYPE (object), DECL_CONTEXT (member))))
    3114              :         {
    3115      1416641 :           tree anonymous_union;
    3116              : 
    3117      1416641 :           anonymous_union = lookup_anon_field (TREE_TYPE (object),
    3118      1416641 :                                                DECL_CONTEXT (member));
    3119      1416641 :           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     50040950 :       type_quals = TYPE_UNQUALIFIED;
    3128     50040950 :       member_type = TREE_TYPE (member);
    3129     50040950 :       if (!TYPE_REF_P (member_type))
    3130              :         {
    3131     49242004 :           type_quals = (cp_type_quals (member_type)
    3132     49242004 :                         | 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     49242004 :           if (DECL_MUTABLE_P (member))
    3138       316234 :             type_quals &= ~TYPE_QUAL_CONST;
    3139     49242004 :           member_type = cp_build_qualified_type (member_type, type_quals);
    3140              :         }
    3141              : 
    3142     50040950 :       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     50040950 :       if (type_quals & TYPE_QUAL_CONST)
    3149     15792365 :         TREE_READONLY (result) = 1;
    3150     50040950 :       if (type_quals & TYPE_QUAL_VOLATILE)
    3151       181382 :         TREE_THIS_VOLATILE (result) = 1;
    3152              :     }
    3153     66790031 :   else if (BASELINK_P (member))
    3154              :     {
    3155              :       /* The member is a (possibly overloaded) member function.  */
    3156     66789818 :       tree functions;
    3157     66789818 :       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     66789818 :       functions = BASELINK_FUNCTIONS (member);
    3163     66789818 :       if (TREE_CODE (functions) == OVERLOAD && OVL_SINGLE_P (functions))
    3164     66789818 :         functions = OVL_FIRST (functions);
    3165     66789818 :       if (TREE_CODE (functions) == FUNCTION_DECL
    3166     66789818 :           && DECL_STATIC_FUNCTION_P (functions))
    3167       598308 :         type = TREE_TYPE (functions);
    3168              :       else
    3169     66191510 :         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     66789818 :       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    116904132 :   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    110299312 :     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       201464 : lookup_destructor (tree object, tree scope, tree dtor_name,
    3211              :                    tsubst_flags_t complain)
    3212              : {
    3213       201464 :   tree object_type = TREE_TYPE (object);
    3214       201464 :   tree dtor_type = TREE_OPERAND (dtor_name, 0);
    3215       201464 :   tree expr;
    3216              : 
    3217              :   /* We've already complained about this destructor.  */
    3218       201464 :   if (dtor_type == error_mark_node)
    3219              :     return error_mark_node;
    3220              : 
    3221       201458 :   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       201455 :   if (is_auto (dtor_type))
    3229              :     dtor_type = object_type;
    3230       201452 :   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       201429 :   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       201445 :   expr = lookup_member (dtor_type, complete_dtor_identifier,
    3253              :                         /*protect=*/1, /*want_type=*/false,
    3254              :                         tf_warning_or_error);
    3255       201445 :   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       201439 :   expr = (adjust_result_of_qualified_name_lookup
    3262       201439 :           (expr, dtor_type, object_type));
    3263       201439 :   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       201296 :     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       252670 : 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       252670 :   if (TREE_CODE (decl) != TEMPLATE_DECL
    3296       252670 :       && TREE_CODE (decl) != TEMPLATE_ID_EXPR)
    3297              :     {
    3298        60333 :       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        50606 :       else if (!is_overloaded_fn (decl))
    3307            0 :         permerror (input_location, "%qD is not a template", decl);
    3308              :       else
    3309              :         {
    3310        50606 :           bool found = false;
    3311              : 
    3312       101212 :           for (lkp_iterator iter (MAYBE_BASELINK_FUNCTIONS (decl));
    3313       101214 :                !found && iter; ++iter)
    3314              :             {
    3315        50608 :               tree fn = *iter;
    3316        50608 :               if (TREE_CODE (fn) == TEMPLATE_DECL
    3317        50212 :                   || TREE_CODE (fn) == TEMPLATE_ID_EXPR
    3318        50622 :                   || (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        50606 :           if (!found)
    3324           12 :             permerror (input_location, "%qD is not a template", decl);
    3325              :         }
    3326              :     }
    3327       252670 : }
    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     94664159 : access_failure_info::get_any_accessor (bool const_p) const
    3348              : {
    3349     94664159 :   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     94664089 : access_failure_info::maybe_suggest_accessor (bool const_p) const
    3384              : {
    3385     94664089 :   tree accessor = get_any_accessor (const_p);
    3386     94664089 :   if (accessor == NULL_TREE)
    3387     94663991 :     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    189765566 : 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    189765566 :   tree expr;
    3483    189765566 :   tree object_type;
    3484    189765566 :   tree member;
    3485    189765566 :   tree access_path = NULL_TREE;
    3486    189765566 :   tree orig_object = object;
    3487    189765566 :   tree orig_name = name;
    3488              : 
    3489    189765566 :   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    189765070 :   if (!objc_is_public (object, name))
    3494            0 :     return error_mark_node;
    3495              : 
    3496    189765070 :   object_type = TREE_TYPE (object);
    3497              : 
    3498    189765070 :   if (processing_template_decl)
    3499              :     {
    3500    157439827 :       if (/* If OBJECT is dependent, so is OBJECT.NAME.  */
    3501    157439827 :           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     73867954 :           || (TREE_CODE (name) == TEMPLATE_ID_EXPR
    3505       580988 :               && dependent_template_id_p (TREE_OPERAND (name, 0),
    3506       580988 :                                           TREE_OPERAND (name, 1)))
    3507              :           /* If NAME is "T::X" where "T" is dependent, then the
    3508              :              expression is dependent.  */
    3509     73581237 :           || (TREE_CODE (name) == SCOPE_REF
    3510       104225 :               && TYPE_P (TREE_OPERAND (name, 0))
    3511       104225 :               && 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     73477232 :           || (TREE_CODE (name) == IDENTIFIER_NODE
    3515     72859959 :               && IDENTIFIER_CONV_OP_P (name)
    3516           57 :               && dependent_type_p (TREE_TYPE (name)))
    3517              :           /* This is OBJECT.[:R:], which is dependent.  */
    3518     73477181 :           || dependent_splice_p (name)
    3519              :           /* This is OBJECT.[:T::R:], which is dependent.  */
    3520    230916805 :           || (TREE_CODE (name) == SCOPE_REF
    3521          220 :               && dependent_splice_p (TREE_OPERAND (name, 1))))
    3522              :         {
    3523     98125965 :         dependent:
    3524     98125965 :           expr = build_min_nt_loc (UNKNOWN_LOCATION, COMPONENT_REF,
    3525              :                                    orig_object, orig_name, NULL_TREE);
    3526     98125965 :           COMPONENT_REF_SPLICE_P (expr) = splice_p;
    3527     98125965 :           return expr;
    3528              :         }
    3529              :     }
    3530     32325243 :   else if (c_dialect_objc ()
    3531    105802221 :            && identifier_p (name)
    3532     32325243 :            && (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    105802221 :   if (!currently_open_class (object_type)
    3540    105802221 :       && !complete_type_or_maybe_complain (object_type, object, complain))
    3541          123 :     return error_mark_node;
    3542    105802098 :   if (!CLASS_TYPE_P (object_type))
    3543              :     {
    3544       270364 :       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       270364 :       return error_mark_node;
    3556              :     }
    3557              : 
    3558    105531734 :   if (BASELINK_P (name))
    3559              :     /* A member function that has already been looked up.  */
    3560              :     member = name;
    3561     94912988 :   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     94912942 :       bool is_template_id = false;
    3574     94912942 :       tree template_args = NULL_TREE;
    3575     94912942 :       tree scope = NULL_TREE;
    3576              : 
    3577     94912942 :       access_path = object_type;
    3578              : 
    3579     94912942 :       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     94911168 :       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     94912937 :       if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
    3613              :         {
    3614       431497 :           is_template_id = true;
    3615       431497 :           template_args = TREE_OPERAND (name, 1);
    3616       431497 :           name = TREE_OPERAND (name, 0);
    3617              : 
    3618       431497 :           if (splice_p
    3619       432190 :               && (DECL_FUNCTION_TEMPLATE_P (OVL_FIRST (name))
    3620           69 :                   || variable_template_p (name)))
    3621          231 :             scope = DECL_CONTEXT (OVL_FIRST (name));
    3622       842077 :           else if (!identifier_p (name))
    3623       410861 :             name = OVL_NAME (name);
    3624              :         }
    3625              : 
    3626     94912937 :       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     94912877 :       if (TREE_CODE (name) == BIT_NOT_EXPR)
    3707              :         {
    3708       247917 :           if (dependent_type_p (object_type))
    3709              :             /* The destructor isn't declared yet.  */
    3710        46468 :             goto dependent;
    3711       201449 :           member = lookup_destructor (object, scope, name, complain);
    3712              :         }
    3713     94664960 :       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     94664089 :           {
    3731     94664089 :             auto_diagnostic_group d;
    3732     94664089 :             access_failure_info afi;
    3733     94664089 :             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     73154302 :               push_deferring_access_checks (dk_no_check);
    3741     94664089 :             member = lookup_member (access_path, name, /*protect=*/1,
    3742              :                                     /*want_type=*/false, complain,
    3743              :                                     &afi);
    3744     94664089 :             if (processing_template_decl)
    3745     73154302 :               pop_deferring_access_checks ();
    3746     94664089 :             afi.maybe_suggest_accessor (TYPE_READONLY (object_type));
    3747     94664089 :           }
    3748     94664089 :           if (member == NULL_TREE)
    3749              :             {
    3750      9047610 :               if (dependentish_scope_p (object_type))
    3751              :                 /* Try again at instantiation time.  */
    3752      9031162 :                 goto dependent;
    3753        16448 :               if (complain & tf_error)
    3754          315 :                 complain_about_unrecognized_member (access_path, name,
    3755              :                                                     object_type);
    3756        16448 :               return error_mark_node;
    3757              :             }
    3758     85616479 :           if (member == error_mark_node)
    3759              :             return error_mark_node;
    3760     85616434 :           if (DECL_P (member)
    3761     85616434 :               && 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     85616428 :           if (TREE_CODE (member) == USING_DECL && DECL_DEPENDENT_P (member))
    3766      5085474 :             goto dependent;
    3767              :         }
    3768              : 
    3769     80733274 :       if (is_template_id)
    3770              :         {
    3771       431389 :           tree templ = member;
    3772              : 
    3773       431389 :           if (BASELINK_P (templ))
    3774       431256 :             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     91352020 :   if (TREE_UNAVAILABLE (member))
    3788           30 :     error_unavailable_use (member, NULL_TREE);
    3789     91351990 :   else if (TREE_DEPRECATED (member))
    3790           30 :     warn_deprecated_use (member, NULL_TREE);
    3791              : 
    3792     91352020 :   if (template_p)
    3793         9300 :     check_template_keyword (member);
    3794              : 
    3795     91352020 :   expr = build_class_member_access_expr (object, member, access_path,
    3796              :                                          /*preserve_reference=*/false,
    3797              :                                          complain);
    3798     91352020 :   if (processing_template_decl && expr != error_mark_node)
    3799              :     {
    3800     59313780 :       if (BASELINK_P (member))
    3801              :         {
    3802     44261072 :           if (TREE_CODE (orig_name) == SCOPE_REF)
    3803          172 :             BASELINK_QUALIFIED_P (member) = 1;
    3804              :           orig_name = member;
    3805              :         }
    3806     59313780 :       expr = build_min_non_dep (COMPONENT_REF, expr,
    3807              :                                 orig_object, orig_name,
    3808              :                                 NULL_TREE);
    3809    118627560 :       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       168814 : build_simple_component_ref (tree object, tree member)
    3820              : {
    3821       168814 :   tree type = cp_build_qualified_type (TREE_TYPE (member),
    3822       168814 :                                        cp_type_quals (TREE_TYPE (object)));
    3823       168814 :   return build3_loc (input_location,
    3824              :                      COMPONENT_REF, type,
    3825       168814 :                      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       168724 : build_ptrmemfunc_access_expr (tree ptrmem, tree member_name)
    3837              : {
    3838       168724 :   tree ptrmem_type;
    3839       168724 :   tree member;
    3840              : 
    3841       168724 :   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       168658 :   ptrmem_type = TREE_TYPE (ptrmem);
    3854       168658 :   gcc_assert (TYPE_PTRMEMFUNC_P (ptrmem_type));
    3855       252884 :   for (member = TYPE_FIELDS (ptrmem_type); member;
    3856        84226 :        member = DECL_CHAIN (member))
    3857       252884 :     if (DECL_NAME (member) == member_name)
    3858              :       break;
    3859       168658 :   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    137246627 : op_unqualified_lookup (tree_code code, bool is_assign)
    3867              : {
    3868    137246627 :   tree lookups = NULL_TREE;
    3869              : 
    3870    137246627 :   if (cxx_dialect >= cxx20 && !is_assign)
    3871              :     {
    3872    129649125 :       if (code == NE_EXPR)
    3873              :         {
    3874              :           /* != can get rewritten in terms of ==.  */
    3875      8293885 :           tree fnname = ovl_op_identifier (false, EQ_EXPR);
    3876      8293885 :           if (tree fns = lookup_name (fnname, LOOK_where::BLOCK_NAMESPACE))
    3877      8196438 :             lookups = tree_cons (fnname, fns, lookups);
    3878              :         }
    3879    121355240 :       else if (code == GT_EXPR || code == LE_EXPR
    3880    121355240 :                || code == LT_EXPR || code == GE_EXPR)
    3881              :         {
    3882              :           /* These can get rewritten in terms of <=>.  */
    3883     11260116 :           tree fnname = ovl_op_identifier (false, SPACESHIP_EXPR);
    3884     11260116 :           if (tree fns = lookup_name (fnname, LOOK_where::BLOCK_NAMESPACE))
    3885     10657261 :             lookups = tree_cons (fnname, fns, lookups);
    3886              :         }
    3887              :     }
    3888              : 
    3889    137246627 :   tree fnname = ovl_op_identifier (is_assign, code);
    3890    137246627 :   if (tree fns = lookup_name (fnname, LOOK_where::BLOCK_NAMESPACE))
    3891     74879558 :     lookups = tree_cons (fnname, fns, lookups);
    3892              : 
    3893    137246627 :   if (lookups)
    3894              :     return lookups;
    3895              :   else
    3896     62141233 :     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    143375668 : build_dependent_operator_type (tree lookups, tree_code code, bool is_assign)
    3905              : {
    3906    143375668 :   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      6129041 :     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    137246627 :   lookups = op_unqualified_lookup (code, is_assign);
    3916              : 
    3917    137246627 :   tree type = cxx_make_type (DEPENDENT_OPERATOR_TYPE);
    3918    137246627 :   DEPENDENT_OPERATOR_TYPE_SAVED_LOOKUPS (type) = lookups;
    3919    137246627 :   TREE_TYPE (lookups) = type;
    3920    137246627 :   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     49215504 : build_x_indirect_ref (location_t loc, tree expr, ref_operator errorstring,
    3932              :                       tree lookups, tsubst_flags_t complain)
    3933              : {
    3934     49215504 :   tree orig_expr = expr;
    3935     49215504 :   tree rval;
    3936     49215504 :   tree overload = NULL_TREE;
    3937              : 
    3938     49215504 :   if (processing_template_decl)
    3939              :     {
    3940              :       /* Retain the type if we know the operand is a pointer.  */
    3941     28825038 :       if (TREE_TYPE (expr) && INDIRECT_TYPE_P (TREE_TYPE (expr)))
    3942              :         {
    3943     14149755 :           if (expr == current_class_ptr
    3944     14149755 :               || (TREE_CODE (expr) == NOP_EXPR
    3945      9341454 :                   && TREE_OPERAND (expr, 0) == current_class_ptr
    3946      9231409 :                   && (same_type_ignoring_top_level_qualifiers_p
    3947      9231409 :                         (TREE_TYPE (expr), TREE_TYPE (current_class_ptr)))))
    3948      9231408 :             return current_class_ref;
    3949      4918347 :           return build_min (INDIRECT_REF, TREE_TYPE (TREE_TYPE (expr)), expr);
    3950              :         }
    3951     14675283 :       if (type_dependent_expression_p (expr))
    3952              :         {
    3953     14540002 :           expr = build_min_nt_loc (loc, INDIRECT_REF, expr);
    3954     14540002 :           TREE_TYPE (expr)
    3955     14540002 :             = build_dependent_operator_type (lookups, INDIRECT_REF, false);
    3956     14540002 :           return expr;
    3957              :         }
    3958              :     }
    3959              : 
    3960     20525747 :   rval = build_new_op (loc, INDIRECT_REF, LOOKUP_NORMAL, expr,
    3961              :                        NULL_TREE, NULL_TREE, lookups,
    3962              :                        &overload, complain);
    3963     20525747 :   if (!rval)
    3964            0 :     rval = cp_build_indirect_ref (loc, expr, errorstring, complain);
    3965              : 
    3966     20525747 :   if (processing_template_decl && rval != error_mark_node)
    3967              :     {
    3968       133448 :       if (overload != NULL_TREE)
    3969       133417 :         return (build_min_non_dep_op_overload
    3970       133417 :                 (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       645803 : cp_strict_aliasing_warning (location_t loc, tree type, tree expr)
    3983              : {
    3984       645803 :   if (processing_template_decl)
    3985              :     {
    3986        45577 :       tree e = expr;
    3987        45577 :       STRIP_NOPS (e);
    3988        45577 :       if (dependent_type_p (type) || type_dependent_expression_p (e))
    3989         7412 :         return false;
    3990              :     }
    3991       638391 :   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    349395095 : cp_build_indirect_ref_1 (location_t loc, tree ptr, ref_operator errorstring,
    3999              :                          tsubst_flags_t complain, bool do_fold)
    4000              : {
    4001    349395095 :   tree pointer, type;
    4002              : 
    4003              :   /* RO_NULL should only be used with the folding entry points below, not
    4004              :      cp_build_indirect_ref.  */
    4005    349395095 :   gcc_checking_assert (errorstring != RO_NULL || do_fold);
    4006              : 
    4007    349395095 :   if (ptr == current_class_ptr
    4008    349395095 :       || (TREE_CODE (ptr) == NOP_EXPR
    4009     37214916 :           && TREE_OPERAND (ptr, 0) == current_class_ptr
    4010     19741614 :           && (same_type_ignoring_top_level_qualifiers_p
    4011     19741614 :               (TREE_TYPE (ptr), TREE_TYPE (current_class_ptr)))))
    4012     21167690 :     return current_class_ref;
    4013              : 
    4014    328227405 :   pointer = (TYPE_REF_P (TREE_TYPE (ptr))
    4015    328227405 :              ? ptr : decay_conversion (ptr, complain));
    4016    328227405 :   if (pointer == error_mark_node)
    4017              :     return error_mark_node;
    4018              : 
    4019    328221576 :   type = TREE_TYPE (pointer);
    4020              : 
    4021    328221576 :   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    328221038 :       tree t = TREE_TYPE (type);
    4028              : 
    4029    309490941 :       if ((CONVERT_EXPR_P (ptr)
    4030    226745085 :            || TREE_CODE (ptr) == VIEW_CONVERT_EXPR)
    4031    413270476 :           && (!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     81337148 :           if (warn_strict_aliasing > 2
    4037     81883085 :               && cp_strict_aliasing_warning (EXPR_LOCATION (ptr),
    4038       545937 :                                              type, TREE_OPERAND (ptr, 0)))
    4039            6 :             suppress_warning (ptr, OPT_Wstrict_aliasing);
    4040              :         }
    4041              : 
    4042    328221038 :       if (VOID_TYPE_P (t))
    4043              :         {
    4044              :           /* A pointer to incomplete type (other than cv void) can be
    4045              :              dereferenced [expr.unary.op]/1  */
    4046           48 :           if (complain & tf_error)
    4047           19 :             error_at (loc, "%qT is not a pointer-to-object type", type);
    4048           48 :           return error_mark_node;
    4049              :         }
    4050    317772032 :       else if (do_fold && TREE_CODE (pointer) == ADDR_EXPR
    4051    335376543 :                && 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      7155514 :         return TREE_OPERAND (pointer, 0);
    4057              :       else
    4058              :         {
    4059    321065476 :           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    321065476 :           TREE_READONLY (ref) = CP_TYPE_CONST_P (t);
    4065    321065476 :           TREE_THIS_VOLATILE (ref) = CP_TYPE_VOLATILE_P (t);
    4066    321065476 :           TREE_SIDE_EFFECTS (ref)
    4067    321065476 :             = (TREE_THIS_VOLATILE (ref) || TREE_SIDE_EFFECTS (pointer));
    4068    321065476 :           return ref;
    4069              :         }
    4070              :     }
    4071          538 :   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          538 :   return error_mark_node;
    4101              : }
    4102              : 
    4103              : /* Entry point used by c-common, which expects folding.  */
    4104              : 
    4105              : tree
    4106        68047 : build_indirect_ref (location_t loc, tree ptr, ref_operator errorstring)
    4107              : {
    4108        68047 :   return cp_build_indirect_ref_1 (loc, ptr, errorstring,
    4109        68047 :                                   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    321393156 : cp_build_fold_indirect_ref (tree pointer)
    4117              : {
    4118    321393156 :   return cp_build_indirect_ref_1 (input_location, pointer, RO_NULL,
    4119    321393156 :                                   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     27933892 : cp_build_indirect_ref (location_t loc, tree ptr, ref_operator errorstring,
    4127              :                        tsubst_flags_t complain)
    4128              : {
    4129     27933892 :   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      5910886 : cp_build_array_ref (location_t loc, tree array, tree idx,
    4149              :                     tsubst_flags_t complain)
    4150              : {
    4151      5910886 :   tree ret;
    4152              : 
    4153      5910886 :   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      5910886 :   if (TREE_TYPE (array) == error_mark_node
    4161      5910886 :       || TREE_TYPE (idx) == error_mark_node)
    4162              :     return error_mark_node;
    4163              : 
    4164              :   /* 0[array] */
    4165      5910886 :   if (TREE_CODE (TREE_TYPE (idx)) == ARRAY_TYPE
    4166      5910886 :       && TREE_CODE (TREE_TYPE (array)) != ARRAY_TYPE)
    4167              :     {
    4168           10 :       std::swap (array, idx);
    4169              : 
    4170           10 :       tree first = NULL_TREE;
    4171           10 :       if (flag_strong_eval_order == 2 && TREE_SIDE_EFFECTS (array))
    4172            9 :         idx = first = save_expr (idx);
    4173           10 :       ret = cp_build_array_ref (loc, array, idx, complain);
    4174              : 
    4175           10 :       if (first)
    4176            9 :         ret = build2 (COMPOUND_EXPR, TREE_TYPE (ret), first, ret);
    4177           10 :       return ret;
    4178              :     }
    4179              : 
    4180              :   /* If ARRAY is a COMPOUND_EXPR or COND_EXPR, move our reference
    4181              :      inside it.  */
    4182      5910876 :   switch (TREE_CODE (array))
    4183              :     {
    4184           28 :     case COMPOUND_EXPR:
    4185           28 :       {
    4186           28 :         tree value = cp_build_array_ref (loc, TREE_OPERAND (array, 1), idx,
    4187              :                                          complain);
    4188           28 :         ret = build2 (COMPOUND_EXPR, TREE_TYPE (value),
    4189           28 :                       TREE_OPERAND (array, 0), value);
    4190           28 :         SET_EXPR_LOCATION (ret, loc);
    4191           28 :         return ret;
    4192              :       }
    4193              : 
    4194           73 :     case COND_EXPR:
    4195           73 :       tree op0, op1, op2;
    4196           73 :       op0 = TREE_OPERAND (array, 0);
    4197           73 :       op1 = TREE_OPERAND (array, 1);
    4198           73 :       op2 = TREE_OPERAND (array, 2);
    4199           73 :       if (TREE_SIDE_EFFECTS (idx) || !tree_invariant_p (idx))
    4200              :         {
    4201              :           /* If idx could possibly have some SAVE_EXPRs, turning
    4202              :              (op0 ? op1 : op2)[idx] into
    4203              :              op0 ? op1[idx] : op2[idx] can lead into temporaries
    4204              :              initialized in one conditional path and uninitialized
    4205              :              uses of them in the other path.
    4206              :              And if idx is a really large expression, evaluating it
    4207              :              twice is also not optimal.
    4208              :              On the other side, op0 must be sequenced before evaluation
    4209              :              of op1 and op2 and for C++17 op0, op1 and op2 must be
    4210              :              sequenced before idx.
    4211              :              If idx is INTEGER_CST, we can just do the optimization
    4212              :              without any SAVE_EXPRs, if op1 and op2 are both ARRAY_TYPE
    4213              :              VAR_DECLs or COMPONENT_REFs thereof (so their address
    4214              :              is constant or relative to frame), optimize into
    4215              :              (SAVE_EXPR <op0>, SAVE_EXPR <idx>, SAVE_EXPR <op0>)
    4216              :              ? op1[SAVE_EXPR <idx>] : op2[SAVE_EXPR <idx>]
    4217              :              Otherwise avoid this optimization.  */
    4218           58 :           if (flag_strong_eval_order == 2)
    4219              :             {
    4220           39 :               if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE)
    4221              :                 {
    4222           30 :                   if (!address_invariant_p (op1) || !address_invariant_p (op2))
    4223              :                     {
    4224              :                       /* Force default conversion on array if
    4225              :                          we can't optimize this and array is ARRAY_TYPE
    4226              :                          COND_EXPR, we can't leave COND_EXPRs with
    4227              :                          ARRAY_TYPE in the IL.  */
    4228            8 :                       array = cp_default_conversion (array, complain);
    4229            8 :                       if (error_operand_p (array))
    4230            0 :                         return error_mark_node;
    4231              :                       break;
    4232              :                     }
    4233              :                 }
    4234           16 :               else if (!POINTER_TYPE_P (TREE_TYPE (array))
    4235            2 :                        || !tree_invariant_p (op1)
    4236           11 :                        || !tree_invariant_p (op2))
    4237              :                 break;
    4238              :             }
    4239           43 :           if (TREE_SIDE_EFFECTS (idx))
    4240              :             {
    4241           18 :               idx = save_expr (idx);
    4242           18 :               op0 = save_expr (op0);
    4243           18 :               warning_sentinel w (warn_unused_value);
    4244           18 :               tree tem = build_compound_expr (loc, op0, idx);
    4245           18 :               op0 = build_compound_expr (loc, tem, op0);
    4246           18 :             }
    4247              :         }
    4248           58 :       op1 = cp_build_array_ref (loc, op1, idx, complain);
    4249           58 :       op2 = cp_build_array_ref (loc, op2, idx, complain);
    4250           58 :       ret = build_conditional_expr (loc, op0, op1, op2, complain);
    4251           58 :       protected_set_expr_location (ret, loc);
    4252           58 :       return ret;
    4253              : 
    4254              :     default:
    4255              :       break;
    4256              :     }
    4257              : 
    4258      5910790 :   bool non_lvalue = convert_vector_to_array_for_subscript (loc, &array, idx);
    4259              : 
    4260      5910790 :   if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE)
    4261              :     {
    4262      1801620 :       tree rval, type;
    4263              : 
    4264      1801620 :       warn_array_subscript_with_type_char (loc, idx);
    4265              : 
    4266      1801620 :       if (!INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (idx)))
    4267              :         {
    4268            6 :           if (complain & tf_error)
    4269            6 :             error_at (loc, "array subscript is not an integer");
    4270            6 :           return error_mark_node;
    4271              :         }
    4272              : 
    4273              :       /* Apply integral promotions *after* noticing character types.
    4274              :          (It is unclear why we do these promotions -- the standard
    4275              :          does not say that we should.  In fact, the natural thing would
    4276              :          seem to be to convert IDX to ptrdiff_t; we're performing
    4277              :          pointer arithmetic.)  */
    4278      1801614 :       idx = cp_perform_integral_promotions (idx, complain);
    4279              : 
    4280      1801614 :       idx = maybe_fold_non_dependent_expr (idx, complain);
    4281              : 
    4282              :       /* An array that is indexed by a non-constant
    4283              :          cannot be stored in a register; we must be able to do
    4284              :          address arithmetic on its address.
    4285              :          Likewise an array of elements of variable size.  */
    4286      1801614 :       if (TREE_CODE (idx) != INTEGER_CST
    4287      1801614 :           || (COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (array)))
    4288       854950 :               && (TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))))
    4289              :                   != INTEGER_CST)))
    4290              :         {
    4291       947924 :           if (!cxx_mark_addressable (array, true))
    4292            0 :             return error_mark_node;
    4293              :         }
    4294              : 
    4295              :       /* An array that is indexed by a constant value which is not within
    4296              :          the array bounds cannot be stored in a register either; because we
    4297              :          would get a crash in store_bit_field/extract_bit_field when trying
    4298              :          to access a non-existent part of the register.  */
    4299      1801614 :       if (TREE_CODE (idx) == INTEGER_CST
    4300       854953 :           && TYPE_DOMAIN (TREE_TYPE (array))
    4301      2655184 :           && ! int_fits_type_p (idx, TYPE_DOMAIN (TREE_TYPE (array))))
    4302              :         {
    4303         3019 :           if (!cxx_mark_addressable (array))
    4304            0 :             return error_mark_node;
    4305              :         }
    4306              : 
    4307              :       /* Note in C++ it is valid to subscript a `register' array, since
    4308              :          it is valid to take the address of something with that
    4309              :          storage specification.  */
    4310      1801614 :       if (extra_warnings)
    4311              :         {
    4312        38844 :           tree foo = array;
    4313        59524 :           while (TREE_CODE (foo) == COMPONENT_REF)
    4314        20680 :             foo = TREE_OPERAND (foo, 0);
    4315            8 :           if (VAR_P (foo) && DECL_REGISTER (foo)
    4316        38844 :               && (complain & tf_warning))
    4317            0 :             warning_at (loc, OPT_Wextra,
    4318              :                         "subscripting array declared %<register%>");
    4319              :         }
    4320              : 
    4321      1801614 :       type = TREE_TYPE (TREE_TYPE (array));
    4322      1801614 :       rval = build4 (ARRAY_REF, type, array, idx, NULL_TREE, NULL_TREE);
    4323              :       /* Array ref is const/volatile if the array elements are
    4324              :          or if the array is..  */
    4325      5404842 :       TREE_READONLY (rval)
    4326      1801614 :         |= (CP_TYPE_CONST_P (type) | TREE_READONLY (array));
    4327      5404842 :       TREE_SIDE_EFFECTS (rval)
    4328      1801614 :         |= (CP_TYPE_VOLATILE_P (type) | TREE_SIDE_EFFECTS (array));
    4329      3603228 :       TREE_THIS_VOLATILE (rval)
    4330      1801614 :         |= (CP_TYPE_VOLATILE_P (type) | TREE_THIS_VOLATILE (array));
    4331      1801614 :       ret = require_complete_type (rval, complain);
    4332      1801614 :       protected_set_expr_location (ret, loc);
    4333      1801614 :       if (non_lvalue)
    4334        19966 :         ret = non_lvalue_loc (loc, ret);
    4335      1801614 :       return ret;
    4336              :     }
    4337              : 
    4338      4109170 :   {
    4339      4109170 :     tree ar = cp_default_conversion (array, complain);
    4340      4109170 :     tree ind = cp_default_conversion (idx, complain);
    4341      4109170 :     tree first = NULL_TREE;
    4342              : 
    4343      2638895 :     if (!processing_template_decl && flag_strong_eval_order == 2
    4344      6706362 :         && TREE_SIDE_EFFECTS (ind))
    4345        81579 :       ar = first = save_expr (ar);
    4346              : 
    4347              :     /* Put the integer in IND to simplify error checking.  */
    4348      4109170 :     if (TREE_CODE (TREE_TYPE (ar)) == INTEGER_TYPE)
    4349           57 :       std::swap (ar, ind);
    4350              : 
    4351      4109170 :     if (ar == error_mark_node || ind == error_mark_node)
    4352              :       return error_mark_node;
    4353              : 
    4354      4109170 :     if (!TYPE_PTR_P (TREE_TYPE (ar)))
    4355              :       {
    4356           33 :         if (complain & tf_error)
    4357            3 :           error_at (loc, "subscripted value is neither array nor pointer");
    4358           33 :         return error_mark_node;
    4359              :       }
    4360      4109137 :     if (TREE_CODE (TREE_TYPE (ind)) != INTEGER_TYPE)
    4361              :       {
    4362            0 :         if (complain & tf_error)
    4363            0 :           error_at (loc, "array subscript is not an integer");
    4364            0 :         return error_mark_node;
    4365              :       }
    4366              : 
    4367      4109137 :     warn_array_subscript_with_type_char (loc, idx);
    4368              : 
    4369      4109137 :     ret = cp_build_binary_op (input_location, PLUS_EXPR, ar, ind, complain);
    4370      4109137 :     if (first)
    4371        81579 :       ret = build2_loc (loc, COMPOUND_EXPR, TREE_TYPE (ret), first, ret);
    4372      4109137 :     ret = cp_build_indirect_ref (loc, ret, RO_ARRAY_INDEXING, complain);
    4373      4109137 :     protected_set_expr_location (ret, loc);
    4374      4109137 :     if (non_lvalue)
    4375            0 :       ret = non_lvalue_loc (loc, ret);
    4376              :     return ret;
    4377              :   }
    4378              : }
    4379              : 
    4380              : /* Entry point for Obj-C++.  */
    4381              : 
    4382              : tree
    4383      3639133 : build_array_ref (location_t loc, tree array, tree idx)
    4384              : {
    4385      3639133 :   return cp_build_array_ref (loc, array, idx, tf_warning_or_error);
    4386              : }
    4387              : 
    4388              : /* Resolve a pointer to member function.  INSTANCE is the object
    4389              :    instance to use, if the member points to a virtual member.
    4390              : 
    4391              :    This used to avoid checking for virtual functions if basetype
    4392              :    has no virtual functions, according to an earlier ANSI draft.
    4393              :    With the final ISO C++ rules, such an optimization is
    4394              :    incorrect: A pointer to a derived member can be static_cast
    4395              :    to pointer-to-base-member, as long as the dynamic object
    4396              :    later has the right member.  So now we only do this optimization
    4397              :    when we know the dynamic type of the object.  */
    4398              : 
    4399              : tree
    4400        84095 : get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function,
    4401              :                                   tsubst_flags_t complain)
    4402              : {
    4403        84095 :   if (TREE_CODE (function) == OFFSET_REF)
    4404            0 :     function = TREE_OPERAND (function, 1);
    4405              : 
    4406        84095 :   if (TYPE_PTRMEMFUNC_P (TREE_TYPE (function)))
    4407              :     {
    4408        84095 :       tree idx, delta, e1, e2, e3, vtbl;
    4409        84095 :       bool nonvirtual;
    4410        84095 :       tree fntype = TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (function));
    4411        84095 :       tree basetype = TYPE_METHOD_BASETYPE (TREE_TYPE (fntype));
    4412              : 
    4413        84095 :       tree instance_ptr = *instance_ptrptr;
    4414        84095 :       tree instance_save_expr = 0;
    4415        84095 :       if (instance_ptr == error_mark_node)
    4416              :         {
    4417            0 :           if (TREE_CODE (function) == PTRMEM_CST)
    4418              :             {
    4419              :               /* Extracting the function address from a pmf is only
    4420              :                  allowed with -Wno-pmf-conversions. It only works for
    4421              :                  pmf constants.  */
    4422            0 :               e1 = build_addr_func (PTRMEM_CST_MEMBER (function), complain);
    4423            0 :               e1 = convert (fntype, e1);
    4424            0 :               return e1;
    4425              :             }
    4426              :           else
    4427              :             {
    4428            0 :               if (complain & tf_error)
    4429            0 :                 error ("object missing in use of %qE", function);
    4430            0 :               return error_mark_node;
    4431              :             }
    4432              :         }
    4433              : 
    4434              :       /* True if we know that the dynamic type of the object doesn't have
    4435              :          virtual functions, so we can assume the PFN field is a pointer.  */
    4436        84095 :       nonvirtual = (COMPLETE_TYPE_P (basetype)
    4437        84059 :                     && !TYPE_POLYMORPHIC_P (basetype)
    4438       113026 :                     && resolves_to_fixed_type_p (instance_ptr, 0));
    4439              : 
    4440              :       /* If we don't really have an object (i.e. in an ill-formed
    4441              :          conversion from PMF to pointer), we can't resolve virtual
    4442              :          functions anyway.  */
    4443        83843 :       if (!nonvirtual && is_dummy_object (instance_ptr))
    4444              :         nonvirtual = true;
    4445              : 
    4446              :       /* Use force_target_expr even when instance_ptr doesn't have
    4447              :          side-effects, unless it is a simple decl or constant, so
    4448              :          that we don't ubsan instrument the expression multiple times.
    4449              :          Don't use save_expr, as save_expr can avoid building a SAVE_EXPR
    4450              :          and building a SAVE_EXPR manually can be optimized away during
    4451              :          cp_fold.  See PR116449 and PR117259.  */
    4452        84095 :       if (TREE_SIDE_EFFECTS (instance_ptr)
    4453        84095 :           || (!nonvirtual
    4454        46921 :               && !DECL_P (instance_ptr)
    4455        46921 :               && !TREE_CONSTANT (instance_ptr)))
    4456        83561 :         instance_ptr = instance_save_expr
    4457        83561 :           = get_internal_target_expr (instance_ptr);
    4458              : 
    4459              :       /* See above comment.  */
    4460        84095 :       if (TREE_SIDE_EFFECTS (function)
    4461        84095 :           || (!nonvirtual
    4462        65217 :               && !DECL_P (function)
    4463        65205 :               && !TREE_CONSTANT (function)))
    4464        83642 :         function = get_internal_target_expr (function);
    4465              : 
    4466              :       /* Start by extracting all the information from the PMF itself.  */
    4467        84095 :       e3 = pfn_from_ptrmemfunc (function);
    4468        84095 :       delta = delta_from_ptrmemfunc (function);
    4469        84095 :       idx = build1 (NOP_EXPR, vtable_index_type, e3);
    4470        84095 :       switch (TARGET_PTRMEMFUNC_VBIT_LOCATION)
    4471              :         {
    4472        84095 :           sanitize_code_type flag_sanitize_save;
    4473        84095 :         case ptrmemfunc_vbit_in_pfn:
    4474        84095 :           e1 = cp_build_binary_op (input_location,
    4475              :                                    BIT_AND_EXPR, idx, integer_one_node,
    4476              :                                    complain);
    4477        84095 :           idx = cp_build_binary_op (input_location,
    4478              :                                     MINUS_EXPR, idx, integer_one_node,
    4479              :                                     complain);
    4480        84095 :           if (idx == error_mark_node)
    4481              :             return error_mark_node;
    4482        84095 :           break;
    4483              : 
    4484              :         case ptrmemfunc_vbit_in_delta:
    4485              :           e1 = cp_build_binary_op (input_location,
    4486              :                                    BIT_AND_EXPR, delta, integer_one_node,
    4487              :                                    complain);
    4488              :           /* Don't instrument the RSHIFT_EXPR we're about to create because
    4489              :              we're going to use DELTA number of times, and that wouldn't play
    4490              :              well with SAVE_EXPRs therein.  */
    4491              :           flag_sanitize_save = flag_sanitize;
    4492              :           flag_sanitize = 0;
    4493              :           delta = cp_build_binary_op (input_location,
    4494              :                                       RSHIFT_EXPR, delta, integer_one_node,
    4495              :                                       complain);
    4496              :           flag_sanitize = flag_sanitize_save;
    4497              :           if (delta == error_mark_node)
    4498              :             return error_mark_node;
    4499              :           break;
    4500              : 
    4501              :         default:
    4502              :           gcc_unreachable ();
    4503              :         }
    4504              : 
    4505        84095 :       if (e1 == error_mark_node)
    4506              :         return error_mark_node;
    4507              : 
    4508              :       /* Convert down to the right base before using the instance.  A
    4509              :          special case is that in a pointer to member of class C, C may
    4510              :          be incomplete.  In that case, the function will of course be
    4511              :          a member of C, and no conversion is required.  In fact,
    4512              :          lookup_base will fail in that case, because incomplete
    4513              :          classes do not have BINFOs.  */
    4514        84095 :       if (!same_type_ignoring_top_level_qualifiers_p
    4515        84095 :           (basetype, TREE_TYPE (TREE_TYPE (instance_ptr))))
    4516              :         {
    4517           81 :           basetype = lookup_base (TREE_TYPE (TREE_TYPE (instance_ptr)),
    4518              :                                   basetype, ba_check, NULL, complain);
    4519           81 :           instance_ptr = build_base_path (PLUS_EXPR, instance_ptr, basetype,
    4520              :                                           1, complain);
    4521           81 :           if (instance_ptr == error_mark_node)
    4522              :             return error_mark_node;
    4523              :         }
    4524              :       /* ...and then the delta in the PMF.  */
    4525        84095 :       instance_ptr = fold_build_pointer_plus (instance_ptr, delta);
    4526              : 
    4527              :       /* Hand back the adjusted 'this' argument to our caller.  */
    4528        84095 :       *instance_ptrptr = instance_ptr;
    4529              : 
    4530        84095 :       if (nonvirtual)
    4531              :         /* Now just return the pointer.  */
    4532              :         return e3;
    4533              : 
    4534              :       /* Next extract the vtable pointer from the object.  */
    4535        83825 :       vtbl = build1 (NOP_EXPR, build_pointer_type (vtbl_ptr_type_node),
    4536              :                      instance_ptr);
    4537        83825 :       vtbl = cp_build_fold_indirect_ref (vtbl);
    4538        83825 :       if (vtbl == error_mark_node)
    4539              :         return error_mark_node;
    4540              : 
    4541              :       /* Finally, extract the function pointer from the vtable.  */
    4542        83825 :       e2 = fold_build_pointer_plus_loc (input_location, vtbl, idx);
    4543        83825 :       e2 = cp_build_fold_indirect_ref (e2);
    4544        83825 :       if (e2 == error_mark_node)
    4545              :         return error_mark_node;
    4546        83825 :       TREE_CONSTANT (e2) = 1;
    4547              : 
    4548              :       /* When using function descriptors, the address of the
    4549              :          vtable entry is treated as a function pointer.  */
    4550        83825 :       if (TARGET_VTABLE_USES_DESCRIPTORS)
    4551              :         e2 = build1 (NOP_EXPR, TREE_TYPE (e2),
    4552              :                      cp_build_addr_expr (e2, complain));
    4553              : 
    4554        83825 :       e2 = fold_convert (TREE_TYPE (e3), e2);
    4555        83825 :       e1 = build_conditional_expr (input_location, e1, e2, e3, complain);
    4556        83825 :       if (e1 == error_mark_node)
    4557              :         return error_mark_node;
    4558              : 
    4559              :       /* Make sure this doesn't get evaluated first inside one of the
    4560              :          branches of the COND_EXPR.  */
    4561        83825 :       if (instance_save_expr)
    4562        83513 :         e1 = build2 (COMPOUND_EXPR, TREE_TYPE (e1),
    4563              :                      instance_save_expr, e1);
    4564              : 
    4565              :       function = e1;
    4566              :     }
    4567              :   return function;
    4568              : }
    4569              : 
    4570              : /* Used by the C-common bits.  */
    4571              : tree
    4572            0 : build_function_call (location_t /*loc*/,
    4573              :                      tree function, tree params)
    4574              : {
    4575            0 :   return cp_build_function_call (function, params, tf_warning_or_error);
    4576              : }
    4577              : 
    4578              : /* Used by the C-common bits.  */
    4579              : tree
    4580       331837 : build_function_call_vec (location_t /*loc*/, vec<location_t> /*arg_loc*/,
    4581              :                          tree function, vec<tree, va_gc> *params,
    4582              :                          vec<tree, va_gc> * /*origtypes*/, tree orig_function)
    4583              : {
    4584       331837 :   vec<tree, va_gc> *orig_params = params;
    4585       331837 :   tree ret = cp_build_function_call_vec (function, &params,
    4586              :                                          tf_warning_or_error, orig_function);
    4587              : 
    4588              :   /* cp_build_function_call_vec can reallocate PARAMS by adding
    4589              :      default arguments.  That should never happen here.  Verify
    4590              :      that.  */
    4591       331837 :   gcc_assert (params == orig_params);
    4592              : 
    4593       331837 :   return ret;
    4594              : }
    4595              : 
    4596              : /* Build a function call using a tree list of arguments.  */
    4597              : 
    4598              : static tree
    4599            0 : cp_build_function_call (tree function, tree params, tsubst_flags_t complain)
    4600              : {
    4601            0 :   tree ret;
    4602              : 
    4603            0 :   releasing_vec vec;
    4604            0 :   for (; params != NULL_TREE; params = TREE_CHAIN (params))
    4605            0 :     vec_safe_push (vec, TREE_VALUE (params));
    4606            0 :   ret = cp_build_function_call_vec (function, &vec, complain);
    4607            0 :   return ret;
    4608            0 : }
    4609              : 
    4610              : /* Build a function call using varargs.  */
    4611              : 
    4612              : tree
    4613       558309 : cp_build_function_call_nary (tree function, tsubst_flags_t complain, ...)
    4614              : {
    4615       558309 :   va_list args;
    4616       558309 :   tree ret, t;
    4617              : 
    4618       558309 :   releasing_vec vec;
    4619       558309 :   va_start (args, complain);
    4620      1391278 :   for (t = va_arg (args, tree); t != NULL_TREE; t = va_arg (args, tree))
    4621       832969 :     vec_safe_push (vec, t);
    4622       558309 :   va_end (args);
    4623       558309 :   ret = cp_build_function_call_vec (function, &vec, complain);
    4624       558309 :   return ret;
    4625       558309 : }
    4626              : 
    4627              : /* C++ implementation of callback for use when checking param types.  */
    4628              : 
    4629              : bool
    4630           18 : cp_comp_parm_types (tree wanted_type, tree actual_type)
    4631              : {
    4632           18 :   if (TREE_CODE (wanted_type) == POINTER_TYPE
    4633           18 :       && TREE_CODE (actual_type) == POINTER_TYPE)
    4634           15 :     return same_or_base_type_p (TREE_TYPE (wanted_type),
    4635              :                                 TREE_TYPE (actual_type));
    4636              :   return false;
    4637              : }
    4638              : 
    4639              : /* Build a function call using a vector of arguments.
    4640              :    If FUNCTION is the result of resolving an overloaded target built-in,
    4641              :    ORIG_FNDECL is the original function decl, otherwise it is null.
    4642              :    PARAMS may be NULL if there are no parameters.  This changes the
    4643              :    contents of PARAMS.  */
    4644              : 
    4645              : tree
    4646      7290395 : cp_build_function_call_vec (tree function, vec<tree, va_gc> **params,
    4647              :                             tsubst_flags_t complain, tree orig_fndecl)
    4648              : {
    4649      7290395 :   tree fntype, fndecl;
    4650      7290395 :   int is_method;
    4651      7290395 :   tree original = function;
    4652      7290395 :   int nargs;
    4653      7290395 :   tree *argarray;
    4654      7290395 :   tree parm_types;
    4655      7290395 :   vec<tree, va_gc> *allocated = NULL;
    4656      7290395 :   tree ret;
    4657              : 
    4658              :   /* For Objective-C, convert any calls via a cast to OBJC_TYPE_REF
    4659              :      expressions, like those used for ObjC messenger dispatches.  */
    4660      7290395 :   if (params != NULL && !vec_safe_is_empty (*params))
    4661      2096959 :     function = objc_rewrite_function_call (function, (**params)[0]);
    4662              : 
    4663              :   /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
    4664              :      Strip such NOP_EXPRs, since FUNCTION is used in non-lvalue context.  */
    4665      7290395 :   if (TREE_CODE (function) == NOP_EXPR
    4666      7290395 :       && TREE_TYPE (function) == TREE_TYPE (TREE_OPERAND (function, 0)))
    4667           15 :     function = TREE_OPERAND (function, 0);
    4668              : 
    4669      7290395 :   if (TREE_CODE (function) == FUNCTION_DECL)
    4670              :     {
    4671      1571617 :       if (!mark_used (function, complain))
    4672           24 :         return error_mark_node;
    4673      1571593 :       fndecl = function;
    4674              : 
    4675              :       /* For target_version semantics, the function set cannot be called
    4676              :          if there is no default version in scope.  */
    4677      1571593 :       if (!TARGET_HAS_FMV_TARGET_ATTRIBUTE
    4678              :            && !is_function_default_version (fndecl))
    4679              :          {
    4680              :            if (complain & tf_error)
    4681              :             error ("no default version in scope");
    4682              :            return error_mark_node;
    4683              :          }
    4684              : 
    4685              :       /* Convert anything with function type to a pointer-to-function.  */
    4686      1571593 :       if (DECL_MAIN_P (function))
    4687              :         {
    4688            0 :           if (complain & tf_error)
    4689            0 :             pedwarn (input_location, OPT_Wpedantic,
    4690              :                      "ISO C++ forbids calling %<::main%> from within program");
    4691              :           else
    4692            0 :             return error_mark_node;
    4693              :         }
    4694      1571593 :       function = build_addr_func (function, complain);
    4695              :     }
    4696              :   else
    4697              :     {
    4698      5718778 :       fndecl = NULL_TREE;
    4699              : 
    4700      5718778 :       function = build_addr_func (function, complain);
    4701              :     }
    4702              : 
    4703      7290371 :   if (function == error_mark_node)
    4704              :     return error_mark_node;
    4705              : 
    4706      7290269 :   fntype = TREE_TYPE (function);
    4707              : 
    4708      7290269 :   if (TYPE_PTRMEMFUNC_P (fntype))
    4709              :     {
    4710           15 :       if (complain & tf_error)
    4711           15 :         error ("must use %<.*%> or %<->*%> to call pointer-to-member "
    4712              :                "function in %<%E (...)%>, e.g. %<(... ->* %E) (...)%>",
    4713              :                original, original);
    4714           15 :       return error_mark_node;
    4715              :     }
    4716              : 
    4717     14580508 :   is_method = (TYPE_PTR_P (fntype)
    4718      7290254 :                && TREE_CODE (TREE_TYPE (fntype)) == METHOD_TYPE);
    4719              : 
    4720      7290254 :   if (!(TYPE_PTRFN_P (fntype)
    4721        85800 :         || is_method
    4722         1762 :         || TREE_CODE (function) == TEMPLATE_ID_EXPR))
    4723              :     {
    4724         1762 :       if (complain & tf_error)
    4725              :         {
    4726          176 :           if (is_stub_object (original))
    4727            3 :             error_at (input_location,
    4728              :                       "%qT cannot be used as a function",
    4729            3 :                       TREE_TYPE (original));
    4730          173 :           else if (!flag_diagnostics_show_caret)
    4731          173 :             error_at (input_location,
    4732              :                       "%qE cannot be used as a function", original);
    4733            0 :           else if (DECL_P (original))
    4734            0 :             error_at (input_location,
    4735              :                       "%qD cannot be used as a function", original);
    4736              :           else
    4737            0 :             error_at (input_location,
    4738              :                       "expression cannot be used as a function");
    4739              :         }
    4740              : 
    4741         1762 :       return error_mark_node;
    4742              :     }
    4743              : 
    4744              :   /* fntype now gets the type of function pointed to.  */
    4745      7288492 :   fntype = TREE_TYPE (fntype);
    4746      7288492 :   parm_types = TYPE_ARG_TYPES (fntype);
    4747              : 
    4748      7288492 :   if (params == NULL)
    4749              :     {
    4750       151475 :       allocated = make_tree_vector ();
    4751       151475 :       params = &allocated;
    4752              :     }
    4753              : 
    4754      7288492 :     nargs = convert_arguments (parm_types, params, fndecl, LOOKUP_NORMAL,
    4755              :                                complain);
    4756      7288492 :   if (nargs < 0)
    4757         1889 :     return error_mark_node;
    4758              : 
    4759      7286603 :   argarray = (*params)->address ();
    4760              : 
    4761              :   /* Check for errors in format strings and inappropriately
    4762              :      null parameters.  */
    4763      7286603 :   bool warned_p
    4764      7286603 :     = ((complain & tf_warning)
    4765      7286603 :        && check_function_arguments (input_location, fndecl, fntype,
    4766              :                                     nargs, argarray, NULL,
    4767      7286603 :                                     cp_comp_parm_types));
    4768              : 
    4769      7286603 :   ret = build_cxx_call (function, nargs, argarray, complain, orig_fndecl);
    4770              : 
    4771      7286603 :   if (warned_p)
    4772              :     {
    4773           27 :       tree c = extract_call_expr (ret);
    4774           27 :       if (TREE_CODE (c) == CALL_EXPR)
    4775           27 :         suppress_warning (c, OPT_Wnonnull);
    4776              :     }
    4777              : 
    4778      7286603 :   if (allocated != NULL)
    4779       151475 :     release_tree_vector (allocated);
    4780              : 
    4781              :   return ret;
    4782              : }
    4783              : 
    4784              : /* Subroutine of convert_arguments.
    4785              :    Print an error message about a wrong number of arguments.  */
    4786              : 
    4787              : static void
    4788          162 : error_args_num (location_t loc, tree fndecl, bool too_many_p)
    4789              : {
    4790          162 :   if (fndecl)
    4791              :     {
    4792          126 :       auto_diagnostic_group d;
    4793          126 :       if (TREE_CODE (TREE_TYPE (fndecl)) == METHOD_TYPE)
    4794              :         {
    4795            0 :           if (DECL_NAME (fndecl) == NULL_TREE
    4796            0 :               || (DECL_NAME (fndecl)
    4797            0 :                   == DECL_NAME (TYPE_NAME (DECL_CONTEXT (fndecl)))))
    4798            0 :             error_at (loc,
    4799              :                       too_many_p
    4800              :                       ? G_("too many arguments to constructor %q#D")
    4801              :                       : G_("too few arguments to constructor %q#D"),
    4802              :                       fndecl);
    4803              :           else
    4804            0 :             error_at (loc,
    4805              :                       too_many_p
    4806              :                       ? G_("too many arguments to member function %q#D")
    4807              :                       : G_("too few arguments to member function %q#D"),
    4808              :                       fndecl);
    4809              :         }
    4810              :       else
    4811          189 :         error_at (loc,
    4812              :                   too_many_p
    4813              :                   ? G_("too many arguments to function %q#D")
    4814              :                   : G_("too few arguments to function %q#D"),
    4815              :                   fndecl);
    4816          126 :       if (!DECL_IS_UNDECLARED_BUILTIN (fndecl))
    4817           87 :         inform (DECL_SOURCE_LOCATION (fndecl), "declared here");
    4818          126 :     }
    4819              :   else
    4820              :     {
    4821           36 :       if (c_dialect_objc ()  &&  objc_message_selector ())
    4822            0 :         error_at (loc,
    4823              :                   too_many_p
    4824              :                   ? G_("too many arguments to method %q#D")
    4825              :                   : G_("too few arguments to method %q#D"),
    4826              :                   objc_message_selector ());
    4827              :       else
    4828           57 :         error_at (loc, too_many_p ? G_("too many arguments to function")
    4829              :                                   : G_("too few arguments to function"));
    4830              :     }
    4831          162 : }
    4832              : 
    4833              : /* Convert the actual parameter expressions in the list VALUES to the
    4834              :    types in the list TYPELIST.  The converted expressions are stored
    4835              :    back in the VALUES vector.
    4836              :    If parmdecls is exhausted, or when an element has NULL as its type,
    4837              :    perform the default conversions.
    4838              : 
    4839              :    NAME is an IDENTIFIER_NODE or 0.  It is used only for error messages.
    4840              : 
    4841              :    This is also where warnings about wrong number of args are generated.
    4842              : 
    4843              :    Returns the actual number of arguments processed (which might be less
    4844              :    than the length of the vector), or -1 on error.
    4845              : 
    4846              :    In C++, unspecified trailing parameters can be filled in with their
    4847              :    default arguments, if such were specified.  Do so here.  */
    4848              : 
    4849              : static int
    4850      7288492 : convert_arguments (tree typelist, vec<tree, va_gc> **values, tree fndecl,
    4851              :                    int flags, tsubst_flags_t complain)
    4852              : {
    4853      7288492 :   tree typetail;
    4854      7288492 :   unsigned int i;
    4855              : 
    4856              :   /* Argument passing is always copy-initialization.  */
    4857      7288492 :   flags |= LOOKUP_ONLYCONVERTING;
    4858              : 
    4859     11863358 :   for (i = 0, typetail = typelist;
    4860     11863358 :        i < vec_safe_length (*values);
    4861              :        i++)
    4862              :     {
    4863      9152740 :       tree type = typetail ? TREE_VALUE (typetail) : 0;
    4864      4576593 :       tree val = (**values)[i];
    4865              : 
    4866      4576593 :       if (val == error_mark_node || type == error_mark_node)
    4867              :         return -1;
    4868              : 
    4869      4576587 :       if (type == void_type_node)
    4870              :         {
    4871          205 :           if (complain & tf_error)
    4872           78 :             error_args_num (input_location, fndecl, /*too_many_p=*/true);
    4873          205 :           return -1;
    4874              :         }
    4875              : 
    4876              :       /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
    4877              :          Strip such NOP_EXPRs, since VAL is used in non-lvalue context.  */
    4878      4576382 :       if (TREE_CODE (val) == NOP_EXPR
    4879      1192508 :           && TREE_TYPE (val) == TREE_TYPE (TREE_OPERAND (val, 0))
    4880      4576400 :           && (type == 0 || !TYPE_REF_P (type)))
    4881           18 :         val = TREE_OPERAND (val, 0);
    4882              : 
    4883      4576382 :       if (type == 0 || !TYPE_REF_P (type))
    4884              :         {
    4885      4379130 :           if (TREE_CODE (TREE_TYPE (val)) == ARRAY_TYPE
    4886      4379130 :               || FUNC_OR_METHOD_TYPE_P (TREE_TYPE (val)))
    4887        11333 :             val = decay_conversion (val, complain);
    4888              :         }
    4889              : 
    4890      4576382 :       if (val == error_mark_node)
    4891              :         return -1;
    4892              : 
    4893      4576382 :       if (type != 0)
    4894              :         {
    4895              :           /* Formal parm type is specified by a function prototype.  */
    4896      4575936 :           tree parmval;
    4897              : 
    4898      4575936 :           if (!COMPLETE_TYPE_P (complete_type (type)))
    4899              :             {
    4900           18 :               if (complain & tf_error)
    4901              :                 {
    4902           12 :                   location_t loc = EXPR_LOC_OR_LOC (val, input_location);
    4903           12 :                   if (fndecl)
    4904              :                     {
    4905           12 :                       auto_diagnostic_group d;
    4906           12 :                       error_at (loc,
    4907              :                                 "parameter %P of %qD has incomplete type %qT",
    4908              :                                 i, fndecl, type);
    4909           12 :                       inform (get_fndecl_argument_location (fndecl, i),
    4910              :                               "  declared here");
    4911           12 :                     }
    4912              :                   else
    4913            0 :                     error_at (loc, "parameter %P has incomplete type %qT", i,
    4914              :                               type);
    4915              :                 }
    4916           18 :               parmval = error_mark_node;
    4917              :             }
    4918              :           else
    4919              :             {
    4920      4575918 :               parmval = convert_for_initialization
    4921      4575918 :                 (NULL_TREE, type, val, flags,
    4922              :                  ICR_ARGPASS, fndecl, i, complain);
    4923      4575918 :               parmval = convert_for_arg_passing (type, parmval, complain);
    4924              :             }
    4925              : 
    4926      4575936 :           if (parmval == error_mark_node)
    4927              :             return -1;
    4928              : 
    4929      4574420 :           (**values)[i] = parmval;
    4930              :         }
    4931              :       else
    4932              :         {
    4933          446 :           int magic = fndecl ? magic_varargs_p (fndecl) : 0;
    4934           21 :           if (magic)
    4935              :             {
    4936              :               /* Don't truncate excess precision to the semantic type.  */
    4937            0 :               if (magic == 1 && TREE_CODE (val) == EXCESS_PRECISION_EXPR)
    4938            0 :                 val = TREE_OPERAND (val, 0);
    4939              :               /* Don't do ellipsis conversion for __built_in_constant_p
    4940              :                  as this will result in spurious errors for non-trivial
    4941              :                  types.  */
    4942            0 :               val = require_complete_type (val, complain);
    4943              :             }
    4944              :           else
    4945          446 :             val = convert_arg_to_ellipsis (val, complain);
    4946              : 
    4947          446 :           (**values)[i] = val;
    4948              :         }
    4949              : 
    4950      4574866 :       if (typetail)
    4951      4574420 :         typetail = TREE_CHAIN (typetail);
    4952              :     }
    4953              : 
    4954      7286765 :   if (typetail != 0 && typetail != void_list_node)
    4955              :     {
    4956              :       /* See if there are default arguments that can be used.  Because
    4957              :          we hold default arguments in the FUNCTION_TYPE (which is so
    4958              :          wrong), we can see default parameters here from deduced
    4959              :          contexts (and via typeof) for indirect function calls.
    4960              :          Fortunately we know whether we have a function decl to
    4961              :          provide default arguments in a language conformant
    4962              :          manner.  */
    4963           63 :       if (fndecl && TREE_PURPOSE (typetail)
    4964          165 :           && TREE_CODE (TREE_PURPOSE (typetail)) != DEFERRED_PARSE)
    4965              :         {
    4966            6 :           for (; typetail != void_list_node; ++i)
    4967              :             {
    4968              :               /* After DR777, with explicit template args we can end up with a
    4969              :                  default argument followed by no default argument.  */
    4970            6 :               if (!TREE_PURPOSE (typetail))
    4971              :                 break;
    4972            3 :               tree parmval
    4973            3 :                 = convert_default_arg (TREE_VALUE (typetail),
    4974            3 :                                        TREE_PURPOSE (typetail),
    4975            3 :                                        fndecl, i, complain);
    4976              : 
    4977            3 :               if (parmval == error_mark_node)
    4978            0 :                 return -1;
    4979              : 
    4980            3 :               vec_safe_push (*values, parmval);
    4981            3 :               typetail = TREE_CHAIN (typetail);
    4982              :               /* ends with `...'.  */
    4983            3 :               if (typetail == NULL_TREE)
    4984              :                 break;
    4985              :             }
    4986              :         }
    4987              : 
    4988          162 :       if (typetail && typetail != void_list_node)
    4989              :         {
    4990          162 :           if (complain & tf_error)
    4991           84 :             error_args_num (input_location, fndecl, /*too_many_p=*/false);
    4992          162 :           return -1;
    4993              :         }
    4994              :     }
    4995              : 
    4996      7286603 :   return (int) i;
    4997              : }
    4998              : 
    4999              : /* Build a binary-operation expression, after performing default
    5000              :    conversions on the operands.  CODE is the kind of expression to
    5001              :    build.  ARG1 and ARG2 are the arguments.  ARG1_CODE and ARG2_CODE
    5002              :    are the tree codes which correspond to ARG1 and ARG2 when issuing
    5003              :    warnings about possibly misplaced parentheses.  They may differ
    5004              :    from the TREE_CODE of ARG1 and ARG2 if the parser has done constant
    5005              :    folding (e.g., if the parser sees "a | 1 + 1", it may call this
    5006              :    routine with ARG2 being an INTEGER_CST and ARG2_CODE == PLUS_EXPR).
    5007              :    To avoid issuing any parentheses warnings, pass ARG1_CODE and/or
    5008              :    ARG2_CODE as ERROR_MARK.  */
    5009              : 
    5010              : tree
    5011    225845737 : build_x_binary_op (const op_location_t &loc, enum tree_code code, tree arg1,
    5012              :                    enum tree_code arg1_code, tree arg2,
    5013              :                    enum tree_code arg2_code, tree lookups,
    5014              :                    tree *overload_p, tsubst_flags_t complain)
    5015              : {
    5016    225845737 :   tree orig_arg1;
    5017    225845737 :   tree orig_arg2;
    5018    225845737 :   tree expr;
    5019    225845737 :   tree overload = NULL_TREE;
    5020              : 
    5021    225845737 :   orig_arg1 = arg1;
    5022    225845737 :   orig_arg2 = arg2;
    5023              : 
    5024    225845737 :   if (processing_template_decl)
    5025              :     {
    5026    132018194 :       if (type_dependent_expression_p (arg1)
    5027    132018194 :           || type_dependent_expression_p (arg2))
    5028              :         {
    5029     91270338 :           expr = build_min_nt_loc (loc, code, arg1, arg2);
    5030     91270338 :           TREE_TYPE (expr)
    5031     91270338 :             = build_dependent_operator_type (lookups, code, false);
    5032     91270338 :           return expr;
    5033              :         }
    5034              :     }
    5035              : 
    5036    134575399 :   if (code == DOTSTAR_EXPR)
    5037        84231 :     expr = build_m_component_ref (arg1, arg2, complain);
    5038              :   else
    5039    134491168 :     expr = build_new_op (loc, code, LOOKUP_NORMAL, arg1, arg2, NULL_TREE,
    5040              :                          lookups, &overload, complain);
    5041              : 
    5042    134575366 :   if (overload_p != NULL)
    5043     59472641 :     *overload_p = overload;
    5044              : 
    5045              :   /* Check for cases such as x+y<<z which users are likely to
    5046              :      misinterpret.  But don't warn about obj << x + y, since that is a
    5047              :      common idiom for I/O.  */
    5048    134575366 :   if (warn_parentheses
    5049      1238110 :       && (complain & tf_warning)
    5050      1181544 :       && !processing_template_decl
    5051       816392 :       && !error_operand_p (arg1)
    5052       816386 :       && !error_operand_p (arg2)
    5053    135391740 :       && (code != LSHIFT_EXPR
    5054        71165 :           || !CLASS_TYPE_P (TREE_TYPE (arg1))))
    5055       815327 :     warn_about_parentheses (loc, code, arg1_code, orig_arg1,
    5056              :                             arg2_code, orig_arg2);
    5057              : 
    5058    134575366 :   if (processing_template_decl && expr != error_mark_node)
    5059              :     {
    5060     40747655 :       if (overload != NULL_TREE)
    5061      3821592 :         return (build_min_non_dep_op_overload
    5062      3821592 :                 (code, expr, overload, orig_arg1, orig_arg2));
    5063              : 
    5064     36926063 :       return build_min_non_dep (code, expr, orig_arg1, orig_arg2);
    5065              :     }
    5066              : 
    5067              :   return expr;
    5068              : }
    5069              : 
    5070              : /* Build and return an ARRAY_REF expression.  */
    5071              : 
    5072              : tree
    5073      2424982 : build_x_array_ref (location_t loc, tree arg1, tree arg2,
    5074              :                    tsubst_flags_t complain)
    5075              : {
    5076      2424982 :   tree orig_arg1 = arg1;
    5077      2424982 :   tree orig_arg2 = arg2;
    5078      2424982 :   tree expr;
    5079      2424982 :   tree overload = NULL_TREE;
    5080              : 
    5081      2424982 :   if (processing_template_decl)
    5082              :     {
    5083         4768 :       if (type_dependent_expression_p (arg1)
    5084         4768 :           || type_dependent_expression_p (arg2))
    5085         2574 :         return build_min_nt_loc (loc, ARRAY_REF, arg1, arg2,
    5086         2574 :                                  NULL_TREE, NULL_TREE);
    5087              :     }
    5088              : 
    5089      2422408 :   expr = build_new_op (loc, ARRAY_REF, LOOKUP_NORMAL, arg1, arg2,
    5090              :                        NULL_TREE, NULL_TREE, &overload, complain);
    5091              : 
    5092      2422408 :   if (processing_template_decl && expr != error_mark_node)
    5093              :     {
    5094         2191 :       if (overload != NULL_TREE)
    5095         2183 :         return (build_min_non_dep_op_overload
    5096         2183 :                 (ARRAY_REF, expr, overload, orig_arg1, orig_arg2));
    5097              : 
    5098            8 :       return build_min_non_dep (ARRAY_REF, expr, orig_arg1, orig_arg2,
    5099            8 :                                 NULL_TREE, NULL_TREE);
    5100              :     }
    5101              :   return expr;
    5102              : }
    5103              : 
    5104              : /* Build an OpenMP array section reference, creating an exact type for the
    5105              :    resulting expression based on the element type and bounds if possible.  If
    5106              :    we have variable bounds, create an incomplete array type for the result
    5107              :    instead.  */
    5108              : 
    5109              : tree
    5110        10499 : build_omp_array_section (location_t loc, tree array_expr, tree index,
    5111              :                          tree length)
    5112              : {
    5113        10499 :   if (TREE_CODE (array_expr) == TYPE_DECL
    5114        10499 :       || type_dependent_expression_p (array_expr))
    5115          258 :     return build3_loc (loc, OMP_ARRAY_SECTION, NULL_TREE, array_expr, index,
    5116          258 :                        length);
    5117              : 
    5118        10241 :   tree type = TREE_TYPE (array_expr);
    5119        10241 :   gcc_assert (type);
    5120        10241 :   type = non_reference (type);
    5121              : 
    5122        10241 :   tree sectype, eltype = TREE_TYPE (type);
    5123              : 
    5124              :   /* It's not an array or pointer type.  Just reuse the type of the
    5125              :      original expression as the type of the array section (an error will be
    5126              :      raised anyway, later).  */
    5127        10241 :   if (eltype == NULL_TREE)
    5128           39 :     sectype = TREE_TYPE (array_expr);
    5129              :   else
    5130              :     {
    5131        10202 :       tree idxtype = NULL_TREE;
    5132              : 
    5133              :       /* If we know the integer bounds, create an index type with exact
    5134              :          low/high (or zero/length) bounds.  Otherwise, create an incomplete
    5135              :          array type.  (This mostly only affects diagnostics.)  */
    5136        10202 :       if (index != NULL_TREE
    5137        10202 :           && length != NULL_TREE
    5138         7402 :           && TREE_CODE (index) == INTEGER_CST
    5139         6605 :           && TREE_CODE (length) == INTEGER_CST)
    5140              :         {
    5141         5110 :           tree low = fold_convert (sizetype, index);
    5142         5110 :           tree high = fold_convert (sizetype, length);
    5143         5110 :           high = size_binop (PLUS_EXPR, low, high);
    5144         5110 :           high = size_binop (MINUS_EXPR, high, size_one_node);
    5145         5110 :           idxtype = build_range_type (sizetype, low, high);
    5146         5110 :         }
    5147         2900 :       else if ((index == NULL_TREE || integer_zerop (index))
    5148         3503 :                && length != NULL_TREE
    5149         7187 :                && TREE_CODE (length) == INTEGER_CST)
    5150         1387 :         idxtype = build_index_type (length);
    5151              : 
    5152        10202 :       sectype = build_array_type (eltype, idxtype);
    5153              :     }
    5154              : 
    5155        10241 :   return build3_loc (loc, OMP_ARRAY_SECTION, sectype, array_expr, index,
    5156        10241 :                      length);
    5157              : }
    5158              : 
    5159              : /* Return whether OP is an expression of enum type cast to integer
    5160              :    type.  In C++ even unsigned enum types are cast to signed integer
    5161              :    types.  We do not want to issue warnings about comparisons between
    5162              :    signed and unsigned types when one of the types is an enum type.
    5163              :    Those warnings are always false positives in practice.  */
    5164              : 
    5165              : static bool
    5166       638660 : enum_cast_to_int (tree op)
    5167              : {
    5168       625680 :   if (CONVERT_EXPR_P (op)
    5169        14007 :       && TREE_TYPE (op) == integer_type_node
    5170          917 :       && TREE_CODE (TREE_TYPE (TREE_OPERAND (op, 0))) == ENUMERAL_TYPE
    5171       638675 :       && TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op, 0))))
    5172              :     return true;
    5173              : 
    5174              :   /* The cast may have been pushed into a COND_EXPR.  */
    5175       638653 :   if (TREE_CODE (op) == COND_EXPR)
    5176          765 :     return (enum_cast_to_int (TREE_OPERAND (op, 1))
    5177          765 :             || enum_cast_to_int (TREE_OPERAND (op, 2)));
    5178              : 
    5179              :   return false;
    5180              : }
    5181              : 
    5182              : /* For the c-common bits.  */
    5183              : tree
    5184      4645287 : build_binary_op (location_t location, enum tree_code code, tree op0, tree op1,
    5185              :                  bool /*convert_p*/)
    5186              : {
    5187      4645287 :   return cp_build_binary_op (location, code, op0, op1, tf_warning_or_error);
    5188              : }
    5189              : 
    5190              : /* Build a vector comparison of ARG0 and ARG1 using CODE opcode
    5191              :    into a value of TYPE type.  Comparison is done via VEC_COND_EXPR.  */
    5192              : 
    5193              : static tree
    5194         7718 : build_vec_cmp (tree_code code, tree type,
    5195              :                tree arg0, tree arg1)
    5196              : {
    5197         7718 :   tree zero_vec = build_zero_cst (type);
    5198         7718 :   tree minus_one_vec = build_minus_one_cst (type);
    5199         7718 :   tree cmp_type = truth_type_for (TREE_TYPE (arg0));
    5200         7718 :   tree cmp = build2 (code, cmp_type, arg0, arg1);
    5201         7718 :   return build3 (VEC_COND_EXPR, type, cmp, minus_one_vec, zero_vec);
    5202              : }
    5203              : 
    5204              : /* Possibly warn about an address never being NULL.  */
    5205              : 
    5206              : static void
    5207      1747296 : warn_for_null_address (location_t location, tree op, tsubst_flags_t complain)
    5208              : {
    5209              :   /* Prevent warnings issued for macro expansion.  */
    5210      1747296 :   if (!warn_address
    5211        41601 :       || (complain & tf_warning) == 0
    5212        24878 :       || c_inhibit_evaluation_warnings != 0
    5213        24862 :       || from_macro_expansion_at (location)
    5214      1765427 :       || warning_suppressed_p (op, OPT_Waddress))
    5215      1729488 :     return;
    5216              : 
    5217        18098 :   tree cop = fold_for_warn (op);
    5218              : 
    5219        18098 :   if (TREE_CODE (cop) == NON_LVALUE_EXPR)
    5220              :     /* Unwrap the expression for C++ 98.  */
    5221            1 :     cop = TREE_OPERAND (cop, 0);
    5222              : 
    5223        18098 :   if (TREE_CODE (cop) == PTRMEM_CST)
    5224              :     {
    5225              :       /* The address of a nonstatic data member is never null.  */
    5226           30 :       warning_at (location, OPT_Waddress,
    5227              :                   "the address %qE will never be NULL",
    5228              :                   cop);
    5229           30 :       return;
    5230              :     }
    5231              : 
    5232        18068 :   if (TREE_CODE (cop) == NOP_EXPR)
    5233              :     {
    5234              :       /* Allow casts to intptr_t to suppress the warning.  */
    5235         1243 :       tree type = TREE_TYPE (cop);
    5236         1243 :       if (TREE_CODE (type) == INTEGER_TYPE)
    5237              :         return;
    5238              : 
    5239         1243 :       STRIP_NOPS (cop);
    5240              :     }
    5241              : 
    5242        18068 :   auto_diagnostic_group d;
    5243        18068 :   bool warned = false;
    5244        18068 :   if (TREE_CODE (cop) == ADDR_EXPR)
    5245              :     {
    5246          789 :       cop = TREE_OPERAND (cop, 0);
    5247              : 
    5248              :       /* Set to true in the loop below if OP dereferences its operand.
    5249              :          In such a case the ultimate target need not be a decl for
    5250              :          the null [in]equality test to be necessarily constant.  */
    5251          789 :       bool deref = false;
    5252              : 
    5253              :       /* Get the outermost array or object, or member.  */
    5254          960 :       while (handled_component_p (cop))
    5255              :         {
    5256          270 :           if (TREE_CODE (cop) == COMPONENT_REF)
    5257              :             {
    5258              :               /* Get the member (its address is never null).  */
    5259           99 :               cop = TREE_OPERAND (cop, 1);
    5260           99 :               break;
    5261              :             }
    5262              : 
    5263              :           /* Get the outer array/object to refer to in the warning.  */
    5264          171 :           cop = TREE_OPERAND (cop, 0);
    5265          171 :           deref = true;
    5266              :         }
    5267              : 
    5268          639 :       if ((!deref && !decl_with_nonnull_addr_p (cop))
    5269          631 :           || from_macro_expansion_at (location)
    5270         1420 :           || warning_suppressed_p (cop, OPT_Waddress))
    5271          158 :         return;
    5272              : 
    5273          631 :       warned = warning_at (location, OPT_Waddress,
    5274              :                            "the address of %qD will never be NULL", cop);
    5275          631 :       op = cop;
    5276              :     }
    5277        17279 :   else if (TREE_CODE (cop) == POINTER_PLUS_EXPR)
    5278              :     {
    5279              :       /* Adding zero to the null pointer is well-defined in C++.  When
    5280              :          the offset is unknown (i.e., not a constant) warn anyway since
    5281              :          it's less likely that the pointer operand is null than not.  */
    5282          102 :       tree off = TREE_OPERAND (cop, 1);
    5283          102 :       if (!integer_zerop (off)
    5284          102 :           && !warning_suppressed_p (cop, OPT_Waddress))
    5285              :         {
    5286          102 :           tree base = TREE_OPERAND (cop, 0);
    5287          102 :           STRIP_NOPS (base);
    5288          102 :           if (TYPE_REF_P (TREE_TYPE (base)))
    5289           12 :             warning_at (location, OPT_Waddress, "the compiler can assume that "
    5290              :                         "the address of %qE will never be NULL", base);
    5291              :           else
    5292           90 :             warning_at (location, OPT_Waddress, "comparing the result of "
    5293              :                         "pointer addition %qE and NULL", cop);
    5294              :         }
    5295          102 :       return;
    5296              :     }
    5297        16215 :   else if (CONVERT_EXPR_P (op)
    5298        17239 :            && TYPE_REF_P (TREE_TYPE (TREE_OPERAND (op, 0))))
    5299              :     {
    5300           62 :       STRIP_NOPS (op);
    5301              : 
    5302           62 :       if (TREE_CODE (op) == COMPONENT_REF)
    5303           24 :         op = TREE_OPERAND (op, 1);
    5304              : 
    5305           62 :       if (DECL_P (op))
    5306           62 :         warned = warning_at (location, OPT_Waddress,
    5307              :                              "the compiler can assume that the address of "
    5308              :                              "%qD will never be NULL", op);
    5309              :     }
    5310              : 
    5311          693 :   if (warned && DECL_P (op))
    5312          657 :     inform (DECL_SOURCE_LOCATION (op), "%qD declared here", op);
    5313        18068 : }
    5314              : 
    5315              : /* Warn about [expr.arith.conv]/2: If one operand is of enumeration type and
    5316              :    the other operand is of a different enumeration type or a floating-point
    5317              :    type, this behavior is deprecated ([depr.arith.conv.enum]).  CODE is the
    5318              :    code of the binary operation, TYPE0 and TYPE1 are the types of the operands,
    5319              :    and LOC is the location for the whole binary expression.
    5320              :    For C++26 this is ill-formed rather than deprecated.
    5321              :    Return true for SFINAE errors.
    5322              :    TODO: Consider combining this with -Wenum-compare in build_new_op_1.  */
    5323              : 
    5324              : static bool
    5325    107753950 : do_warn_enum_conversions (location_t loc, enum tree_code code, tree type0,
    5326              :                           tree type1, tsubst_flags_t complain)
    5327              : {
    5328    107753950 :   if (TREE_CODE (type0) == ENUMERAL_TYPE
    5329      3175896 :       && TREE_CODE (type1) == ENUMERAL_TYPE
    5330    110415399 :       && TYPE_MAIN_VARIANT (type0) != TYPE_MAIN_VARIANT (type1))
    5331              :     {
    5332          198 :       if (cxx_dialect >= cxx26)
    5333              :         {
    5334           60 :           if ((complain & tf_warning_or_error) == 0)
    5335              :             return true;
    5336              :         }
    5337          138 :       else if ((complain & tf_warning) == 0)
    5338              :         return false;
    5339              :       /* In C++20, -Wdeprecated-enum-enum-conversion is on by default.
    5340              :          Otherwise, warn if -Wenum-conversion is on.  */
    5341          190 :       enum opt_code opt;
    5342          190 :       if (warn_deprecated_enum_enum_conv)
    5343              :         opt = OPT_Wdeprecated_enum_enum_conversion;
    5344           93 :       else if (warn_enum_conversion)
    5345              :         opt = OPT_Wenum_conversion;
    5346              :       else
    5347              :         return false;
    5348              : 
    5349          119 :       switch (code)
    5350              :         {
    5351              :         case GT_EXPR:
    5352              :         case LT_EXPR:
    5353              :         case GE_EXPR:
    5354              :         case LE_EXPR:
    5355              :         case EQ_EXPR:
    5356              :         case NE_EXPR:
    5357              :           /* Comparisons are handled by -Wenum-compare.  */
    5358              :           return false;
    5359              :         case SPACESHIP_EXPR:
    5360              :           /* This is invalid, don't warn.  */
    5361              :           return false;
    5362           17 :         case BIT_AND_EXPR:
    5363           17 :         case BIT_IOR_EXPR:
    5364           17 :         case BIT_XOR_EXPR:
    5365           17 :           if (cxx_dialect >= cxx26)
    5366            5 :             pedwarn (loc, opt, "bitwise operation between different "
    5367              :                      "enumeration types %qT and %qT", type0, type1);
    5368              :           else
    5369           12 :             warning_at (loc, opt, "bitwise operation between different "
    5370              :                         "enumeration types %qT and %qT is deprecated",
    5371              :                         type0, type1);
    5372           17 :           return false;
    5373           41 :         default:
    5374           41 :           if (cxx_dialect >= cxx26)
    5375           12 :             pedwarn (loc, opt, "arithmetic between different enumeration "
    5376              :                      "types %qT and %qT", type0, type1);
    5377              :           else
    5378           29 :             warning_at (loc, opt, "arithmetic between different enumeration "
    5379              :                         "types %qT and %qT is deprecated", type0, type1);
    5380           41 :           return false;
    5381              :         }
    5382              :     }
    5383    107753752 :   else if ((TREE_CODE (type0) == ENUMERAL_TYPE
    5384      3175698 :             && SCALAR_FLOAT_TYPE_P (type1))
    5385    107753682 :            || (SCALAR_FLOAT_TYPE_P (type0)
    5386     30831291 :                && TREE_CODE (type1) == ENUMERAL_TYPE))
    5387              :     {
    5388          147 :       if (cxx_dialect >= cxx26)
    5389              :         {
    5390           46 :           if ((complain & tf_warning_or_error) == 0)
    5391              :             return true;
    5392              :         }
    5393          101 :       else if ((complain & tf_warning) == 0)
    5394              :         return false;
    5395          135 :       const bool enum_first_p = TREE_CODE (type0) == ENUMERAL_TYPE;
    5396              :       /* In C++20, -Wdeprecated-enum-float-conversion is on by default.
    5397              :          Otherwise, warn if -Wenum-conversion is on.  */
    5398          135 :       enum opt_code opt;
    5399          135 :       if (warn_deprecated_enum_float_conv)
    5400              :         opt = OPT_Wdeprecated_enum_float_conversion;
    5401           68 :       else if (warn_enum_conversion)
    5402              :         opt = OPT_Wenum_conversion;
    5403              :       else
    5404              :         return false;
    5405              : 
    5406           84 :       switch (code)
    5407              :         {
    5408           34 :         case GT_EXPR:
    5409           34 :         case LT_EXPR:
    5410           34 :         case GE_EXPR:
    5411           34 :         case LE_EXPR:
    5412           34 :         case EQ_EXPR:
    5413           34 :         case NE_EXPR:
    5414           34 :           if (enum_first_p && cxx_dialect >= cxx26)
    5415            5 :             pedwarn (loc, opt, "comparison of enumeration type %qT with "
    5416              :                      "floating-point type %qT", type0, type1);
    5417           29 :           else if (cxx_dialect >= cxx26)
    5418            5 :             pedwarn (loc, opt, "comparison of floating-point type %qT "
    5419              :                       "with enumeration type %qT", type0, type1);
    5420           24 :           else if (enum_first_p)
    5421           12 :             warning_at (loc, opt, "comparison of enumeration type %qT with "
    5422              :                         "floating-point type %qT is deprecated",
    5423              :                         type0, type1);
    5424              :           else
    5425           12 :             warning_at (loc, opt, "comparison of floating-point type %qT "
    5426              :                         "with enumeration type %qT is deprecated",
    5427              :                         type0, type1);
    5428           34 :           return false;
    5429              :         case SPACESHIP_EXPR:
    5430              :           /* This is invalid, don't warn.  */
    5431              :           return false;
    5432           38 :         default:
    5433           38 :           if (enum_first_p && cxx_dialect >= cxx26)
    5434            5 :             pedwarn (loc, opt, "arithmetic between enumeration type %qT "
    5435              :                      "and floating-point type %qT", type0, type1);
    5436           33 :           else if (cxx_dialect >= cxx26)
    5437            6 :             pedwarn (loc, opt, "arithmetic between floating-point type %qT "
    5438              :                      "and enumeration type %qT", type0, type1);
    5439           27 :           else if (enum_first_p)
    5440           12 :             warning_at (loc, opt, "arithmetic between enumeration type %qT "
    5441              :                         "and floating-point type %qT is deprecated",
    5442              :                         type0, type1);
    5443              :           else
    5444           15 :             warning_at (loc, opt, "arithmetic between floating-point type %qT "
    5445              :                         "and enumeration type %qT is deprecated",
    5446              :                         type0, type1);
    5447           38 :           return false;
    5448              :         }
    5449              :     }
    5450              :   return false;
    5451              : }
    5452              : 
    5453              : /* Build a binary-operation expression without default conversions.
    5454              :    CODE is the kind of expression to build.
    5455              :    LOCATION is the location_t of the operator in the source code.
    5456              :    This function differs from `build' in several ways:
    5457              :    the data type of the result is computed and recorded in it,
    5458              :    warnings are generated if arg data types are invalid,
    5459              :    special handling for addition and subtraction of pointers is known,
    5460              :    and some optimization is done (operations on narrow ints
    5461              :    are done in the narrower type when that gives the same result).
    5462              :    Constant folding is also done before the result is returned.
    5463              : 
    5464              :    Note that the operands will never have enumeral types
    5465              :    because either they have just had the default conversions performed
    5466              :    or they have both just been converted to some other type in which
    5467              :    the arithmetic is to be done.
    5468              : 
    5469              :    C++: must do special pointer arithmetic when implementing
    5470              :    multiple inheritance, and deal with pointer to member functions.  */
    5471              : 
    5472              : tree
    5473    143674334 : cp_build_binary_op (const op_location_t &location,
    5474              :                     enum tree_code code, tree orig_op0, tree orig_op1,
    5475              :                     tsubst_flags_t complain)
    5476              : {
    5477    143674334 :   tree op0, op1;
    5478    143674334 :   enum tree_code code0, code1;
    5479    143674334 :   tree type0, type1, orig_type0, orig_type1;
    5480    143674334 :   const char *invalid_op_diag;
    5481              : 
    5482              :   /* Expression code to give to the expression when it is built.
    5483              :      Normally this is CODE, which is what the caller asked for,
    5484              :      but in some special cases we change it.  */
    5485    143674334 :   enum tree_code resultcode = code;
    5486              : 
    5487              :   /* Data type in which the computation is to be performed.
    5488              :      In the simplest cases this is the common type of the arguments.  */
    5489    143674334 :   tree result_type = NULL_TREE;
    5490              : 
    5491              :   /* When the computation is in excess precision, the type of the
    5492              :      final EXCESS_PRECISION_EXPR.  */
    5493    143674334 :   tree semantic_result_type = NULL;
    5494              : 
    5495              :   /* Nonzero means operands have already been type-converted
    5496              :      in whatever way is necessary.
    5497              :      Zero means they need to be converted to RESULT_TYPE.  */
    5498    143674334 :   int converted = 0;
    5499              : 
    5500              :   /* Nonzero means create the expression with this type, rather than
    5501              :      RESULT_TYPE.  */
    5502    143674334 :   tree build_type = 0;
    5503              : 
    5504              :   /* Nonzero means after finally constructing the expression
    5505              :      convert it to this type.  */
    5506    143674334 :   tree final_type = 0;
    5507              : 
    5508    143674334 :   tree result;
    5509              : 
    5510              :   /* Nonzero if this is an operation like MIN or MAX which can
    5511              :      safely be computed in short if both args are promoted shorts.
    5512              :      Also implies COMMON.
    5513              :      -1 indicates a bitwise operation; this makes a difference
    5514              :      in the exact conditions for when it is safe to do the operation
    5515              :      in a narrower mode.  */
    5516    143674334 :   int shorten = 0;
    5517              : 
    5518              :   /* Nonzero if this is a comparison operation;
    5519              :      if both args are promoted shorts, compare the original shorts.
    5520              :      Also implies COMMON.  */
    5521    143674334 :   int short_compare = 0;
    5522              : 
    5523              :   /* Nonzero if this is a right-shift operation, which can be computed on the
    5524              :      original short and then promoted if the operand is a promoted short.  */
    5525    143674334 :   int short_shift = 0;
    5526              : 
    5527              :   /* Nonzero means set RESULT_TYPE to the common type of the args.  */
    5528    143674334 :   int common = 0;
    5529              : 
    5530              :   /* True if both operands have arithmetic type.  */
    5531    143674334 :   bool arithmetic_types_p;
    5532              : 
    5533              :   /* Remember whether we're doing / or %.  */
    5534    143674334 :   bool doing_div_or_mod = false;
    5535              : 
    5536              :   /* Remember whether we're doing << or >>.  */
    5537    143674334 :   bool doing_shift = false;
    5538              : 
    5539              :   /* Tree holding instrumentation expression.  */
    5540    143674334 :   tree instrument_expr = NULL_TREE;
    5541              : 
    5542              :   /* True means this is an arithmetic operation that may need excess
    5543              :      precision.  */
    5544    143674334 :   bool may_need_excess_precision;
    5545              : 
    5546              :   /* Apply default conversions.  */
    5547    143674334 :   op0 = resolve_nondeduced_context (orig_op0, complain);
    5548    143674334 :   op1 = resolve_nondeduced_context (orig_op1, complain);
    5549              : 
    5550    143674334 :   if (code == TRUTH_AND_EXPR || code == TRUTH_ANDIF_EXPR
    5551    130878527 :       || code == TRUTH_OR_EXPR || code == TRUTH_ORIF_EXPR
    5552    127594618 :       || code == TRUTH_XOR_EXPR)
    5553              :     {
    5554     16079716 :       if (!really_overloaded_fn (op0) && !VOID_TYPE_P (TREE_TYPE (op0)))
    5555     16079698 :         op0 = decay_conversion (op0, complain);
    5556     16079716 :       if (!really_overloaded_fn (op1) && !VOID_TYPE_P (TREE_TYPE (op1)))
    5557     16079716 :         op1 = decay_conversion (op1, complain);
    5558              :     }
    5559              :   else
    5560              :     {
    5561    127594618 :       if (!really_overloaded_fn (op0) && !VOID_TYPE_P (TREE_TYPE (op0)))
    5562    127594575 :         op0 = cp_default_conversion (op0, complain);
    5563    127594618 :       if (!really_overloaded_fn (op1) && !VOID_TYPE_P (TREE_TYPE (op1)))
    5564    127594599 :         op1 = cp_default_conversion (op1, complain);
    5565              :     }
    5566              : 
    5567              :   /* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue.  */
    5568    152033462 :   STRIP_TYPE_NOPS (op0);
    5569    176573989 :   STRIP_TYPE_NOPS (op1);
    5570              : 
    5571              :   /* DTRT if one side is an overloaded function, but complain about it.  */
    5572    143674334 :   if (type_unknown_p (op0))
    5573              :     {
    5574            9 :       tree t = instantiate_type (TREE_TYPE (op1), op0, tf_none);
    5575            9 :       if (t != error_mark_node)
    5576              :         {
    5577            0 :           if (complain & tf_error)
    5578            0 :             permerror (location,
    5579              :                        "assuming cast to type %qT from overloaded function",
    5580            0 :                        TREE_TYPE (t));
    5581              :           op0 = t;
    5582              :         }
    5583              :     }
    5584    143674334 :   if (type_unknown_p (op1))
    5585              :     {
    5586            3 :       tree t = instantiate_type (TREE_TYPE (op0), op1, tf_none);
    5587            3 :       if (t != error_mark_node)
    5588              :         {
    5589            3 :           if (complain & tf_error)
    5590            3 :             permerror (location,
    5591              :                        "assuming cast to type %qT from overloaded function",
    5592            3 :                        TREE_TYPE (t));
    5593              :           op1 = t;
    5594              :         }
    5595              :     }
    5596              : 
    5597    143674334 :   orig_type0 = type0 = TREE_TYPE (op0);
    5598    143674334 :   orig_type1 = type1 = TREE_TYPE (op1);
    5599    143674334 :   tree non_ep_op0 = op0;
    5600    143674334 :   tree non_ep_op1 = op1;
    5601              : 
    5602              :   /* The expression codes of the data types of the arguments tell us
    5603              :      whether the arguments are integers, floating, pointers, etc.  */
    5604    143674334 :   code0 = TREE_CODE (type0);
    5605    143674334 :   code1 = TREE_CODE (type1);
    5606              : 
    5607              :   /* If an error was already reported for one of the arguments,
    5608              :      avoid reporting another error.  */
    5609    143674334 :   if (code0 == ERROR_MARK || code1 == ERROR_MARK)
    5610          100 :     return error_mark_node;
    5611              : 
    5612    287348468 :   if ((invalid_op_diag
    5613    143674234 :        = targetm.invalid_binary_op (code, type0, type1)))
    5614              :     {
    5615            0 :       if (complain & tf_error)
    5616              :         {
    5617            0 :           if (code0 == REAL_TYPE
    5618            0 :               && code1 == REAL_TYPE
    5619            0 :               && (extended_float_type_p (type0)
    5620            0 :                   || extended_float_type_p (type1))
    5621            0 :               && cp_compare_floating_point_conversion_ranks (type0,
    5622              :                                                              type1) == 3)
    5623              :             {
    5624            0 :               rich_location richloc (line_table, location);
    5625            0 :               binary_op_error (&richloc, code, type0, type1);
    5626            0 :             }
    5627              :           else
    5628            0 :             error (invalid_op_diag);
    5629              :         }
    5630            0 :       return error_mark_node;
    5631              :     }
    5632              : 
    5633    143674234 :   switch (code)
    5634              :     {
    5635              :     case PLUS_EXPR:
    5636              :     case MINUS_EXPR:
    5637              :     case MULT_EXPR:
    5638              :     case TRUNC_DIV_EXPR:
    5639              :     case CEIL_DIV_EXPR:
    5640              :     case FLOOR_DIV_EXPR:
    5641              :     case ROUND_DIV_EXPR:
    5642              :     case EXACT_DIV_EXPR:
    5643              :       may_need_excess_precision = true;
    5644              :       break;
    5645     50920343 :     case EQ_EXPR:
    5646     50920343 :     case NE_EXPR:
    5647     50920343 :     case LE_EXPR:
    5648     50920343 :     case GE_EXPR:
    5649     50920343 :     case LT_EXPR:
    5650     50920343 :     case GT_EXPR:
    5651     50920343 :     case SPACESHIP_EXPR:
    5652              :       /* Excess precision for implicit conversions of integers to
    5653              :          floating point.  */
    5654     11052626 :       may_need_excess_precision = (ANY_INTEGRAL_TYPE_P (type0)
    5655     61965868 :                                    || ANY_INTEGRAL_TYPE_P (type1));
    5656              :       break;
    5657              :     default:
    5658    143674234 :       may_need_excess_precision = false;
    5659              :       break;
    5660              :     }
    5661    143674234 :   if (TREE_CODE (op0) == EXCESS_PRECISION_EXPR)
    5662              :     {
    5663        11242 :       op0 = TREE_OPERAND (op0, 0);
    5664        11242 :       type0 = TREE_TYPE (op0);
    5665              :     }
    5666    143662992 :   else if (may_need_excess_precision
    5667    108502943 :            && (code0 == REAL_TYPE || code0 == COMPLEX_TYPE))
    5668     26911461 :     if (tree eptype = excess_precision_type (type0))
    5669              :       {
    5670        29805 :         type0 = eptype;
    5671        29805 :         op0 = convert (eptype, op0);
    5672              :       }
    5673    143674234 :   if (TREE_CODE (op1) == EXCESS_PRECISION_EXPR)
    5674              :     {
    5675        14052 :       op1 = TREE_OPERAND (op1, 0);
    5676        14052 :       type1 = TREE_TYPE (op1);
    5677              :     }
    5678    143660182 :   else if (may_need_excess_precision
    5679    108501766 :            && (code1 == REAL_TYPE || code1 == COMPLEX_TYPE))
    5680     26769756 :     if (tree eptype = excess_precision_type (type1))
    5681              :       {
    5682        20163 :         type1 = eptype;
    5683        20163 :         op1 = convert (eptype, op1);
    5684              :       }
    5685              : 
    5686              :   /* Issue warnings about peculiar, but valid, uses of NULL.  */
    5687    287348383 :   if ((null_node_p (orig_op0) || null_node_p (orig_op1))
    5688              :       /* It's reasonable to use pointer values as operands of &&
    5689              :          and ||, so NULL is no exception.  */
    5690        12051 :       && code != TRUTH_ANDIF_EXPR && code != TRUTH_ORIF_EXPR
    5691        12036 :       && ( /* Both are NULL (or 0) and the operation was not a
    5692              :               comparison or a pointer subtraction.  */
    5693        12109 :           (null_ptr_cst_p (orig_op0) && null_ptr_cst_p (orig_op1)
    5694           27 :            && code != EQ_EXPR && code != NE_EXPR && code != MINUS_EXPR)
    5695              :           /* Or if one of OP0 or OP1 is neither a pointer nor NULL.  */
    5696        12024 :           || (!null_ptr_cst_p (orig_op0)
    5697        11963 :               && !TYPE_PTR_OR_PTRMEM_P (type0))
    5698        12012 :           || (!null_ptr_cst_p (orig_op1)
    5699           46 :               && !TYPE_PTR_OR_PTRMEM_P (type1)))
    5700    143674273 :       && (complain & tf_warning))
    5701              :     {
    5702           39 :       location_t loc =
    5703           39 :         expansion_point_location_if_in_system_header (input_location);
    5704              : 
    5705           39 :       warning_at (loc, OPT_Wpointer_arith, "NULL used in arithmetic");
    5706              :     }
    5707              : 
    5708              :   /* In case when one of the operands of the binary operation is
    5709              :      a vector and another is a scalar -- convert scalar to vector.  */
    5710    143742356 :   if ((gnu_vector_type_p (type0) && code1 != VECTOR_TYPE)
    5711    143741379 :       || (gnu_vector_type_p (type1) && code0 != VECTOR_TYPE))
    5712              :     {
    5713         1062 :       enum stv_conv convert_flag
    5714         1062 :         = scalar_to_vector (location, code, non_ep_op0, non_ep_op1,
    5715              :                             complain & tf_error);
    5716              : 
    5717         1062 :       switch (convert_flag)
    5718              :         {
    5719           21 :           case stv_error:
    5720           21 :             return error_mark_node;
    5721           55 :           case stv_firstarg:
    5722           55 :             {
    5723           55 :               op0 = convert (TREE_TYPE (type1), op0);
    5724           55 :               op0 = cp_save_expr (op0);
    5725           55 :               op0 = build_vector_from_val (type1, op0);
    5726           55 :               orig_type0 = type0 = TREE_TYPE (op0);
    5727           55 :               code0 = TREE_CODE (type0);
    5728           55 :               converted = 1;
    5729           55 :               break;
    5730              :             }
    5731          865 :           case stv_secondarg:
    5732          865 :             {
    5733          865 :               op1 = convert (TREE_TYPE (type0), op1);
    5734          865 :               op1 = cp_save_expr (op1);
    5735          865 :               op1 = build_vector_from_val (type0, op1);
    5736          865 :               orig_type1 = type1 = TREE_TYPE (op1);
    5737          865 :               code1 = TREE_CODE (type1);
    5738          865 :               converted = 1;
    5739          865 :               break;
    5740              :             }
    5741              :           default:
    5742              :             break;
    5743              :         }
    5744              :     }
    5745              : 
    5746    143674213 :   switch (code)
    5747              :     {
    5748     15900086 :     case MINUS_EXPR:
    5749              :       /* Subtraction of two similar pointers.
    5750              :          We must subtract them as integers, then divide by object size.  */
    5751     15900086 :       if (code0 == POINTER_TYPE && code1 == POINTER_TYPE
    5752     17347160 :           && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (type0),
    5753      1447074 :                                                         TREE_TYPE (type1)))
    5754              :         {
    5755      1447072 :           result = pointer_diff (location, op0, op1,
    5756              :                                  common_pointer_type (type0, type1), complain,
    5757              :                                  &instrument_expr);
    5758      1447072 :           if (instrument_expr != NULL)
    5759           84 :             result = build2 (COMPOUND_EXPR, TREE_TYPE (result),
    5760              :                              instrument_expr, result);
    5761              : 
    5762      1447072 :           return result;
    5763              :         }
    5764              :       /* In all other cases except pointer - int, the usual arithmetic
    5765              :          rules apply.  */
    5766     14453014 :       else if (!(code0 == POINTER_TYPE && code1 == INTEGER_TYPE))
    5767              :         {
    5768              :           common = 1;
    5769              :           break;
    5770              :         }
    5771              :       /* The pointer - int case is just like pointer + int; fall
    5772              :          through.  */
    5773     20878935 :       gcc_fallthrough ();
    5774     20878935 :     case PLUS_EXPR:
    5775     20878935 :       if ((code0 == POINTER_TYPE || code1 == POINTER_TYPE)
    5776      7581177 :           && (code0 == INTEGER_TYPE || code1 == INTEGER_TYPE))
    5777              :         {
    5778      7581168 :           tree ptr_operand;
    5779      7581168 :           tree int_operand;
    5780      7581168 :           ptr_operand = ((code0 == POINTER_TYPE) ? op0 : op1);
    5781       121976 :           int_operand = ((code0 == INTEGER_TYPE) ? op0 : op1);
    5782      7581168 :           if (processing_template_decl)
    5783              :             {
    5784      2175815 :               result_type = TREE_TYPE (ptr_operand);
    5785      2175815 :               break;
    5786              :             }
    5787      5405353 :           return cp_pointer_int_sum (location, code,
    5788              :                                      ptr_operand,
    5789              :                                      int_operand,
    5790      5405353 :                                      complain);
    5791              :         }
    5792              :       common = 1;
    5793              :       break;
    5794              : 
    5795              :     case MULT_EXPR:
    5796    136778781 :       common = 1;
    5797              :       break;
    5798              : 
    5799     12044753 :     case TRUNC_DIV_EXPR:
    5800     12044753 :     case CEIL_DIV_EXPR:
    5801     12044753 :     case FLOOR_DIV_EXPR:
    5802     12044753 :     case ROUND_DIV_EXPR:
    5803     12044753 :     case EXACT_DIV_EXPR:
    5804     12044753 :       if (TREE_CODE (op0) == SIZEOF_EXPR && TREE_CODE (op1) == SIZEOF_EXPR)
    5805              :         {
    5806       120286 :           tree type0 = TREE_OPERAND (op0, 0);
    5807       120286 :           tree type1 = TREE_OPERAND (op1, 0);
    5808       120286 :           tree first_arg = tree_strip_any_location_wrapper (type0);
    5809       120286 :           if (!TYPE_P (type0))
    5810        79567 :             type0 = TREE_TYPE (type0);
    5811       120286 :           if (!TYPE_P (type1))
    5812        44994 :             type1 = TREE_TYPE (type1);
    5813       120286 :           if (type0
    5814       120286 :               && type1
    5815       101139 :               && INDIRECT_TYPE_P (type0)
    5816       120361 :               && same_type_p (TREE_TYPE (type0), type1))
    5817              :             {
    5818           27 :               if (!(TREE_CODE (first_arg) == PARM_DECL
    5819           21 :                     && DECL_ARRAY_PARAMETER_P (first_arg)
    5820            3 :                     && warn_sizeof_array_argument)
    5821           42 :                   && (complain & tf_warning))
    5822              :                 {
    5823           21 :                   auto_diagnostic_group d;
    5824           21 :                   if (warning_at (location, OPT_Wsizeof_pointer_div,
    5825              :                                   "division %<sizeof (%T) / sizeof (%T)%> does "
    5826              :                                   "not compute the number of array elements",
    5827              :                                   type0, type1))
    5828           18 :                     if (DECL_P (first_arg))
    5829           18 :                       inform (DECL_SOURCE_LOCATION (first_arg),
    5830              :                               "first %<sizeof%> operand was declared here");
    5831           21 :                 }
    5832              :             }
    5833       120262 :           else if (!dependent_type_p (type0)
    5834        25948 :                    && !dependent_type_p (type1)
    5835        25850 :                    && TREE_CODE (type0) == ARRAY_TYPE
    5836        21044 :                    && !char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type0)))
    5837              :                    /* Set by finish_parenthesized_expr.  */
    5838        20395 :                    && !warning_suppressed_p (op1, OPT_Wsizeof_array_div)
    5839       140639 :                    && (complain & tf_warning))
    5840        20377 :             maybe_warn_sizeof_array_div (location, first_arg, type0,
    5841              :                                          op1, non_reference (type1));
    5842              :         }
    5843              : 
    5844     12044753 :       if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
    5845              :            || code0 == COMPLEX_TYPE || code0 == VECTOR_TYPE)
    5846     12044735 :           && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
    5847              :               || code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE))
    5848              :         {
    5849     12044726 :           enum tree_code tcode0 = code0, tcode1 = code1;
    5850     12044726 :           doing_div_or_mod = true;
    5851     12044726 :           warn_for_div_by_zero (location, fold_for_warn (op1));
    5852              : 
    5853     12044726 :           if (tcode0 == COMPLEX_TYPE || tcode0 == VECTOR_TYPE)
    5854        57241 :             tcode0 = TREE_CODE (TREE_TYPE (TREE_TYPE (op0)));
    5855     12044726 :           if (tcode1 == COMPLEX_TYPE || tcode1 == VECTOR_TYPE)
    5856        29484 :             tcode1 = TREE_CODE (TREE_TYPE (TREE_TYPE (op1)));
    5857              : 
    5858     12044729 :           if (!((tcode0 == INTEGER_TYPE
    5859      5273851 :                  || (tcode0 == ENUMERAL_TYPE && code0 == VECTOR_TYPE))
    5860              :                 && (tcode1 == INTEGER_TYPE
    5861        94430 :                     || (tcode1 == ENUMERAL_TYPE && code1 == VECTOR_TYPE))))
    5862              :             resultcode = RDIV_EXPR;
    5863              :           else
    5864              :             {
    5865              :               /* When dividing two signed integers, we have to promote to int.
    5866              :                  unless we divide by a constant != -1.  Note that default
    5867              :                  conversion will have been performed on the operands at this
    5868              :                  point, so we have to dig out the original type to find out if
    5869              :                  it was unsigned.  */
    5870      6676451 :               tree stripped_op1 = tree_strip_any_location_wrapper (op1);
    5871      6676451 :               shorten = may_shorten_divmod (op0, stripped_op1);
    5872              :             }
    5873              : 
    5874              :           common = 1;
    5875              :         }
    5876              :       break;
    5877              : 
    5878      2808862 :     case BIT_AND_EXPR:
    5879      2808862 :     case BIT_IOR_EXPR:
    5880      2808862 :     case BIT_XOR_EXPR:
    5881      2808862 :       if ((code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
    5882      2808862 :           || (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE
    5883        21080 :               && !VECTOR_FLOAT_TYPE_P (type0)
    5884        21062 :               && !VECTOR_FLOAT_TYPE_P (type1)))
    5885              :         shorten = -1;
    5886              :       break;
    5887              : 
    5888      1517958 :     case TRUNC_MOD_EXPR:
    5889      1517958 :     case FLOOR_MOD_EXPR:
    5890      1517958 :       doing_div_or_mod = true;
    5891      1517958 :       warn_for_div_by_zero (location, fold_for_warn (op1));
    5892              : 
    5893      1517958 :       if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE
    5894           28 :           && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE
    5895      1517986 :           && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE)
    5896              :         common = 1;
    5897      1517930 :       else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
    5898              :         {
    5899              :           /* Although it would be tempting to shorten always here, that loses
    5900              :              on some targets, since the modulo instruction is undefined if the
    5901              :              quotient can't be represented in the computation mode.  We shorten
    5902              :              only if unsigned or if dividing by something we know != -1.  */
    5903      1517906 :           tree stripped_op1 = tree_strip_any_location_wrapper (op1);
    5904      1517906 :           shorten = may_shorten_divmod (op0, stripped_op1);
    5905      1517906 :           common = 1;
    5906              :         }
    5907              :       break;
    5908              : 
    5909     16079701 :     case TRUTH_ANDIF_EXPR:
    5910     16079701 :     case TRUTH_ORIF_EXPR:
    5911     16079701 :     case TRUTH_AND_EXPR:
    5912     16079701 :     case TRUTH_OR_EXPR:
    5913     16079701 :       if (!VECTOR_TYPE_P (type0) && gnu_vector_type_p (type1))
    5914              :         {
    5915            3 :           if (!COMPARISON_CLASS_P (op1))
    5916            3 :             op1 = cp_build_binary_op (EXPR_LOCATION (op1), NE_EXPR, op1,
    5917              :                                       build_zero_cst (type1), complain);
    5918            3 :           if (code == TRUTH_ANDIF_EXPR)
    5919              :             {
    5920            0 :               tree z = build_zero_cst (TREE_TYPE (op1));
    5921            0 :               return build_conditional_expr (location, op0, op1, z, complain);
    5922              :             }
    5923            3 :           else if (code == TRUTH_ORIF_EXPR)
    5924              :             {
    5925            3 :               tree m1 = build_all_ones_cst (TREE_TYPE (op1));
    5926            3 :               return build_conditional_expr (location, op0, m1, op1, complain);
    5927              :             }
    5928              :           else
    5929            0 :             gcc_unreachable ();
    5930              :         }
    5931     16079698 :       if (gnu_vector_type_p (type0)
    5932     16079698 :           && (!VECTOR_TYPE_P (type1) || gnu_vector_type_p (type1)))
    5933              :         {
    5934           24 :           if (!COMPARISON_CLASS_P (op0))
    5935           24 :             op0 = cp_build_binary_op (EXPR_LOCATION (op0), NE_EXPR, op0,
    5936              :                                       build_zero_cst (type0), complain);
    5937           24 :           if (!VECTOR_TYPE_P (type1))
    5938              :             {
    5939            9 :               tree m1 = build_all_ones_cst (TREE_TYPE (op0));
    5940            9 :               tree z = build_zero_cst (TREE_TYPE (op0));
    5941            9 :               op1 = build_conditional_expr (location, op1, m1, z, complain);
    5942              :             }
    5943           15 :           else if (!COMPARISON_CLASS_P (op1))
    5944           15 :             op1 = cp_build_binary_op (EXPR_LOCATION (op1), NE_EXPR, op1,
    5945              :                                       build_zero_cst (type1), complain);
    5946              : 
    5947           24 :           if (code == TRUTH_ANDIF_EXPR)
    5948              :             code = BIT_AND_EXPR;
    5949            9 :           else if (code == TRUTH_ORIF_EXPR)
    5950              :             code = BIT_IOR_EXPR;
    5951              :           else
    5952            0 :             gcc_unreachable ();
    5953              : 
    5954           24 :           return cp_build_binary_op (location, code, op0, op1, complain);
    5955              :         }
    5956              : 
    5957     16079674 :       if (warn_constant_logical_operand
    5958       122037 :           && (complain & tf_warning)
    5959       119626 :           && (code0 == INTEGER_TYPE || code0 == ENUMERAL_TYPE)
    5960        11187 :           && (code1 == INTEGER_TYPE || code1 == ENUMERAL_TYPE))
    5961              :         {
    5962         4858 :           tree cop0 = fold_for_warn (op0), cop1 = fold_for_warn (op1);
    5963         4858 :           const char *name
    5964              :             = ((code == TRUTH_ANDIF_EXPR || code == TRUTH_AND_EXPR)
    5965              :                ? "&&" : "||");
    5966         4943 :           auto enum_other_than_0_1 = [] (tree type) {
    5967           85 :             if (TREE_CODE (type) != ENUMERAL_TYPE)
    5968              :               return false;
    5969          154 :             for (tree l = TYPE_VALUES (type); l; l = TREE_CHAIN (l))
    5970              :               {
    5971          125 :                 tree v = DECL_INITIAL (TREE_VALUE (l));
    5972          125 :                 if (!integer_zerop (v) && !integer_onep (v))
    5973              :                   return true;
    5974              :               }
    5975              :             return false;
    5976              :           };
    5977        14526 :           auto diagnose_constant_logical_operand = [=] (tree val, tree type) {
    5978         9668 :             if (TREE_CODE (val) != INTEGER_CST || integer_zerop (val))
    5979         9511 :               return false;
    5980          157 :             if (integer_onep (val) && !enum_other_than_0_1 (type))
    5981              :               return false;
    5982           96 :             gcc_rich_location richloc (location);
    5983           96 :             richloc.add_fixit_replace (name + 1);
    5984           96 :             auto_diagnostic_group d;
    5985           96 :             if (warning_at (location, OPT_Wconstant_logical_operand,
    5986              :                             "use of logical %qs with constant operand %qE",
    5987              :                             name, val))
    5988           96 :               inform (&richloc, "use %qs for bitwise operation", name + 1);
    5989           96 :             return true;
    5990           96 :           };
    5991         4858 :           if (!diagnose_constant_logical_operand (cop1, orig_type1))
    5992         4810 :             diagnose_constant_logical_operand (cop0, orig_type0);
    5993              :         }
    5994              : 
    5995     16079674 :       result_type = boolean_type_node;
    5996     16079674 :       break;
    5997              : 
    5998              :       /* Shift operations: result has same type as first operand;
    5999              :          always convert second operand to int.
    6000              :          Also set SHORT_SHIFT if shifting rightward.  */
    6001              : 
    6002      1087354 :     case RSHIFT_EXPR:
    6003      1087354 :       if (gnu_vector_type_p (type0)
    6004          186 :           && code1 == INTEGER_TYPE
    6005      1087410 :           && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE)
    6006              :         {
    6007              :           result_type = type0;
    6008              :           converted = 1;
    6009              :         }
    6010      1087298 :       else if (gnu_vector_type_p (type0)
    6011          130 :                && gnu_vector_type_p (type1)
    6012          130 :                && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE
    6013          127 :                && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE
    6014      1087425 :                && known_eq (TYPE_VECTOR_SUBPARTS (type0),
    6015              :                             TYPE_VECTOR_SUBPARTS (type1)))
    6016              :         {
    6017              :           result_type = type0;
    6018              :           converted = 1;
    6019              :         }
    6020      1087171 :       else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
    6021              :         {
    6022      1087144 :           tree const_op1 = fold_for_warn (op1);
    6023      1087144 :           if (TREE_CODE (const_op1) != INTEGER_CST)
    6024       100560 :             const_op1 = op1;
    6025      1087144 :           result_type = type0;
    6026      1087144 :           doing_shift = true;
    6027      1087144 :           if (TREE_CODE (const_op1) == INTEGER_CST)
    6028              :             {
    6029       986584 :               if (tree_int_cst_lt (const_op1, integer_zero_node))
    6030              :                 {
    6031           48 :                   if ((complain & tf_warning)
    6032           48 :                       && c_inhibit_evaluation_warnings == 0)
    6033           36 :                     warning_at (location, OPT_Wshift_count_negative,
    6034              :                                 "right shift count is negative");
    6035              :                 }
    6036              :               else
    6037              :                 {
    6038       986536 :                   if (!integer_zerop (const_op1))
    6039       986315 :                     short_shift = 1;
    6040              : 
    6041       986536 :                   if (compare_tree_int (const_op1, TYPE_PRECISION (type0)) >= 0
    6042           46 :                       && (complain & tf_warning)
    6043       986582 :                       && c_inhibit_evaluation_warnings == 0)
    6044           34 :                     warning_at (location, OPT_Wshift_count_overflow,
    6045              :                                 "right shift count >= width of type");
    6046              :                 }
    6047              :             }
    6048              :           /* Avoid converting op1 to result_type later.  */
    6049              :           converted = 1;
    6050              :         }
    6051              :       break;
    6052              : 
    6053      3099381 :     case LSHIFT_EXPR:
    6054      3099381 :       if (gnu_vector_type_p (type0)
    6055          229 :           && code1 == INTEGER_TYPE
    6056      3099425 :           && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE)
    6057              :         {
    6058              :           result_type = type0;
    6059              :           converted = 1;
    6060              :         }
    6061      3099337 :       else if (gnu_vector_type_p (type0)
    6062          185 :                && gnu_vector_type_p (type1)
    6063          185 :                && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE
    6064          182 :                && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE
    6065      3099516 :                && known_eq (TYPE_VECTOR_SUBPARTS (type0),
    6066              :                             TYPE_VECTOR_SUBPARTS (type1)))
    6067              :         {
    6068              :           result_type = type0;
    6069              :           converted = 1;
    6070              :         }
    6071      3099158 :       else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
    6072              :         {
    6073      3099103 :           tree const_op0 = fold_for_warn (op0);
    6074      3099103 :           if (TREE_CODE (const_op0) != INTEGER_CST)
    6075       263749 :             const_op0 = op0;
    6076      3099103 :           tree const_op1 = fold_for_warn (op1);
    6077      3099103 :           if (TREE_CODE (const_op1) != INTEGER_CST)
    6078       217788 :             const_op1 = op1;
    6079      3099103 :           result_type = type0;
    6080      3099103 :           doing_shift = true;
    6081      3099103 :           if (TREE_CODE (const_op0) == INTEGER_CST
    6082      2835354 :               && tree_int_cst_sgn (const_op0) < 0
    6083          280 :               && !TYPE_OVERFLOW_WRAPS (type0)
    6084          196 :               && (complain & tf_warning)
    6085      3099299 :               && c_inhibit_evaluation_warnings == 0)
    6086          196 :             warning_at (location, OPT_Wshift_negative_value,
    6087              :                         "left shift of negative value");
    6088      3099103 :           if (TREE_CODE (const_op1) == INTEGER_CST)
    6089              :             {
    6090      2881315 :               if (tree_int_cst_lt (const_op1, integer_zero_node))
    6091              :                 {
    6092           57 :                   if ((complain & tf_warning)
    6093           57 :                       && c_inhibit_evaluation_warnings == 0)
    6094           39 :                     warning_at (location, OPT_Wshift_count_negative,
    6095              :                                 "left shift count is negative");
    6096              :                 }
    6097      2881258 :               else if (compare_tree_int (const_op1,
    6098      2881258 :                                          TYPE_PRECISION (type0)) >= 0)
    6099              :                 {
    6100           83 :                   if ((complain & tf_warning)
    6101           61 :                       && c_inhibit_evaluation_warnings == 0)
    6102           45 :                     warning_at (location, OPT_Wshift_count_overflow,
    6103              :                                 "left shift count >= width of type");
    6104              :                 }
    6105      2881175 :               else if (TREE_CODE (const_op0) == INTEGER_CST
    6106      2655337 :                        && (complain & tf_warning))
    6107      2548873 :                 maybe_warn_shift_overflow (location, const_op0, const_op1);
    6108              :             }
    6109              :           /* Avoid converting op1 to result_type later.  */
    6110              :           converted = 1;
    6111              :         }
    6112              :       break;
    6113              : 
    6114     25544852 :     case EQ_EXPR:
    6115     25544852 :     case NE_EXPR:
    6116     25544852 :       if (gnu_vector_type_p (type0) && gnu_vector_type_p (type1))
    6117         2992 :         goto vector_compare;
    6118     25541860 :       if ((complain & tf_warning)
    6119     22688489 :           && c_inhibit_evaluation_warnings == 0
    6120     47153008 :           && (FLOAT_TYPE_P (type0) || FLOAT_TYPE_P (type1)))
    6121       784324 :         warning_at (location, OPT_Wfloat_equal,
    6122              :                     "comparing floating-point with %<==%> "
    6123              :                     "or %<!=%> is unsafe");
    6124     25541860 :       {
    6125     25541860 :         tree stripped_orig_op0 = tree_strip_any_location_wrapper (orig_op0);
    6126     25541860 :         tree stripped_orig_op1 = tree_strip_any_location_wrapper (orig_op1);
    6127     25541860 :         if ((complain & tf_warning_or_error)
    6128     25541860 :             && ((TREE_CODE (stripped_orig_op0) == STRING_CST
    6129           39 :                  && !integer_zerop (cp_fully_fold (op1)))
    6130     23150312 :                 || (TREE_CODE (stripped_orig_op1) == STRING_CST
    6131           68 :                     && !integer_zerop (cp_fully_fold (op0)))))
    6132           47 :           warning_at (location, OPT_Waddress,
    6133              :                       "comparison with string literal results in "
    6134              :                       "unspecified behavior");
    6135     25541813 :         else if (TREE_CODE (TREE_TYPE (orig_op0)) == ARRAY_TYPE
    6136     25541813 :                  && TREE_CODE (TREE_TYPE (orig_op1)) == ARRAY_TYPE)
    6137              :           {
    6138              :             /* P2865R5 made array comparisons ill-formed in C++26.  */
    6139           68 :             if (complain & tf_warning_or_error)
    6140           45 :               do_warn_array_compare (location, code, stripped_orig_op0,
    6141              :                                      stripped_orig_op1);
    6142           23 :             else if (cxx_dialect >= cxx26)
    6143            1 :               return error_mark_node;
    6144              :           }
    6145              :       }
    6146              : 
    6147     25541859 :       build_type = boolean_type_node;
    6148     25541859 :       if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
    6149              :            || code0 == COMPLEX_TYPE || code0 == ENUMERAL_TYPE)
    6150     21514443 :           && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
    6151              :               || code1 == COMPLEX_TYPE || code1 == ENUMERAL_TYPE))
    6152              :         short_compare = 1;
    6153        39429 :       else if (((code0 == POINTER_TYPE || TYPE_PTRDATAMEM_P (type0))
    6154      4024681 :                 && null_ptr_cst_p (orig_op1))
    6155              :                /* Handle, eg, (void*)0 (c++/43906), and more.  */
    6156      6399086 :                || (code0 == POINTER_TYPE
    6157      2296854 :                    && TYPE_PTR_P (type1) && integer_zerop (op1)))
    6158              :         {
    6159      1746123 :           if (TYPE_PTR_P (type1))
    6160        18681 :             result_type = composite_pointer_type (location,
    6161              :                                                   type0, type1, op0, op1,
    6162              :                                                   CPO_COMPARISON, complain);
    6163              :           else
    6164              :             result_type = type0;
    6165              : 
    6166      1746123 :           if (char_type_p (TREE_TYPE (orig_op1)))
    6167              :             {
    6168           10 :               auto_diagnostic_group d;
    6169           10 :               if (warning_at (location, OPT_Wpointer_compare,
    6170              :                               "comparison between pointer and zero character "
    6171              :                               "constant"))
    6172           10 :                 inform (location,
    6173              :                         "did you mean to dereference the pointer?");
    6174           10 :             }
    6175      1746123 :           warn_for_null_address (location, op0, complain);
    6176              :         }
    6177         3190 :       else if (((code1 == POINTER_TYPE || TYPE_PTRDATAMEM_P (type1))
    6178      2314360 :                 && null_ptr_cst_p (orig_op0))
    6179              :                /* Handle, eg, (void*)0 (c++/43906), and more.  */
    6180      4633389 :                || (code1 == POINTER_TYPE
    6181      2313082 :                    && TYPE_PTR_P (type0) && integer_zerop (op0)))
    6182              :         {
    6183          961 :           if (TYPE_PTR_P (type0))
    6184           68 :             result_type = composite_pointer_type (location,
    6185              :                                                   type0, type1, op0, op1,
    6186              :                                                   CPO_COMPARISON, complain);
    6187              :           else
    6188              :             result_type = type1;
    6189              : 
    6190          961 :           if (char_type_p (TREE_TYPE (orig_op0)))
    6191              :             {
    6192           10 :               auto_diagnostic_group d;
    6193           10 :               if (warning_at (location, OPT_Wpointer_compare,
    6194              :                              "comparison between pointer and zero character "
    6195              :                              "constant"))
    6196           10 :                 inform (location,
    6197              :                         "did you mean to dereference the pointer?");
    6198           10 :             }
    6199          961 :           warn_for_null_address (location, op1, complain);
    6200              :         }
    6201      2316180 :       else if ((code0 == POINTER_TYPE && code1 == POINTER_TYPE)
    6202        38133 :                || (TYPE_PTRDATAMEM_P (type0) && TYPE_PTRDATAMEM_P (type1)))
    6203      2278432 :         result_type = composite_pointer_type (location,
    6204              :                                               type0, type1, op0, op1,
    6205              :                                               CPO_COMPARISON, complain);
    6206        37748 :       else if (null_ptr_cst_p (orig_op0) && null_ptr_cst_p (orig_op1))
    6207              :         /* One of the operands must be of nullptr_t type.  */
    6208           67 :         result_type = TREE_TYPE (nullptr_node);
    6209        37681 :       else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
    6210              :         {
    6211           58 :           result_type = type0;
    6212           58 :           if (complain & tf_error)
    6213           56 :             permerror (location, "ISO C++ forbids comparison between "
    6214              :                        "pointer and integer");
    6215              :           else
    6216            2 :             return error_mark_node;
    6217              :         }
    6218        37623 :       else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
    6219              :         {
    6220        34967 :           result_type = type1;
    6221        34967 :           if (complain & tf_error)
    6222           69 :             permerror (location, "ISO C++ forbids comparison between "
    6223              :                        "pointer and integer");
    6224              :           else
    6225        34898 :             return error_mark_node;
    6226              :         }
    6227         2656 :       else if (TYPE_PTRMEMFUNC_P (type0) && null_ptr_cst_p (orig_op1))
    6228              :         {
    6229          212 :           if (TARGET_PTRMEMFUNC_VBIT_LOCATION
    6230              :               == ptrmemfunc_vbit_in_delta)
    6231              :             {
    6232              :               tree pfn0, delta0, e1, e2;
    6233              : 
    6234              :               if (TREE_SIDE_EFFECTS (op0))
    6235              :                 op0 = cp_save_expr (op0);
    6236              : 
    6237              :               pfn0 = pfn_from_ptrmemfunc (op0);
    6238              :               delta0 = delta_from_ptrmemfunc (op0);
    6239              :               {
    6240              :                 /* If we will warn below about a null-address compare
    6241              :                    involving the orig_op0 ptrmemfunc, we'd likely also
    6242              :                    warn about the pfn0's null-address compare, and
    6243              :                    that would be redundant, so suppress it.  */
    6244              :                 warning_sentinel ws (warn_address);
    6245              :                 e1 = cp_build_binary_op (location,
    6246              :                                          EQ_EXPR,
    6247              :                                          pfn0,
    6248              :                                          build_zero_cst (TREE_TYPE (pfn0)),
    6249              :                                          complain);
    6250              :               }
    6251              :               e2 = cp_build_binary_op (location,
    6252              :                                        BIT_AND_EXPR,
    6253              :                                        delta0,
    6254              :                                        integer_one_node,
    6255              :                                        complain);
    6256              : 
    6257              :               if (complain & tf_warning)
    6258              :                 maybe_warn_zero_as_null_pointer_constant (op1, input_location);
    6259              : 
    6260              :               e2 = cp_build_binary_op (location,
    6261              :                                        EQ_EXPR, e2, integer_zero_node,
    6262              :                                        complain);
    6263              :               op0 = cp_build_binary_op (location,
    6264              :                                         TRUTH_ANDIF_EXPR, e1, e2,
    6265              :                                         complain);
    6266              :               op1 = cp_convert (TREE_TYPE (op0), integer_one_node, complain);
    6267              :             }
    6268              :           else
    6269              :             {
    6270          212 :               op0 = build_ptrmemfunc_access_expr (op0, pfn_identifier);
    6271          212 :               op1 = cp_convert (TREE_TYPE (op0), op1, complain);
    6272              :             }
    6273          212 :           result_type = TREE_TYPE (op0);
    6274              : 
    6275          212 :           warn_for_null_address (location, orig_op0, complain);
    6276              :         }
    6277         2444 :       else if (TYPE_PTRMEMFUNC_P (type1) && null_ptr_cst_p (orig_op0))
    6278           36 :         return cp_build_binary_op (location, code, op1, op0, complain);
    6279         2408 :       else if (TYPE_PTRMEMFUNC_P (type0) && TYPE_PTRMEMFUNC_P (type1))
    6280              :         {
    6281          125 :           tree type;
    6282              :           /* E will be the final comparison.  */
    6283          125 :           tree e;
    6284              :           /* E1 and E2 are for scratch.  */
    6285          125 :           tree e1;
    6286          125 :           tree e2;
    6287          125 :           tree pfn0;
    6288          125 :           tree pfn1;
    6289          125 :           tree delta0;
    6290          125 :           tree delta1;
    6291              : 
    6292          125 :           type = composite_pointer_type (location, type0, type1, op0, op1,
    6293              :                                          CPO_COMPARISON, complain);
    6294              : 
    6295          125 :           if (!same_type_p (TREE_TYPE (op0), type))
    6296            6 :             op0 = cp_convert_and_check (type, op0, complain);
    6297          125 :           if (!same_type_p (TREE_TYPE (op1), type))
    6298            9 :             op1 = cp_convert_and_check (type, op1, complain);
    6299              : 
    6300          125 :           if (op0 == error_mark_node || op1 == error_mark_node)
    6301              :             return error_mark_node;
    6302              : 
    6303          122 :           if (TREE_SIDE_EFFECTS (op0))
    6304           61 :             op0 = cp_save_expr (op0);
    6305          122 :           if (TREE_SIDE_EFFECTS (op1))
    6306            3 :             op1 = cp_save_expr (op1);
    6307              : 
    6308          122 :           pfn0 = pfn_from_ptrmemfunc (op0);
    6309          122 :           pfn0 = cp_fully_fold (pfn0);
    6310              :           /* Avoid -Waddress warnings (c++/64877).  */
    6311          122 :           if (TREE_CODE (pfn0) == ADDR_EXPR)
    6312           16 :             suppress_warning (pfn0, OPT_Waddress);
    6313          122 :           pfn1 = pfn_from_ptrmemfunc (op1);
    6314          122 :           pfn1 = cp_fully_fold (pfn1);
    6315          122 :           delta0 = delta_from_ptrmemfunc (op0);
    6316          122 :           delta1 = delta_from_ptrmemfunc (op1);
    6317          122 :           if (TARGET_PTRMEMFUNC_VBIT_LOCATION
    6318              :               == ptrmemfunc_vbit_in_delta)
    6319              :             {
    6320              :               /* We generate:
    6321              : 
    6322              :                  (op0.pfn == op1.pfn
    6323              :                   && ((op0.delta == op1.delta)
    6324              :                        || (!op0.pfn && op0.delta & 1 == 0
    6325              :                            && op1.delta & 1 == 0))
    6326              : 
    6327              :                  The reason for the `!op0.pfn' bit is that a NULL
    6328              :                  pointer-to-member is any member with a zero PFN and
    6329              :                  LSB of the DELTA field is 0.  */
    6330              : 
    6331              :               e1 = cp_build_binary_op (location, BIT_AND_EXPR,
    6332              :                                        delta0,
    6333              :                                        integer_one_node,
    6334              :                                        complain);
    6335              :               e1 = cp_build_binary_op (location,
    6336              :                                        EQ_EXPR, e1, integer_zero_node,
    6337              :                                        complain);
    6338              :               e2 = cp_build_binary_op (location, BIT_AND_EXPR,
    6339              :                                        delta1,
    6340              :                                        integer_one_node,
    6341              :                                        complain);
    6342              :               e2 = cp_build_binary_op (location,
    6343              :                                        EQ_EXPR, e2, integer_zero_node,
    6344              :                                        complain);
    6345              :               e1 = cp_build_binary_op (location,
    6346              :                                        TRUTH_ANDIF_EXPR, e2, e1,
    6347              :                                        complain);
    6348              :               e2 = cp_build_binary_op (location, EQ_EXPR,
    6349              :                                        pfn0,
    6350              :                                        build_zero_cst (TREE_TYPE (pfn0)),
    6351              :                                        complain);
    6352              :               e2 = cp_build_binary_op (location,
    6353              :                                        TRUTH_ANDIF_EXPR, e2, e1, complain);
    6354              :               e1 = cp_build_binary_op (location,
    6355              :                                        EQ_EXPR, delta0, delta1, complain);
    6356              :               e1 = cp_build_binary_op (location,
    6357              :                                        TRUTH_ORIF_EXPR, e1, e2, complain);
    6358              :             }
    6359              :           else
    6360              :             {
    6361              :               /* We generate:
    6362              : 
    6363              :                  (op0.pfn == op1.pfn
    6364              :                  && (!op0.pfn || op0.delta == op1.delta))
    6365              : 
    6366              :                  The reason for the `!op0.pfn' bit is that a NULL
    6367              :                  pointer-to-member is any member with a zero PFN; the
    6368              :                  DELTA field is unspecified.  */
    6369              : 
    6370          122 :               e1 = cp_build_binary_op (location,
    6371              :                                        EQ_EXPR, delta0, delta1, complain);
    6372          122 :               e2 = cp_build_binary_op (location,
    6373              :                                        EQ_EXPR,
    6374              :                                        pfn0,
    6375          122 :                                        build_zero_cst (TREE_TYPE (pfn0)),
    6376              :                                        complain);
    6377          122 :               e1 = cp_build_binary_op (location,
    6378              :                                        TRUTH_ORIF_EXPR, e1, e2, complain);
    6379              :             }
    6380          122 :           e2 = build2 (EQ_EXPR, boolean_type_node, pfn0, pfn1);
    6381          122 :           e = cp_build_binary_op (location,
    6382              :                                   TRUTH_ANDIF_EXPR, e2, e1, complain);
    6383          122 :           if (code == EQ_EXPR)
    6384              :             return e;
    6385           30 :           return cp_build_binary_op (location,
    6386           30 :                                      EQ_EXPR, e, integer_zero_node, complain);
    6387              :         }
    6388              :       /* [expr.eq]: "If both operands are of type std::meta::info,
    6389              :          comparison is defined as follows..."  */
    6390         2283 :       else if (code0 == META_TYPE && code1 == META_TYPE)
    6391              :         result_type = type0;
    6392              :       else
    6393              :         {
    6394           22 :           gcc_assert (!TYPE_PTRMEMFUNC_P (type0)
    6395              :                       || !same_type_p (TYPE_PTRMEMFUNC_FN_TYPE (type0),
    6396              :                                        type1));
    6397           22 :           gcc_assert (!TYPE_PTRMEMFUNC_P (type1)
    6398              :                       || !same_type_p (TYPE_PTRMEMFUNC_FN_TYPE (type1),
    6399              :                                        type0));
    6400              :         }
    6401              : 
    6402              :       break;
    6403              : 
    6404          241 :     case MAX_EXPR:
    6405          241 :     case MIN_EXPR:
    6406          241 :       if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
    6407          241 :            && (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
    6408              :         shorten = 1;
    6409            0 :       else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
    6410            0 :         result_type = composite_pointer_type (location,
    6411              :                                               type0, type1, op0, op1,
    6412              :                                               CPO_COMPARISON, complain);
    6413              :       break;
    6414              : 
    6415     25375491 :     case LE_EXPR:
    6416     25375491 :     case GE_EXPR:
    6417     25375491 :     case LT_EXPR:
    6418     25375491 :     case GT_EXPR:
    6419     25375491 :     case SPACESHIP_EXPR:
    6420     25375491 :       if (TREE_CODE (orig_op0) == STRING_CST
    6421     25375491 :           || TREE_CODE (orig_op1) == STRING_CST)
    6422              :         {
    6423            0 :           if (complain & tf_warning)
    6424            0 :             warning_at (location, OPT_Waddress,
    6425              :                         "comparison with string literal results "
    6426              :                         "in unspecified behavior");
    6427              :         }
    6428     25375491 :       else if (TREE_CODE (TREE_TYPE (orig_op0)) == ARRAY_TYPE
    6429          224 :                && TREE_CODE (TREE_TYPE (orig_op1)) == ARRAY_TYPE
    6430     25375606 :                && code != SPACESHIP_EXPR)
    6431              :         {
    6432           96 :           if (complain & tf_warning_or_error)
    6433           51 :             do_warn_array_compare (location, code,
    6434              :                                    tree_strip_any_location_wrapper (orig_op0),
    6435              :                                    tree_strip_any_location_wrapper (orig_op1));
    6436           45 :           else if (cxx_dialect >= cxx26)
    6437            1 :             return error_mark_node;
    6438              :         }
    6439              : 
    6440     25375490 :       if (gnu_vector_type_p (type0) && gnu_vector_type_p (type1))
    6441              :         {
    6442         7727 :         vector_compare:
    6443         7727 :           tree intt;
    6444         7727 :           if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (type0),
    6445         7727 :                                                           TREE_TYPE (type1))
    6446         7727 :               && !vector_types_compatible_elements_p (type0, type1))
    6447              :             {
    6448            3 :               if (complain & tf_error)
    6449              :                 {
    6450            3 :                   auto_diagnostic_group d;
    6451            3 :                   error_at (location, "comparing vectors with different "
    6452              :                                       "element types");
    6453            3 :                   inform (location, "operand types are %qT and %qT",
    6454              :                           type0, type1);
    6455            3 :                 }
    6456            3 :               return error_mark_node;
    6457              :             }
    6458              : 
    6459         7724 :           if (maybe_ne (TYPE_VECTOR_SUBPARTS (type0),
    6460        15448 :                         TYPE_VECTOR_SUBPARTS (type1)))
    6461              :             {
    6462            3 :               if (complain & tf_error)
    6463              :                 {
    6464            3 :                   auto_diagnostic_group d;
    6465            3 :                   error_at (location, "comparing vectors with different "
    6466              :                                       "number of elements");
    6467            3 :                   inform (location, "operand types are %qT and %qT",
    6468              :                           type0, type1);
    6469            3 :                 }
    6470            3 :               return error_mark_node;
    6471              :             }
    6472              : 
    6473              :           /* It's not precisely specified how the usual arithmetic
    6474              :              conversions apply to the vector types.  Here, we use
    6475              :              the unsigned type if one of the operands is signed and
    6476              :              the other one is unsigned.  */
    6477         7721 :           if (TYPE_UNSIGNED (type0) != TYPE_UNSIGNED (type1))
    6478              :             {
    6479           36 :               if (!TYPE_UNSIGNED (type0))
    6480           36 :                 op0 = build1 (VIEW_CONVERT_EXPR, type1, op0);
    6481              :               else
    6482            0 :                 op1 = build1 (VIEW_CONVERT_EXPR, type0, op1);
    6483           36 :               warning_at (location, OPT_Wsign_compare, "comparison between "
    6484              :                           "types %qT and %qT", type0, type1);
    6485              :             }
    6486              : 
    6487         7721 :           if (resultcode == SPACESHIP_EXPR)
    6488              :             {
    6489            3 :               if (complain & tf_error)
    6490            3 :                 sorry_at (location, "three-way comparison of vectors");
    6491            3 :               return error_mark_node;
    6492              :             }
    6493              : 
    6494         7718 :           if (VECTOR_BOOLEAN_TYPE_P (type0) && VECTOR_BOOLEAN_TYPE_P (type1))
    6495              :             result_type = type0;
    6496              :           else
    6497              :             {
    6498              :               /* Always construct signed integer vector type.  */
    6499         7718 :               auto intmode = SCALAR_TYPE_MODE (TREE_TYPE (type0));
    6500         7718 :               auto nelts = TYPE_VECTOR_SUBPARTS (type0);
    6501              : 
    6502        15436 :               intt = c_common_type_for_size (GET_MODE_BITSIZE (intmode), 0);
    6503         7718 :               if (!intt)
    6504              :                 {
    6505            0 :                   if (complain & tf_error)
    6506            0 :                     error_at (location, "could not find an integer type "
    6507            0 :                                 "of the same size as %qT", TREE_TYPE (type0));
    6508            0 :                   return error_mark_node;
    6509              :                 }
    6510         7718 :               result_type = build_opaque_vector_type (intt, nelts);
    6511              :             }
    6512         7718 :           return build_vec_cmp (resultcode, result_type, op0, op1);
    6513              :         }
    6514     25370755 :       build_type = boolean_type_node;
    6515     25370755 :       if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
    6516              :            || code0 == ENUMERAL_TYPE)
    6517     22816604 :            && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
    6518              :                || code1 == ENUMERAL_TYPE))
    6519              :         short_compare = 1;
    6520      2554254 :       else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
    6521      2553977 :         result_type = composite_pointer_type (location,
    6522              :                                               type0, type1, op0, op1,
    6523              :                                               CPO_COMPARISON, complain);
    6524           73 :       else if ((code0 == POINTER_TYPE && null_ptr_cst_p (orig_op1))
    6525          205 :                || (code1 == POINTER_TYPE && null_ptr_cst_p (orig_op0))
    6526          428 :                || (null_ptr_cst_p (orig_op0) && null_ptr_cst_p (orig_op1)))
    6527              :         {
    6528              :           /* Core Issue 1512 made this ill-formed.  */
    6529          190 :           if (complain & tf_error)
    6530          186 :             error_at (location, "ordered comparison of pointer with "
    6531              :                       "integer zero (%qT and %qT)", type0, type1);
    6532          190 :           return error_mark_node;
    6533              :         }
    6534           87 :       else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
    6535              :         {
    6536            0 :           result_type = type0;
    6537            0 :           if (complain & tf_error)
    6538            0 :             permerror (location, "ISO C++ forbids comparison between "
    6539              :                        "pointer and integer");
    6540              :           else
    6541            0 :             return error_mark_node;
    6542              :         }
    6543           87 :       else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
    6544              :         {
    6545           24 :           result_type = type1;
    6546           24 :           if (complain & tf_error)
    6547           24 :             permerror (location, "ISO C++ forbids comparison between "
    6548              :                        "pointer and integer");
    6549              :           else
    6550            0 :             return error_mark_node;
    6551              :         }
    6552              : 
    6553     25370565 :       if ((code0 == POINTER_TYPE || code1 == POINTER_TYPE)
    6554      2554002 :           && !processing_template_decl
    6555     27711008 :           && sanitize_flags_p (SANITIZE_POINTER_COMPARE))
    6556              :         {
    6557           49 :           op0 = cp_save_expr (op0);
    6558           49 :           op1 = cp_save_expr (op1);
    6559              : 
    6560           49 :           tree tt = builtin_decl_explicit (BUILT_IN_ASAN_POINTER_COMPARE);
    6561           49 :           instrument_expr = build_call_expr_loc (location, tt, 2, op0, op1);
    6562              :         }
    6563              : 
    6564              :       break;
    6565              : 
    6566            0 :     case UNORDERED_EXPR:
    6567            0 :     case ORDERED_EXPR:
    6568            0 :     case UNLT_EXPR:
    6569            0 :     case UNLE_EXPR:
    6570            0 :     case UNGT_EXPR:
    6571            0 :     case UNGE_EXPR:
    6572            0 :     case UNEQ_EXPR:
    6573            0 :       build_type = integer_type_node;
    6574            0 :       if (code0 != REAL_TYPE || code1 != REAL_TYPE)
    6575              :         {
    6576            0 :           if (complain & tf_error)
    6577            0 :             error ("unordered comparison on non-floating-point argument");
    6578            0 :           return error_mark_node;
    6579              :         }
    6580              :       common = 1;
    6581              :       break;
    6582              : 
    6583              :     default:
    6584              :       break;
    6585              :     }
    6586              : 
    6587    136778781 :   if (((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE
    6588              :         || code0 == ENUMERAL_TYPE)
    6589    112397751 :        && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
    6590              :            || code1 == COMPLEX_TYPE || code1 == ENUMERAL_TYPE)))
    6591              :     arithmetic_types_p = 1;
    6592              :   else
    6593              :     {
    6594     24764045 :       arithmetic_types_p = 0;
    6595              :       /* Vector arithmetic is only allowed when both sides are vectors.  */
    6596     24764045 :       if (gnu_vector_type_p (type0) && gnu_vector_type_p (type1))
    6597              :         {
    6598        60323 :           if (!tree_int_cst_equal (TYPE_SIZE (type0), TYPE_SIZE (type1))
    6599        60323 :               || !vector_types_compatible_elements_p (type0, type1))
    6600              :             {
    6601           18 :               if (complain & tf_error)
    6602              :                 {
    6603              :                   /* "location" already embeds the locations of the
    6604              :                      operands, so we don't need to add them separately
    6605              :                      to richloc.  */
    6606           18 :                   rich_location richloc (line_table, location);
    6607           18 :                   binary_op_error (&richloc, code, type0, type1);
    6608           18 :                 }
    6609           18 :               return error_mark_node;
    6610              :             }
    6611              :           arithmetic_types_p = 1;
    6612              :         }
    6613              :     }
    6614              :   /* Determine the RESULT_TYPE, if it is not already known.  */
    6615    136778763 :   if (!result_type
    6616    136778763 :       && arithmetic_types_p
    6617    107754057 :       && (shorten || common || short_compare))
    6618              :     {
    6619    107753956 :       result_type = cp_common_type (type0, type1);
    6620    107753956 :       if (result_type == error_mark_node)
    6621              :         {
    6622            6 :           tree t1 = type0;
    6623            6 :           tree t2 = type1;
    6624            6 :           if (TREE_CODE (t1) == COMPLEX_TYPE)
    6625            0 :             t1 = TREE_TYPE (t1);
    6626            6 :           if (TREE_CODE (t2) == COMPLEX_TYPE)
    6627            0 :             t2 = TREE_TYPE (t2);
    6628            6 :           gcc_checking_assert (TREE_CODE (t1) == REAL_TYPE
    6629              :                                && TREE_CODE (t2) == REAL_TYPE
    6630              :                                && (extended_float_type_p (t1)
    6631              :                                    || extended_float_type_p (t2))
    6632              :                                && cp_compare_floating_point_conversion_ranks
    6633              :                                     (t1, t2) == 3);
    6634            6 :           if (complain & tf_error)
    6635              :             {
    6636            6 :               rich_location richloc (line_table, location);
    6637            6 :               binary_op_error (&richloc, code, type0, type1);
    6638            6 :             }
    6639            6 :           return error_mark_node;
    6640              :         }
    6641    107753950 :       if (complain & tf_warning)
    6642     97927789 :         do_warn_double_promotion (result_type, type0, type1,
    6643              :                                   "implicit conversion from %qH to %qI "
    6644              :                                   "to match other operand of binary "
    6645              :                                   "expression", location);
    6646    107753950 :       if (do_warn_enum_conversions (location, code, TREE_TYPE (orig_op0),
    6647    107753950 :                                     TREE_TYPE (orig_op1), complain))
    6648            6 :         return error_mark_node;
    6649              :     }
    6650    136778751 :   if (may_need_excess_precision
    6651    101619367 :       && (orig_type0 != type0 || orig_type1 != type1)
    6652        42493 :       && build_type == NULL_TREE
    6653        42493 :       && result_type)
    6654              :     {
    6655        32512 :       gcc_assert (common);
    6656        32512 :       semantic_result_type = cp_common_type (orig_type0, orig_type1);
    6657        32512 :       if (semantic_result_type == error_mark_node)
    6658              :         {
    6659            0 :           tree t1 = orig_type0;
    6660            0 :           tree t2 = orig_type1;
    6661            0 :           if (TREE_CODE (t1) == COMPLEX_TYPE)
    6662            0 :             t1 = TREE_TYPE (t1);
    6663            0 :           if (TREE_CODE (t2) == COMPLEX_TYPE)
    6664            0 :             t2 = TREE_TYPE (t2);
    6665            0 :           gcc_checking_assert (TREE_CODE (t1) == REAL_TYPE
    6666              :                                && TREE_CODE (t2) == REAL_TYPE
    6667              :                                && (extended_float_type_p (t1)
    6668              :                                    || extended_float_type_p (t2))
    6669              :                                && cp_compare_floating_point_conversion_ranks
    6670              :                                     (t1, t2) == 3);
    6671            0 :           if (complain & tf_error)
    6672              :             {
    6673            0 :               rich_location richloc (line_table, location);
    6674            0 :               binary_op_error (&richloc, code, type0, type1);
    6675            0 :             }
    6676            0 :           return error_mark_node;
    6677              :         }
    6678              :     }
    6679              : 
    6680    136778751 :   if (code == SPACESHIP_EXPR)
    6681              :     {
    6682       586955 :       iloc_sentinel s (location);
    6683              : 
    6684       586955 :       tree orig_type0 = TREE_TYPE (orig_op0);
    6685       586955 :       tree_code orig_code0 = TREE_CODE (orig_type0);
    6686       586955 :       tree orig_type1 = TREE_TYPE (orig_op1);
    6687       586955 :       tree_code orig_code1 = TREE_CODE (orig_type1);
    6688       586955 :       if (!result_type || result_type == error_mark_node)
    6689              :         /* Nope.  */
    6690              :         result_type = NULL_TREE;
    6691       586934 :       else if ((orig_code0 == BOOLEAN_TYPE) != (orig_code1 == BOOLEAN_TYPE))
    6692              :         /* "If one of the operands is of type bool and the other is not, the
    6693              :            program is ill-formed."  */
    6694              :         result_type = NULL_TREE;
    6695       586931 :       else if (code0 == POINTER_TYPE && orig_code0 != POINTER_TYPE
    6696           19 :                && code1 == POINTER_TYPE && orig_code1 != POINTER_TYPE)
    6697              :         /* We only do array/function-to-pointer conversion if "at least one of
    6698              :            the operands is of pointer type".  */
    6699              :         result_type = NULL_TREE;
    6700       586912 :       else if (TYPE_PTRFN_P (result_type) || NULLPTR_TYPE_P (result_type))
    6701              :         /* <=> no longer supports equality relations.  */
    6702              :         result_type = NULL_TREE;
    6703       586909 :       else if (orig_code0 == ENUMERAL_TYPE && orig_code1 == ENUMERAL_TYPE
    6704       586939 :                && !(same_type_ignoring_top_level_qualifiers_p
    6705           30 :                     (orig_type0, orig_type1)))
    6706              :         /* "If both operands have arithmetic types, or one operand has integral
    6707              :            type and the other operand has unscoped enumeration type, the usual
    6708              :            arithmetic conversions are applied to the operands."  So we don't do
    6709              :            arithmetic conversions if the operands both have enumeral type.  */
    6710              :         result_type = NULL_TREE;
    6711       586894 :       else if ((orig_code0 == ENUMERAL_TYPE && orig_code1 == REAL_TYPE)
    6712       586888 :                || (orig_code0 == REAL_TYPE && orig_code1 == ENUMERAL_TYPE))
    6713              :         /* [depr.arith.conv.enum]: Three-way comparisons between such operands
    6714              :            [where one is of enumeration type and the other is of a different
    6715              :            enumeration type or a floating-point type] are ill-formed.  */
    6716              :         result_type = NULL_TREE;
    6717              : 
    6718       586882 :       if (result_type)
    6719              :         {
    6720       586882 :           build_type = spaceship_type (result_type, complain);
    6721       586882 :           if (build_type == error_mark_node)
    6722              :             return error_mark_node;
    6723              :         }
    6724              : 
    6725       586940 :       if (result_type && arithmetic_types_p)
    6726              :         {
    6727              :           /* If a narrowing conversion is required, other than from an integral
    6728              :              type to a floating point type, the program is ill-formed.  */
    6729       276468 :           bool ok = true;
    6730       276468 :           if (TREE_CODE (result_type) == REAL_TYPE
    6731          554 :               && CP_INTEGRAL_TYPE_P (orig_type0))
    6732              :             /* OK */;
    6733       276461 :           else if (!check_narrowing (result_type, orig_op0, complain))
    6734       276468 :             ok = false;
    6735       276468 :           if (TREE_CODE (result_type) == REAL_TYPE
    6736          554 :               && CP_INTEGRAL_TYPE_P (orig_type1))
    6737              :             /* OK */;
    6738       276461 :           else if (!check_narrowing (result_type, orig_op1, complain))
    6739              :             ok = false;
    6740       276468 :           if (!ok && !(complain & tf_error))
    6741            2 :             return error_mark_node;
    6742              :         }
    6743       586955 :     }
    6744              : 
    6745    136778734 :   if (!result_type)
    6746              :     {
    6747          550 :       if (complain & tf_error)
    6748              :         {
    6749          210 :           binary_op_rich_location richloc (location,
    6750          210 :                                            orig_op0, orig_op1, true);
    6751          210 :           error_at (&richloc,
    6752              :                     "invalid operands of types %qT and %qT to binary %qO",
    6753          210 :                     TREE_TYPE (orig_op0), TREE_TYPE (orig_op1), code);
    6754          210 :         }
    6755          550 :       return error_mark_node;
    6756              :     }
    6757              : 
    6758              :   /* If we're in a template, the only thing we need to know is the
    6759              :      RESULT_TYPE.  */
    6760    136778184 :   if (processing_template_decl)
    6761              :     {
    6762              :       /* Since the middle-end checks the type when doing a build2, we
    6763              :          need to build the tree in pieces.  This built tree will never
    6764              :          get out of the front-end as we replace it when instantiating
    6765              :          the template.  */
    6766     61689878 :       tree tmp = build2 (resultcode,
    6767              :                          build_type ? build_type : result_type,
    6768              :                          NULL_TREE, op1);
    6769     38842144 :       TREE_OPERAND (tmp, 0) = op0;
    6770     38842144 :       if (semantic_result_type)
    6771            0 :         tmp = build1 (EXCESS_PRECISION_EXPR, semantic_result_type, tmp);
    6772     38842144 :       return tmp;
    6773              :     }
    6774              : 
    6775              :   /* Remember the original type; RESULT_TYPE might be changed later on
    6776              :      by shorten_binary_op.  */
    6777     97936040 :   tree orig_type = result_type;
    6778              : 
    6779     97936040 :   if (arithmetic_types_p)
    6780              :     {
    6781     84139323 :       bool first_complex = (code0 == COMPLEX_TYPE);
    6782     84139323 :       bool second_complex = (code1 == COMPLEX_TYPE);
    6783     84139323 :       int none_complex = (!first_complex && !second_complex);
    6784              : 
    6785              :       /* Adapted from patch for c/24581.  */
    6786     84139323 :       if (first_complex != second_complex
    6787       157801 :           && (code == PLUS_EXPR
    6788              :               || code == MINUS_EXPR
    6789       157801 :               || code == MULT_EXPR
    6790        41270 :               || (code == TRUNC_DIV_EXPR && first_complex))
    6791       144294 :           && TREE_CODE (TREE_TYPE (result_type)) == REAL_TYPE
    6792     84283456 :           && flag_signed_zeros)
    6793              :         {
    6794              :           /* An operation on mixed real/complex operands must be
    6795              :              handled specially, but the language-independent code can
    6796              :              more easily optimize the plain complex arithmetic if
    6797              :              -fno-signed-zeros.  */
    6798       144133 :           tree real_type = TREE_TYPE (result_type);
    6799       144133 :           tree real, imag;
    6800       144133 :           if (first_complex)
    6801              :             {
    6802       111085 :               if (TREE_TYPE (op0) != result_type)
    6803            6 :                 op0 = cp_convert_and_check (result_type, op0, complain);
    6804       111085 :               if (TREE_TYPE (op1) != real_type)
    6805           26 :                 op1 = cp_convert_and_check (real_type, op1, complain);
    6806              :             }
    6807              :           else
    6808              :             {
    6809        33048 :               if (TREE_TYPE (op0) != real_type)
    6810           31 :                 op0 = cp_convert_and_check (real_type, op0, complain);
    6811        33048 :               if (TREE_TYPE (op1) != result_type)
    6812           32 :                 op1 = cp_convert_and_check (result_type, op1, complain);
    6813              :             }
    6814       144133 :           if (TREE_CODE (op0) == ERROR_MARK || TREE_CODE (op1) == ERROR_MARK)
    6815            0 :             return error_mark_node;
    6816       144133 :           if (first_complex)
    6817              :             {
    6818       111085 :               op0 = cp_save_expr (op0);
    6819       111085 :               real = cp_build_unary_op (REALPART_EXPR, op0, true, complain);
    6820       111085 :               imag = cp_build_unary_op (IMAGPART_EXPR, op0, true, complain);
    6821       111085 :               switch (code)
    6822              :                 {
    6823        55519 :                 case MULT_EXPR:
    6824        55519 :                 case TRUNC_DIV_EXPR:
    6825        55519 :                   op1 = cp_save_expr (op1);
    6826        55519 :                   imag = build2 (resultcode, real_type, imag, op1);
    6827              :                   /* Fall through.  */
    6828       111085 :                 case PLUS_EXPR:
    6829       111085 :                 case MINUS_EXPR:
    6830       111085 :                   real = build2 (resultcode, real_type, real, op1);
    6831       111085 :                   break;
    6832            0 :                 default:
    6833            0 :                   gcc_unreachable();
    6834              :                 }
    6835              :             }
    6836              :           else
    6837              :             {
    6838        33048 :               op1 = cp_save_expr (op1);
    6839        33048 :               real = cp_build_unary_op (REALPART_EXPR, op1, true, complain);
    6840        33048 :               imag = cp_build_unary_op (IMAGPART_EXPR, op1, true, complain);
    6841        33048 :               switch (code)
    6842              :                 {
    6843          638 :                 case MULT_EXPR:
    6844          638 :                   op0 = cp_save_expr (op0);
    6845          638 :                   imag = build2 (resultcode, real_type, op0, imag);
    6846              :                   /* Fall through.  */
    6847        17301 :                 case PLUS_EXPR:
    6848        17301 :                   real = build2 (resultcode, real_type, op0, real);
    6849        17301 :                   break;
    6850        15747 :                 case MINUS_EXPR:
    6851        15747 :                   real = build2 (resultcode, real_type, op0, real);
    6852        15747 :                   imag = build1 (NEGATE_EXPR, real_type, imag);
    6853        15747 :                   break;
    6854            0 :                 default:
    6855            0 :                   gcc_unreachable();
    6856              :                 }
    6857              :             }
    6858       144133 :           result = build2 (COMPLEX_EXPR, result_type, real, imag);
    6859       144133 :           if (semantic_result_type)
    6860           24 :             result = build1 (EXCESS_PRECISION_EXPR, semantic_result_type,
    6861              :                              result);
    6862       144133 :           return result;
    6863              :         }
    6864              : 
    6865              :       /* For certain operations (which identify themselves by shorten != 0)
    6866              :          if both args were extended from the same smaller type,
    6867              :          do the arithmetic in that type and then extend.
    6868              : 
    6869              :          shorten !=0 and !=1 indicates a bitwise operation.
    6870              :          For them, this optimization is safe only if
    6871              :          both args are zero-extended or both are sign-extended.
    6872              :          Otherwise, we might change the result.
    6873              :          E.g., (short)-1 | (unsigned short)-1 is (int)-1
    6874              :          but calculated in (unsigned short) it would be (unsigned short)-1.  */
    6875              : 
    6876     83995190 :       if (shorten && none_complex)
    6877              :         {
    6878      6758846 :           final_type = result_type;
    6879      6758846 :           result_type = shorten_binary_op (result_type, op0, op1,
    6880              :                                            shorten == -1);
    6881              :         }
    6882              : 
    6883              :       /* Shifts can be shortened if shifting right.  */
    6884              : 
    6885     83995190 :       if (short_shift)
    6886              :         {
    6887       817012 :           int unsigned_arg;
    6888       817012 :           tree arg0 = get_narrower (op0, &unsigned_arg);
    6889              :           /* We're not really warning here but when we set short_shift we
    6890              :              used fold_for_warn to fold the operand.  */
    6891       817012 :           tree const_op1 = fold_for_warn (op1);
    6892              : 
    6893       817012 :           final_type = result_type;
    6894              : 
    6895       817012 :           if (arg0 == op0 && final_type == TREE_TYPE (op0))
    6896       741308 :             unsigned_arg = TYPE_UNSIGNED (TREE_TYPE (op0));
    6897              : 
    6898       817012 :           if (TYPE_PRECISION (TREE_TYPE (arg0)) < TYPE_PRECISION (result_type)
    6899         2142 :               && tree_int_cst_sgn (const_op1) > 0
    6900              :               /* We can shorten only if the shift count is less than the
    6901              :                  number of bits in the smaller type size.  */
    6902         2142 :               && compare_tree_int (const_op1,
    6903         2142 :                                    TYPE_PRECISION (TREE_TYPE (arg0))) < 0
    6904              :               /* We cannot drop an unsigned shift after sign-extension.  */
    6905       819129 :               && (!TYPE_UNSIGNED (final_type) || unsigned_arg))
    6906              :             {
    6907              :               /* Do an unsigned shift if the operand was zero-extended.  */
    6908         2110 :               result_type
    6909         2110 :                 = c_common_signed_or_unsigned_type (unsigned_arg,
    6910         2110 :                                                     TREE_TYPE (arg0));
    6911              :               /* Convert value-to-be-shifted to that type.  */
    6912         2110 :               if (TREE_TYPE (op0) != result_type)
    6913         2110 :                 op0 = convert (result_type, op0);
    6914              :               converted = 1;
    6915              :             }
    6916              :         }
    6917              : 
    6918              :       /* Comparison operations are shortened too but differently.
    6919              :          They identify themselves by setting short_compare = 1.  */
    6920              : 
    6921     83995190 :       if (short_compare)
    6922              :         {
    6923              :           /* We call shorten_compare only for diagnostics.  */
    6924     28729143 :           tree xop0 = fold_simple (op0);
    6925     28729143 :           tree xop1 = fold_simple (op1);
    6926     28729143 :           tree xresult_type = result_type;
    6927     28729143 :           enum tree_code xresultcode = resultcode;
    6928     28729143 :           shorten_compare (location, &xop0, &xop1, &xresult_type,
    6929              :                            &xresultcode);
    6930              :         }
    6931              : 
    6932     55265960 :       if ((short_compare || code == MIN_EXPR || code == MAX_EXPR)
    6933     28729332 :           && warn_sign_compare
    6934              :           /* Do not warn until the template is instantiated; we cannot
    6935              :              bound the ranges of the arguments until that point.  */
    6936       343006 :           && !processing_template_decl
    6937       343006 :           && (complain & tf_warning)
    6938       335000 :           && c_inhibit_evaluation_warnings == 0
    6939              :           /* Even unsigned enum types promote to signed int.  We don't
    6940              :              want to issue -Wsign-compare warnings for this case.  */
    6941       318565 :           && !enum_cast_to_int (orig_op0)
    6942     84313755 :           && !enum_cast_to_int (orig_op1))
    6943              :         {
    6944       318558 :           warn_for_sign_compare (location, orig_op0, orig_op1, op0, op1,
    6945              :                                  result_type, resultcode);
    6946              :         }
    6947              :     }
    6948              : 
    6949              :   /* If CONVERTED is zero, both args will be converted to type RESULT_TYPE.
    6950              :      Then the expression will be built.
    6951              :      It will be given type FINAL_TYPE if that is nonzero;
    6952              :      otherwise, it will be given type RESULT_TYPE.  */
    6953     97791907 :   if (! converted)
    6954              :     {
    6955     94164414 :       warning_sentinel w (warn_sign_conversion, short_compare);
    6956     94164414 :       if (!same_type_p (TREE_TYPE (op0), result_type))
    6957      4093895 :         op0 = cp_convert_and_check (result_type, op0, complain);
    6958     94164414 :       if (!same_type_p (TREE_TYPE (op1), result_type))
    6959     18124197 :         op1 = cp_convert_and_check (result_type, op1, complain);
    6960              : 
    6961     94164414 :       if (op0 == error_mark_node || op1 == error_mark_node)
    6962           58 :         return error_mark_node;
    6963     94164414 :     }
    6964              : 
    6965     97791849 :   if (build_type == NULL_TREE)
    6966     62909101 :     build_type = result_type;
    6967              : 
    6968     97791849 :   if (doing_shift
    6969      3626844 :       && flag_strong_eval_order == 2
    6970      3529889 :       && TREE_SIDE_EFFECTS (op1)
    6971     97812792 :       && !processing_template_decl)
    6972              :     {
    6973              :       /* In C++17, in both op0 << op1 and op0 >> op1 op0 is sequenced before
    6974              :          op1, so if op1 has side-effects, use SAVE_EXPR around op0.  */
    6975        20943 :       op0 = cp_save_expr (op0);
    6976        20943 :       instrument_expr = op0;
    6977              :     }
    6978              : 
    6979     97791849 :   if (sanitize_flags_p ((SANITIZE_SHIFT
    6980              :                          | SANITIZE_DIVIDE
    6981              :                          | SANITIZE_FLOAT_DIVIDE
    6982              :                          | SANITIZE_SI_OVERFLOW))
    6983        13415 :       && current_function_decl != NULL_TREE
    6984        11021 :       && !processing_template_decl
    6985     97802870 :       && (doing_div_or_mod || doing_shift))
    6986              :     {
    6987              :       /* OP0 and/or OP1 might have side-effects.  */
    6988          939 :       op0 = cp_save_expr (op0);
    6989          939 :       op1 = cp_save_expr (op1);
    6990          939 :       op0 = fold_non_dependent_expr (op0, complain);
    6991          939 :       op1 = fold_non_dependent_expr (op1, complain);
    6992          939 :       tree instrument_expr1 = NULL_TREE;
    6993          939 :       if (doing_div_or_mod
    6994          939 :           && sanitize_flags_p (SANITIZE_DIVIDE
    6995              :                                | SANITIZE_FLOAT_DIVIDE
    6996              :                                | SANITIZE_SI_OVERFLOW))
    6997              :         {
    6998              :           /* For diagnostics we want to use the promoted types without
    6999              :              shorten_binary_op.  So convert the arguments to the
    7000              :              original result_type.  */
    7001          475 :           tree cop0 = op0;
    7002          475 :           tree cop1 = op1;
    7003          475 :           if (TREE_TYPE (cop0) != orig_type)
    7004            6 :             cop0 = cp_convert (orig_type, op0, complain);
    7005          475 :           if (TREE_TYPE (cop1) != orig_type)
    7006           39 :             cop1 = cp_convert (orig_type, op1, complain);
    7007          475 :           instrument_expr1 = ubsan_instrument_division (location, cop0, cop1);
    7008              :         }
    7009          464 :       else if (doing_shift && sanitize_flags_p (SANITIZE_SHIFT))
    7010          383 :         instrument_expr1 = ubsan_instrument_shift (location, code, op0, op1);
    7011          939 :       if (instrument_expr != NULL)
    7012           18 :         instrument_expr = add_stmt_to_compound (instrument_expr,
    7013              :                                                 instrument_expr1);
    7014              :       else
    7015          921 :         instrument_expr = instrument_expr1;
    7016              :     }
    7017              : 
    7018     97791849 :   result = build2_loc (location, resultcode, build_type, op0, op1);
    7019     97791849 :   if (final_type != 0)
    7020      7575858 :     result = cp_convert (final_type, result, complain);
    7021              : 
    7022     97791849 :   if (instrument_expr != NULL)
    7023        21441 :     result = build2 (COMPOUND_EXPR, TREE_TYPE (result),
    7024              :                      instrument_expr, result);
    7025              : 
    7026     97791849 :   if (resultcode == SPACESHIP_EXPR && !processing_template_decl)
    7027       493821 :     result = get_target_expr (result, complain);
    7028              : 
    7029     97791849 :   if (semantic_result_type)
    7030        32488 :     result = build1 (EXCESS_PRECISION_EXPR, semantic_result_type, result);
    7031              : 
    7032     97791849 :   if (!c_inhibit_evaluation_warnings)
    7033              :     {
    7034     82842853 :       if (!processing_template_decl)
    7035              :         {
    7036     82842853 :           op0 = cp_fully_fold (op0);
    7037              :           /* Only consider the second argument if the first isn't overflowed.  */
    7038     82842853 :           if (!CONSTANT_CLASS_P (op0) || TREE_OVERFLOW_P (op0))
    7039              :             return result;
    7040     23202291 :           op1 = cp_fully_fold (op1);
    7041     23202291 :           if (!CONSTANT_CLASS_P (op1) || TREE_OVERFLOW_P (op1))
    7042              :             return result;
    7043              :         }
    7044            0 :       else if (!CONSTANT_CLASS_P (op0) || !CONSTANT_CLASS_P (op1)
    7045            0 :                || TREE_OVERFLOW_P (op0) || TREE_OVERFLOW_P (op1))
    7046              :         return result;
    7047              : 
    7048     17876809 :       tree result_ovl = fold_build2 (resultcode, build_type, op0, op1);
    7049     17876809 :       if (TREE_OVERFLOW_P (result_ovl))
    7050          190 :         overflow_warning (location, result_ovl);
    7051              :     }
    7052              : 
    7053              :   return result;
    7054              : }
    7055              : 
    7056              : /* Build a VEC_PERM_EXPR.
    7057              :    This is a simple wrapper for c_build_vec_perm_expr.  */
    7058              : tree
    7059        17586 : build_x_vec_perm_expr (location_t loc,
    7060              :                         tree arg0, tree arg1, tree arg2,
    7061              :                         tsubst_flags_t complain)
    7062              : {
    7063        17586 :   tree orig_arg0 = arg0;
    7064        17586 :   tree orig_arg1 = arg1;
    7065        17586 :   tree orig_arg2 = arg2;
    7066        17586 :   if (processing_template_decl)
    7067              :     {
    7068           19 :       if (type_dependent_expression_p (arg0)
    7069           13 :           || type_dependent_expression_p (arg1)
    7070           32 :           || type_dependent_expression_p (arg2))
    7071            6 :         return build_min_nt_loc (loc, VEC_PERM_EXPR, arg0, arg1, arg2);
    7072              :     }
    7073        17580 :   tree exp = c_build_vec_perm_expr (loc, arg0, arg1, arg2, complain & tf_error);
    7074        17580 :   if (processing_template_decl && exp != error_mark_node)
    7075           13 :     return build_min_non_dep (VEC_PERM_EXPR, exp, orig_arg0,
    7076           13 :                               orig_arg1, orig_arg2);
    7077              :   return exp;
    7078              : }
    7079              : 
    7080              : /* Build a VEC_PERM_EXPR.
    7081              :    This is a simple wrapper for c_build_shufflevector.  */
    7082              : tree
    7083        41953 : build_x_shufflevector (location_t loc, vec<tree, va_gc> *args,
    7084              :                        tsubst_flags_t complain)
    7085              : {
    7086        41953 :   tree arg0 = (*args)[0];
    7087        41953 :   tree arg1 = (*args)[1];
    7088        41953 :   if (processing_template_decl)
    7089              :     {
    7090          355 :       for (unsigned i = 0; i < args->length (); ++i)
    7091          339 :         if (i <= 1
    7092          339 :             ? type_dependent_expression_p ((*args)[i])
    7093           61 :             : instantiation_dependent_expression_p ((*args)[i]))
    7094              :           {
    7095          243 :             tree exp = build_min_nt_call_vec (NULL, args);
    7096          243 :             CALL_EXPR_IFN (exp) = IFN_SHUFFLEVECTOR;
    7097          243 :             return exp;
    7098              :           }
    7099              :     }
    7100        41710 :   auto_vec<tree, 16> mask;
    7101       564442 :   for (unsigned i = 2; i < args->length (); ++i)
    7102              :     {
    7103       522732 :       tree idx = fold_non_dependent_expr ((*args)[i], complain);
    7104       522732 :       mask.safe_push (idx);
    7105              :     }
    7106        41710 :   tree exp = c_build_shufflevector (loc, arg0, arg1, mask, complain & tf_error);
    7107        41710 :   if (processing_template_decl && exp != error_mark_node)
    7108              :     {
    7109           16 :       exp = build_min_non_dep_call_vec (exp, NULL, args);
    7110           16 :       CALL_EXPR_IFN (exp) = IFN_SHUFFLEVECTOR;
    7111              :     }
    7112        41710 :   return exp;
    7113        41710 : }
    7114              : 
    7115              : /* Return a tree for the sum or difference (RESULTCODE says which)
    7116              :    of pointer PTROP and integer INTOP.  */
    7117              : 
    7118              : static tree
    7119      5405353 : cp_pointer_int_sum (location_t loc, enum tree_code resultcode, tree ptrop,
    7120              :                     tree intop, tsubst_flags_t complain)
    7121              : {
    7122      5405353 :   tree res_type = TREE_TYPE (ptrop);
    7123              : 
    7124              :   /* pointer_int_sum() uses size_in_bytes() on the TREE_TYPE(res_type)
    7125              :      in certain circumstance (when it's valid to do so).  So we need
    7126              :      to make sure it's complete.  We don't need to check here, if we
    7127              :      can actually complete it at all, as those checks will be done in
    7128              :      pointer_int_sum() anyway.  */
    7129      5405353 :   complete_type (TREE_TYPE (res_type));
    7130              : 
    7131      5405353 :   return pointer_int_sum (loc, resultcode, ptrop,
    7132      5405353 :                           intop, complain & tf_warning_or_error);
    7133              : }
    7134              : 
    7135              : /* Return a tree for the difference of pointers OP0 and OP1.
    7136              :    The resulting tree has type int.  If POINTER_SUBTRACT sanitization is
    7137              :    enabled, assign to INSTRUMENT_EXPR call to libsanitizer.  */
    7138              : 
    7139              : static tree
    7140      1447072 : pointer_diff (location_t loc, tree op0, tree op1, tree ptrtype,
    7141              :               tsubst_flags_t complain, tree *instrument_expr)
    7142              : {
    7143      1447072 :   tree result, inttype;
    7144      1447072 :   tree restype = ptrdiff_type_node;
    7145      1447072 :   tree target_type = TREE_TYPE (ptrtype);
    7146              : 
    7147      1447072 :   if (!complete_type_or_maybe_complain (target_type, NULL_TREE, complain))
    7148            9 :     return error_mark_node;
    7149              : 
    7150      1447063 :   if (VOID_TYPE_P (target_type))
    7151              :     {
    7152            0 :       if (complain & tf_error)
    7153            0 :         permerror (loc, "ISO C++ forbids using pointer of "
    7154              :                    "type %<void *%> in subtraction");
    7155              :       else
    7156            0 :         return error_mark_node;
    7157              :     }
    7158      1447063 :   if (TREE_CODE (target_type) == FUNCTION_TYPE)
    7159              :     {
    7160            9 :       if (complain & tf_error)
    7161            3 :         permerror (loc, "ISO C++ forbids using pointer to "
    7162              :                    "a function in subtraction");
    7163              :       else
    7164            6 :         return error_mark_node;
    7165              :     }
    7166      1447057 :   if (TREE_CODE (target_type) == METHOD_TYPE)
    7167              :     {
    7168            0 :       if (complain & tf_error)
    7169            0 :         permerror (loc, "ISO C++ forbids using pointer to "
    7170              :                    "a method in subtraction");
    7171              :       else
    7172            0 :         return error_mark_node;
    7173              :     }
    7174      2894114 :   else if (!verify_type_context (loc, TCTX_POINTER_ARITH,
    7175      1447057 :                                  TREE_TYPE (TREE_TYPE (op0)),
    7176              :                                  !(complain & tf_error))
    7177      2894114 :            || !verify_type_context (loc, TCTX_POINTER_ARITH,
    7178      1447057 :                                     TREE_TYPE (TREE_TYPE (op1)),
    7179              :                                     !(complain & tf_error)))
    7180            0 :     return error_mark_node;
    7181              : 
    7182              :   /* Determine integer type result of the subtraction.  This will usually
    7183              :      be the same as the result type (ptrdiff_t), but may need to be a wider
    7184              :      type if pointers for the address space are wider than ptrdiff_t.  */
    7185      1447057 :   if (TYPE_PRECISION (restype) < TYPE_PRECISION (TREE_TYPE (op0)))
    7186            0 :     inttype = c_common_type_for_size (TYPE_PRECISION (TREE_TYPE (op0)), 0);
    7187              :   else
    7188              :     inttype = restype;
    7189              : 
    7190      1447057 :   if (!processing_template_decl
    7191      1447057 :       && sanitize_flags_p (SANITIZE_POINTER_SUBTRACT))
    7192              :     {
    7193           84 :       op0 = save_expr (op0);
    7194           84 :       op1 = save_expr (op1);
    7195              : 
    7196           84 :       tree tt = builtin_decl_explicit (BUILT_IN_ASAN_POINTER_SUBTRACT);
    7197           84 :       *instrument_expr = build_call_expr_loc (loc, tt, 2, op0, op1);
    7198              :     }
    7199              : 
    7200              :   /* First do the subtraction, then build the divide operator
    7201              :      and only convert at the very end.
    7202              :      Do not do default conversions in case restype is a short type.  */
    7203              : 
    7204              :   /* POINTER_DIFF_EXPR requires a signed integer type of the same size as
    7205              :      pointers.  If some platform cannot provide that, or has a larger
    7206              :      ptrdiff_type to support differences larger than half the address
    7207              :      space, cast the pointers to some larger integer type and do the
    7208              :      computations in that type.  */
    7209      1447057 :   if (TYPE_PRECISION (inttype) > TYPE_PRECISION (TREE_TYPE (op0)))
    7210            0 :     op0 = cp_build_binary_op (loc,
    7211              :                               MINUS_EXPR,
    7212              :                               cp_convert (inttype, op0, complain),
    7213              :                               cp_convert (inttype, op1, complain),
    7214              :                               complain);
    7215              :   else
    7216      1447057 :     op0 = build2_loc (loc, POINTER_DIFF_EXPR, inttype, op0, op1);
    7217              : 
    7218              :   /* This generates an error if op1 is a pointer to an incomplete type.  */
    7219      1447057 :   if (!COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (op1))))
    7220              :     {
    7221            0 :       if (complain & tf_error)
    7222            0 :         error_at (loc, "invalid use of a pointer to an incomplete type in "
    7223              :                   "pointer arithmetic");
    7224              :       else
    7225            0 :         return error_mark_node;
    7226              :     }
    7227              : 
    7228      1447057 :   if (pointer_to_zero_sized_aggr_p (TREE_TYPE (op1)))
    7229              :     {
    7230           15 :       if (complain & tf_error)
    7231           15 :         error_at (loc, "arithmetic on pointer to an empty aggregate");
    7232              :       else
    7233            0 :         return error_mark_node;
    7234              :     }
    7235              : 
    7236      2894111 :   op1 = (TYPE_PTROB_P (ptrtype)
    7237      2894111 :          ? size_in_bytes_loc (loc, target_type)
    7238              :          : integer_one_node);
    7239              : 
    7240              :   /* Do the division.  */
    7241              : 
    7242      1447057 :   result = build2_loc (loc, EXACT_DIV_EXPR, inttype, op0,
    7243              :                        cp_convert (inttype, op1, complain));
    7244      1447057 :   return cp_convert (restype, result, complain);
    7245              : }
    7246              : 
    7247              : /* Construct and perhaps optimize a tree representation
    7248              :    for a unary operation.  CODE, a tree_code, specifies the operation
    7249              :    and XARG is the operand.  */
    7250              : 
    7251              : tree
    7252     62694477 : build_x_unary_op (location_t loc, enum tree_code code, cp_expr xarg,
    7253              :                   tree lookups, tsubst_flags_t complain)
    7254              : {
    7255     62694477 :   tree orig_expr = xarg;
    7256     62694477 :   tree exp;
    7257     62694477 :   int ptrmem = 0;
    7258     62694477 :   tree overload = NULL_TREE;
    7259              : 
    7260     62694477 :   if (processing_template_decl)
    7261              :     {
    7262     42841733 :       if (type_dependent_expression_p (xarg))
    7263              :         {
    7264     27976747 :           tree e = build_min_nt_loc (loc, code, xarg.get_value (), NULL_TREE);
    7265     27976747 :           TREE_TYPE (e) = build_dependent_operator_type (lookups, code, false);
    7266     27976747 :           return e;
    7267              :         }
    7268              :     }
    7269              : 
    7270     34717730 :   exp = NULL_TREE;
    7271              : 
    7272              :   /* [expr.unary.op] says:
    7273              : 
    7274              :        The address of an object of incomplete type can be taken.
    7275              : 
    7276              :      (And is just the ordinary address operator, not an overloaded
    7277              :      "operator &".)  However, if the type is a template
    7278              :      specialization, we must complete the type at this point so that
    7279              :      an overloaded "operator &" will be available if required.  */
    7280     34717730 :   if (code == ADDR_EXPR
    7281      4077774 :       && TREE_CODE (xarg) != TEMPLATE_ID_EXPR
    7282     38795096 :       && ((CLASS_TYPE_P (TREE_TYPE (xarg))
    7283      1793613 :            && !COMPLETE_TYPE_P (complete_type (TREE_TYPE (xarg))))
    7284      4068252 :           || (TREE_CODE (xarg) == OFFSET_REF)))
    7285              :     /* Don't look for a function.  */;
    7286              :   else
    7287     34646656 :     exp = build_new_op (loc, code, LOOKUP_NORMAL, xarg, NULL_TREE,
    7288              :                         NULL_TREE, lookups, &overload, complain);
    7289              : 
    7290     34717730 :   if (!exp && code == ADDR_EXPR)
    7291              :     {
    7292      4077460 :       if (is_overloaded_fn (xarg))
    7293              :         {
    7294       372855 :           tree fn = get_first_fn (xarg);
    7295       745710 :           if (DECL_CONSTRUCTOR_P (fn) || DECL_DESTRUCTOR_P (fn))
    7296              :             {
    7297           12 :               if (complain & tf_error)
    7298           21 :                 error_at (loc, DECL_CONSTRUCTOR_P (fn)
    7299              :                           ? G_("taking address of constructor %qD")
    7300              :                           : G_("taking address of destructor %qD"),
    7301              :                           fn);
    7302           12 :               return error_mark_node;
    7303              :             }
    7304              :         }
    7305              : 
    7306              :       /* A pointer to member-function can be formed only by saying
    7307              :          &X::mf.  */
    7308      4077442 :       if (!flag_ms_extensions && TREE_CODE (TREE_TYPE (xarg)) == METHOD_TYPE
    7309      4135839 :           && (TREE_CODE (xarg) != OFFSET_REF || !PTRMEM_OK_P (xarg)))
    7310              :         {
    7311            9 :           if (TREE_CODE (xarg) != OFFSET_REF
    7312            9 :               || !TYPE_P (TREE_OPERAND (xarg, 0)))
    7313              :             {
    7314            9 :               if (complain & tf_error)
    7315              :                 {
    7316            9 :                   auto_diagnostic_group d;
    7317            9 :                   error_at (loc, "invalid use of %qE to form a "
    7318              :                             "pointer-to-member-function", xarg.get_value ());
    7319            9 :                   if (TREE_CODE (xarg) != OFFSET_REF)
    7320            6 :                     inform (loc, "  a qualified-id is required");
    7321            9 :                 }
    7322            9 :               return error_mark_node;
    7323              :             }
    7324              :           else
    7325              :             {
    7326            0 :               if (complain & tf_error)
    7327            0 :                 error_at (loc, "parentheses around %qE cannot be used to "
    7328              :                           "form a pointer-to-member-function",
    7329              :                           xarg.get_value ());
    7330              :               else
    7331            0 :                 return error_mark_node;
    7332            0 :               PTRMEM_OK_P (xarg) = 1;
    7333              :             }
    7334              :         }
    7335              : 
    7336      4077439 :       if (TREE_CODE (xarg) == OFFSET_REF)
    7337              :         {
    7338        61945 :           ptrmem = PTRMEM_OK_P (xarg);
    7339              : 
    7340            0 :           if (!ptrmem && !flag_ms_extensions
    7341        61945 :               && TREE_CODE (TREE_TYPE (TREE_OPERAND (xarg, 1))) == METHOD_TYPE)
    7342              :             {
    7343              :               /* A single non-static member, make sure we don't allow a
    7344              :                  pointer-to-member.  */
    7345            0 :               xarg = build2 (OFFSET_REF, TREE_TYPE (xarg),
    7346            0 :                              TREE_OPERAND (xarg, 0),
    7347            0 :                              ovl_make (TREE_OPERAND (xarg, 1)));
    7348            0 :               PTRMEM_OK_P (xarg) = ptrmem;
    7349              :             }
    7350              :         }
    7351              : 
    7352      8154878 :       exp = cp_build_addr_expr_strict (xarg, complain);
    7353              : 
    7354      4077439 :       if (TREE_CODE (exp) == PTRMEM_CST)
    7355        60953 :         PTRMEM_CST_LOCATION (exp) = loc;
    7356              :       else
    7357      4016486 :         protected_set_expr_location (exp, loc);
    7358              :     }
    7359              : 
    7360     34717709 :   if (processing_template_decl && exp != error_mark_node)
    7361              :     {
    7362     14864835 :       if (overload != NULL_TREE)
    7363       187075 :         return (build_min_non_dep_op_overload
    7364       187075 :                 (code, exp, overload, orig_expr, integer_zero_node));
    7365              : 
    7366     14677760 :       exp = build_min_non_dep (code, exp, orig_expr,
    7367              :                                /*For {PRE,POST}{INC,DEC}REMENT_EXPR*/NULL_TREE);
    7368              :     }
    7369     34530634 :   if (TREE_CODE (exp) == ADDR_EXPR)
    7370      3280322 :     PTRMEM_OK_P (exp) = ptrmem;
    7371              :   return exp;
    7372              : }
    7373              : 
    7374              : /* Construct and perhaps optimize a tree representation
    7375              :    for __builtin_addressof operation.  ARG specifies the operand.  */
    7376              : 
    7377              : tree
    7378       654637 : cp_build_addressof (location_t loc, tree arg, tsubst_flags_t complain)
    7379              : {
    7380       654637 :   tree orig_expr = arg;
    7381              : 
    7382       654637 :   if (processing_template_decl)
    7383              :     {
    7384       165504 :       if (type_dependent_expression_p (arg))
    7385       165504 :         return build_min_nt_loc (loc, ADDRESSOF_EXPR, arg, NULL_TREE);
    7386              :     }
    7387              : 
    7388       978266 :   tree exp = cp_build_addr_expr_strict (arg, complain);
    7389              : 
    7390       489133 :   if (processing_template_decl && exp != error_mark_node)
    7391            0 :     exp = build_min_non_dep (ADDRESSOF_EXPR, exp, orig_expr, NULL_TREE);
    7392              :   return exp;
    7393              : }
    7394              : 
    7395              : /* Like c_common_truthvalue_conversion, but handle pointer-to-member
    7396              :    constants, where a null value is represented by an INTEGER_CST of
    7397              :    -1.  */
    7398              : 
    7399              : tree
    7400      7832296 : cp_truthvalue_conversion (tree expr, tsubst_flags_t complain)
    7401              : {
    7402      7832296 :   tree type = TREE_TYPE (expr);
    7403      7832296 :   location_t loc = cp_expr_loc_or_input_loc (expr);
    7404      6602573 :   if (TYPE_PTR_OR_PTRMEM_P (type)
    7405              :       /* Avoid ICE on invalid use of non-static member function.  */
    7406     14434582 :       || TREE_CODE (expr) == FUNCTION_DECL)
    7407      1230010 :     return cp_build_binary_op (loc, NE_EXPR, expr, nullptr_node, complain);
    7408              :   else
    7409      6602286 :     return c_common_truthvalue_conversion (loc, expr);
    7410              : }
    7411              : 
    7412              : /* Returns EXPR contextually converted to bool.  */
    7413              : 
    7414              : tree
    7415     75006161 : contextual_conv_bool (tree expr, tsubst_flags_t complain)
    7416              : {
    7417     75006161 :   return perform_implicit_conversion_flags (boolean_type_node, expr,
    7418     75006161 :                                             complain, LOOKUP_NORMAL);
    7419              : }
    7420              : 
    7421              : /* Just like cp_truthvalue_conversion, but we want a CLEANUP_POINT_EXPR.  This
    7422              :    is a low-level function; most callers should use maybe_convert_cond.  */
    7423              : 
    7424              : tree
    7425     51034131 : condition_conversion (tree expr)
    7426              : {
    7427     51034131 :   tree t = contextual_conv_bool (expr, tf_warning_or_error);
    7428     51034131 :   if (!processing_template_decl)
    7429     25102298 :     t = fold_build_cleanup_point_expr (boolean_type_node, t);
    7430     51034131 :   return t;
    7431              : }
    7432              : 
    7433              : /* Returns the address of T.  This function will fold away
    7434              :    ADDR_EXPR of INDIRECT_REF.  This is only for low-level usage;
    7435              :    most places should use cp_build_addr_expr instead.  */
    7436              : 
    7437              : tree
    7438    329376155 : build_address (tree t)
    7439              : {
    7440    329376155 :   if (error_operand_p (t) || !cxx_mark_addressable (t))
    7441           24 :     return error_mark_node;
    7442    329376131 :   gcc_checking_assert (TREE_CODE (t) != CONSTRUCTOR
    7443              :                        || processing_template_decl);
    7444    329376131 :   t = build_fold_addr_expr_loc (EXPR_LOCATION (t), t);
    7445    329376131 :   if (TREE_CODE (t) != ADDR_EXPR)
    7446     59048817 :     t = rvalue (t);
    7447              :   return t;
    7448              : }
    7449              : 
    7450              : /* Return a NOP_EXPR converting EXPR to TYPE.  */
    7451              : 
    7452              : tree
    7453    557614167 : build_nop (tree type, tree expr MEM_STAT_DECL)
    7454              : {
    7455    557614167 :   if (type == error_mark_node || error_operand_p (expr))
    7456              :     return expr;
    7457    557614093 :   return build1_loc (EXPR_LOCATION (expr), NOP_EXPR, type, expr PASS_MEM_STAT);
    7458              : }
    7459              : 
    7460              : /* Take the address of ARG, whatever that means under C++ semantics.
    7461              :    If STRICT_LVALUE is true, require an lvalue; otherwise, allow xvalues
    7462              :    and class rvalues as well.
    7463              : 
    7464              :    Nothing should call this function directly; instead, callers should use
    7465              :    cp_build_addr_expr or cp_build_addr_expr_strict.  */
    7466              : 
    7467              : static tree
    7468    256361898 : cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain)
    7469              : {
    7470    256361898 :   tree argtype;
    7471    256361898 :   tree val;
    7472              : 
    7473    256361898 :   if (!arg || error_operand_p (arg))
    7474           12 :     return error_mark_node;
    7475              : 
    7476    256361886 :   arg = mark_lvalue_use (arg);
    7477    256361886 :   if (error_operand_p (arg))
    7478            3 :     return error_mark_node;
    7479              : 
    7480    256361883 :   argtype = lvalue_type (arg);
    7481    256361883 :   location_t loc = cp_expr_loc_or_input_loc (arg);
    7482              : 
    7483    256361883 :   gcc_assert (!(identifier_p (arg) && IDENTIFIER_ANY_OP_P (arg)));
    7484              : 
    7485     15410588 :   if (TREE_CODE (arg) == COMPONENT_REF && type_unknown_p (arg)
    7486    256362077 :       && !really_overloaded_fn (arg))
    7487              :     {
    7488              :       /* They're trying to take the address of a unique non-static
    7489              :          member function.  This is ill-formed (except in MS-land),
    7490              :          but let's try to DTRT.
    7491              :          Note: We only handle unique functions here because we don't
    7492              :          want to complain if there's a static overload; non-unique
    7493              :          cases will be handled by instantiate_type.  But we need to
    7494              :          handle this case here to allow casts on the resulting PMF.
    7495              :          We could defer this in non-MS mode, but it's easier to give
    7496              :          a useful error here.  */
    7497              : 
    7498              :       /* Inside constant member functions, the `this' pointer
    7499              :          contains an extra const qualifier.  TYPE_MAIN_VARIANT
    7500              :          is used here to remove this const from the diagnostics
    7501              :          and the created OFFSET_REF.  */
    7502           70 :       tree base = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (arg, 0)));
    7503           70 :       tree fn = get_first_fn (TREE_OPERAND (arg, 1));
    7504           70 :       if (!mark_used (fn, complain) && !(complain & tf_error))
    7505            0 :         return error_mark_node;
    7506              :       /* Until microsoft headers are known to incorrectly take the address of
    7507              :          unqualified xobj member functions we should not support this
    7508              :          extension.
    7509              :          See comment in class.cc:resolve_address_of_overloaded_function for
    7510              :          the extended reasoning.  */
    7511           70 :       if (!flag_ms_extensions || DECL_XOBJ_MEMBER_FUNCTION_P (fn))
    7512              :         {
    7513           64 :           auto_diagnostic_group d;
    7514           64 :           tree name = DECL_NAME (fn);
    7515           64 :           if (!(complain & tf_error))
    7516            0 :             return error_mark_node;
    7517           64 :           else if (current_class_type
    7518           64 :                    && TREE_OPERAND (arg, 0) == current_class_ref)
    7519              :             /* An expression like &memfn.  */
    7520           31 :             if (!DECL_XOBJ_MEMBER_FUNCTION_P (fn))
    7521           21 :               permerror (loc,
    7522              :                          "ISO C++ forbids taking the address of an unqualified"
    7523              :                          " or parenthesized non-static member function to form"
    7524              :                          " a pointer to member function.  Say %<&%T::%D%>",
    7525              :                          base, name);
    7526              :             else
    7527           10 :               error_at (loc,
    7528              :                         "ISO C++ forbids taking the address of an unqualified"
    7529              :                         " or parenthesized non-static member function to form"
    7530              :                         " a pointer to explicit object member function");
    7531              :           else
    7532           33 :             if (!DECL_XOBJ_MEMBER_FUNCTION_P (fn))
    7533            9 :               permerror (loc,
    7534              :                          "ISO C++ forbids taking the address of a bound member"
    7535              :                          " function to form a pointer to member function."
    7536              :                          "  Say %<&%T::%D%>",
    7537              :                          base, name);
    7538              :             else
    7539           24 :               error_at (loc,
    7540              :                         "ISO C++ forbids taking the address of a bound member"
    7541              :                         " function to form a pointer to explicit object member"
    7542              :                         " function");
    7543           64 :           if (DECL_XOBJ_MEMBER_FUNCTION_P (fn))
    7544           34 :             inform (loc,
    7545              :                     "a pointer to explicit object member function can only be "
    7546              :                     "formed with %<&%T::%D%>", base, name);
    7547           64 :         }
    7548           70 :       arg = build_offset_ref (base, fn, /*address_p=*/true, complain);
    7549              :     }
    7550              : 
    7551              :   /* Uninstantiated types are all functions.  Taking the
    7552              :      address of a function is a no-op, so just return the
    7553              :      argument.  */
    7554    256361883 :   if (type_unknown_p (arg))
    7555         2956 :     return build1 (ADDR_EXPR, unknown_type_node, arg);
    7556              : 
    7557    256358927 :   if (TREE_CODE (arg) == OFFSET_REF)
    7558              :     /* We want a pointer to member; bypass all the code for actually taking
    7559              :        the address of something.  */
    7560        61114 :     goto offset_ref;
    7561              : 
    7562              :   /* Anything not already handled and not a true memory reference
    7563              :      is an error.  */
    7564    256297813 :   if (!FUNC_OR_METHOD_TYPE_P (argtype))
    7565              :     {
    7566    136040432 :       cp_lvalue_kind kind = lvalue_kind (arg);
    7567    136040432 :       if (kind == clk_none)
    7568              :         {
    7569           24 :           if (complain & tf_error)
    7570           24 :             lvalue_error (loc, lv_addressof);
    7571           24 :           return error_mark_node;
    7572              :         }
    7573    136040408 :       if (strict_lvalue && (kind & (clk_rvalueref|clk_class)))
    7574              :         {
    7575           36 :           if (!(complain & tf_error))
    7576            9 :             return error_mark_node;
    7577              :           /* Make this a permerror because we used to accept it.  */
    7578           27 :           permerror (loc, "taking address of rvalue");
    7579              :         }
    7580              :     }
    7581              : 
    7582    256297780 :   if (TYPE_REF_P (argtype))
    7583              :     {
    7584          236 :       tree type = build_pointer_type (TREE_TYPE (argtype));
    7585          236 :       arg = build1 (CONVERT_EXPR, type, arg);
    7586          236 :       return arg;
    7587              :     }
    7588    256297544 :   else if (pedantic && DECL_MAIN_P (tree_strip_any_location_wrapper (arg)))
    7589              :     {
    7590              :       /* ARM $3.4 */
    7591              :       /* Apparently a lot of autoconf scripts for C++ packages do this,
    7592              :          so only complain if -Wpedantic.  */
    7593            9 :       if (complain & (flag_pedantic_errors ? tf_error : tf_warning))
    7594            9 :         pedwarn (loc, OPT_Wpedantic,
    7595              :                  "ISO C++ forbids taking address of function %<::main%>");
    7596            0 :       else if (flag_pedantic_errors)
    7597            0 :         return error_mark_node;
    7598              :     }
    7599              : 
    7600              :   /* Let &* cancel out to simplify resulting code.  */
    7601    256297544 :   if (INDIRECT_REF_P (arg))
    7602              :     {
    7603     92233181 :       arg = TREE_OPERAND (arg, 0);
    7604     92233181 :       if (TYPE_REF_P (TREE_TYPE (arg)))
    7605              :         {
    7606     55137534 :           tree type = build_pointer_type (TREE_TYPE (TREE_TYPE (arg)));
    7607     55137534 :           arg = build1 (CONVERT_EXPR, type, arg);
    7608              :         }
    7609              :       else
    7610              :         /* Don't let this be an lvalue.  */
    7611     37095647 :         arg = rvalue (arg);
    7612     92233181 :       return arg;
    7613              :     }
    7614              : 
    7615              :   /* Handle complex lvalues (when permitted)
    7616              :      by reduction to simpler cases.  */
    7617    164064363 :   val = unary_complex_lvalue (ADDR_EXPR, arg);
    7618    164064363 :   if (val != 0)
    7619              :     return val;
    7620              : 
    7621    163590990 :   switch (TREE_CODE (arg))
    7622              :     {
    7623            0 :     CASE_CONVERT:
    7624            0 :     case FLOAT_EXPR:
    7625            0 :     case FIX_TRUNC_EXPR:
    7626              :       /* We should have handled this above in the lvalue_kind check.  */
    7627            0 :       gcc_unreachable ();
    7628        77812 :       break;
    7629              : 
    7630        77812 :     case BASELINK:
    7631        77812 :       arg = BASELINK_FUNCTIONS (arg);
    7632              :       /* Fall through.  */
    7633              : 
    7634        77812 :     case OVERLOAD:
    7635        77812 :       arg = OVL_FIRST (arg);
    7636              :       break;
    7637              : 
    7638        61114 :     case OFFSET_REF:
    7639        61114 :     offset_ref:
    7640              :       /* Turn a reference to a non-static data member into a
    7641              :          pointer-to-member.  */
    7642        61114 :       {
    7643        61114 :         tree type;
    7644        61114 :         tree t;
    7645              : 
    7646        61114 :         gcc_assert (PTRMEM_OK_P (arg));
    7647              : 
    7648        61114 :         t = TREE_OPERAND (arg, 1);
    7649        61114 :         if (TYPE_REF_P (TREE_TYPE (t)))
    7650              :           {
    7651           15 :             if (complain & tf_error)
    7652           15 :               error_at (loc,
    7653              :                         "cannot create pointer to reference member %qD", t);
    7654           15 :             return error_mark_node;
    7655              :           }
    7656              : 
    7657              :         /* Forming a pointer-to-member is a use of non-pure-virtual fns.  */
    7658        61099 :         if (TREE_CODE (t) == FUNCTION_DECL
    7659        58552 :             && !DECL_PURE_VIRTUAL_P (t)
    7660       119629 :             && !mark_used (t, complain) && !(complain & tf_error))
    7661            3 :           return error_mark_node;
    7662              : 
    7663              :         /* Pull out the function_decl for a single xobj member function, and
    7664              :            let the rest of this function handle it.  This is similar to how
    7665              :            static member functions are handled in the BASELINK case above.  */
    7666        61096 :         if (DECL_XOBJ_MEMBER_FUNCTION_P (t))
    7667              :           {
    7668              :             arg = t;
    7669              :             break;
    7670              :           }
    7671              : 
    7672        61030 :         type = build_ptrmem_type (context_for_name_lookup (t),
    7673        61030 :                                   TREE_TYPE (t));
    7674        61030 :         t = make_ptrmem_cst (type, t);
    7675        61030 :         return t;
    7676              :       }
    7677              : 
    7678              :     default:
    7679              :       break;
    7680              :     }
    7681              : 
    7682    163591056 :   if (argtype != error_mark_node)
    7683    163591056 :     argtype = build_pointer_type (argtype);
    7684              : 
    7685    163591056 :   if (bitfield_p (arg))
    7686              :     {
    7687           33 :       if (complain & tf_error)
    7688           33 :         error_at (loc, "attempt to take address of bit-field");
    7689           33 :       return error_mark_node;
    7690              :     }
    7691              : 
    7692              :   /* In a template, we are processing a non-dependent expression
    7693              :      so we can just form an ADDR_EXPR with the correct type.  */
    7694    163591023 :   if (processing_template_decl || TREE_CODE (arg) != COMPONENT_REF)
    7695              :     {
    7696    148650832 :       if (!mark_single_function (arg, complain))
    7697            3 :         return error_mark_node;
    7698    148650829 :       val = build_address (arg);
    7699    148650829 :       if (TREE_CODE (arg) == OFFSET_REF)
    7700            0 :         PTRMEM_OK_P (val) = PTRMEM_OK_P (arg);
    7701              :     }
    7702     14940191 :   else if (BASELINK_P (TREE_OPERAND (arg, 1)))
    7703              :     {
    7704           27 :       tree fn = BASELINK_FUNCTIONS (TREE_OPERAND (arg, 1));
    7705              : 
    7706           27 :       if (TREE_CODE (fn) == OVERLOAD && OVL_SINGLE_P (fn))
    7707           27 :         fn = OVL_FIRST (fn);
    7708              : 
    7709              :       /* We can only get here with a single static member
    7710              :          function.  */
    7711           27 :       gcc_assert (TREE_CODE (fn) == FUNCTION_DECL
    7712              :                   && DECL_STATIC_FUNCTION_P (fn));
    7713           27 :       if (!mark_used (fn, complain) && !(complain & tf_error))
    7714            0 :         return error_mark_node;
    7715           27 :       val = build_address (fn);
    7716           27 :       if (TREE_SIDE_EFFECTS (TREE_OPERAND (arg, 0)))
    7717              :         /* Do not lose object's side effects.  */
    7718           12 :         val = build2 (COMPOUND_EXPR, TREE_TYPE (val),
    7719           12 :                       TREE_OPERAND (arg, 0), val);
    7720              :     }
    7721              :   else
    7722              :     {
    7723     14940164 :       tree object = TREE_OPERAND (arg, 0);
    7724     14940164 :       tree field = TREE_OPERAND (arg, 1);
    7725     14940164 :       gcc_assert (same_type_ignoring_top_level_qualifiers_p
    7726              :                   (TREE_TYPE (object), decl_type_context (field)));
    7727     14940164 :       val = build_address (arg);
    7728              :     }
    7729              : 
    7730    163591020 :   if (TYPE_PTR_P (argtype)
    7731    163591020 :       && TREE_CODE (TREE_TYPE (argtype)) == METHOD_TYPE)
    7732              :     {
    7733         1078 :       build_ptrmemfunc_type (argtype);
    7734         1078 :       val = build_ptrmemfunc (argtype, val, 0,
    7735              :                               /*c_cast_p=*/false,
    7736              :                               complain);
    7737              :     }
    7738              : 
    7739              :   /* Ensure we have EXPR_LOCATION set for possible later diagnostics.  */
    7740    163591020 :   if (TREE_CODE (val) == ADDR_EXPR
    7741    163591020 :       && TREE_CODE (TREE_OPERAND (val, 0)) == FUNCTION_DECL)
    7742    115001800 :     SET_EXPR_LOCATION (val, input_location);
    7743              : 
    7744              :   return val;
    7745              : }
    7746              : 
    7747              : /* Take the address of ARG if it has one, even if it's an rvalue.  */
    7748              : 
    7749              : tree
    7750    251795326 : cp_build_addr_expr (tree arg, tsubst_flags_t complain)
    7751              : {
    7752    251795326 :   return cp_build_addr_expr_1 (arg, 0, complain);
    7753              : }
    7754              : 
    7755              : /* Take the address of ARG, but only if it's an lvalue.  */
    7756              : 
    7757              : static tree
    7758      4566572 : cp_build_addr_expr_strict (tree arg, tsubst_flags_t complain)
    7759              : {
    7760      4566572 :   return cp_build_addr_expr_1 (arg, 1, complain);
    7761              : }
    7762              : 
    7763              : /* C++: Must handle pointers to members.
    7764              : 
    7765              :    Perhaps type instantiation should be extended to handle conversion
    7766              :    from aggregates to types we don't yet know we want?  (Or are those
    7767              :    cases typically errors which should be reported?)
    7768              : 
    7769              :    NOCONVERT suppresses the default promotions (such as from short to int).  */
    7770              : 
    7771              : tree
    7772     30367603 : cp_build_unary_op (enum tree_code code, tree xarg, bool noconvert,
    7773              :                    tsubst_flags_t complain)
    7774              : {
    7775              :   /* No default_conversion here.  It causes trouble for ADDR_EXPR.  */
    7776     30367603 :   tree arg = xarg;
    7777     30367603 :   location_t location = cp_expr_loc_or_input_loc (arg);
    7778     30367603 :   tree argtype = 0;
    7779     30367603 :   tree eptype = NULL_TREE;
    7780     30367603 :   const char *errstring = NULL;
    7781     30367603 :   tree val;
    7782     30367603 :   const char *invalid_op_diag;
    7783              : 
    7784     30367603 :   if (!arg || error_operand_p (arg))
    7785            0 :     return error_mark_node;
    7786              : 
    7787     30367603 :   arg = resolve_nondeduced_context (arg, complain);
    7788              : 
    7789     60735206 :   if ((invalid_op_diag
    7790     30367603 :        = targetm.invalid_unary_op ((code == UNARY_PLUS_EXPR
    7791              :                                     ? CONVERT_EXPR
    7792              :                                     : code),
    7793     30367603 :                                    TREE_TYPE (arg))))
    7794              :     {
    7795            0 :       if (complain & tf_error)
    7796            0 :         error (invalid_op_diag);
    7797            0 :       return error_mark_node;
    7798              :     }
    7799              : 
    7800     30367603 :   if (TREE_CODE (arg) == EXCESS_PRECISION_EXPR)
    7801              :     {
    7802         6806 :       eptype = TREE_TYPE (arg);
    7803         6806 :       arg = TREE_OPERAND (arg, 0);
    7804              :     }
    7805              : 
    7806     30367603 :   switch (code)
    7807              :     {
    7808      2360026 :     case UNARY_PLUS_EXPR:
    7809      2360026 :     case NEGATE_EXPR:
    7810      2360026 :       {
    7811      2360026 :         int flags = WANT_ARITH | WANT_ENUM;
    7812              :         /* Unary plus (but not unary minus) is allowed on pointers.  */
    7813      2360026 :         if (code == UNARY_PLUS_EXPR)
    7814       159268 :           flags |= WANT_POINTER;
    7815      2360026 :         arg = build_expr_type_conversion (flags, arg, true);
    7816      2360026 :         if (!arg)
    7817           34 :           errstring = (code == NEGATE_EXPR
    7818           27 :                        ? _("wrong type argument to unary minus")
    7819            7 :                        : _("wrong type argument to unary plus"));
    7820              :         else
    7821              :           {
    7822      2359992 :             if (!noconvert && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (arg)))
    7823       666481 :               arg = cp_perform_integral_promotions (arg, complain);
    7824              : 
    7825              :             /* Make sure the result is not an lvalue: a unary plus or minus
    7826              :                expression is always a rvalue.  */
    7827      2359992 :             arg = rvalue (arg);
    7828              :           }
    7829              :       }
    7830              :       break;
    7831              : 
    7832       915024 :     case BIT_NOT_EXPR:
    7833       915024 :       if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
    7834              :         {
    7835           15 :           code = CONJ_EXPR;
    7836           15 :           if (!noconvert)
    7837              :             {
    7838           15 :               arg = cp_default_conversion (arg, complain);
    7839           15 :               if (arg == error_mark_node)
    7840              :                 return error_mark_node;
    7841              :             }
    7842              :         }
    7843       915009 :       else if (!(arg = build_expr_type_conversion (WANT_INT | WANT_ENUM
    7844              :                                                    | WANT_VECTOR_OR_COMPLEX,
    7845              :                                                    arg, true)))
    7846           16 :         errstring = _("wrong type argument to bit-complement");
    7847       914993 :       else if (!noconvert && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (arg)))
    7848              :         {
    7849              :           /* Warn if the expression has boolean value.  */
    7850       914638 :           if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE
    7851       914638 :               && (complain & tf_warning))
    7852              :             {
    7853           61 :               auto_diagnostic_group d;
    7854           61 :               if (warning_at (location, OPT_Wbool_operation,
    7855              :                               "%<~%> on an expression of type %<bool%>"))
    7856           42 :                 inform (location, "did you mean to use logical not (%<!%>)?");
    7857           61 :             }
    7858       914638 :           arg = cp_perform_integral_promotions (arg, complain);
    7859              :         }
    7860          355 :       else if (!noconvert && VECTOR_TYPE_P (TREE_TYPE (arg)))
    7861          355 :         arg = mark_rvalue_use (arg);
    7862              :       break;
    7863              : 
    7864            0 :     case ABS_EXPR:
    7865            0 :       if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, arg, true)))
    7866            0 :         errstring = _("wrong type argument to abs");
    7867            0 :       else if (!noconvert)
    7868              :         {
    7869            0 :           arg = cp_default_conversion (arg, complain);
    7870            0 :           if (arg == error_mark_node)
    7871              :             return error_mark_node;
    7872              :         }
    7873              :       break;
    7874              : 
    7875            0 :     case CONJ_EXPR:
    7876              :       /* Conjugating a real value is a no-op, but allow it anyway.  */
    7877            0 :       if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, arg, true)))
    7878            0 :         errstring = _("wrong type argument to conjugation");
    7879            0 :       else if (!noconvert)
    7880              :         {
    7881            0 :           arg = cp_default_conversion (arg, complain);
    7882            0 :           if (arg == error_mark_node)
    7883              :             return error_mark_node;
    7884              :         }
    7885              :       break;
    7886              : 
    7887     17698898 :     case TRUTH_NOT_EXPR:
    7888     17698898 :       if (gnu_vector_type_p (TREE_TYPE (arg)))
    7889           60 :         return cp_build_binary_op (input_location, EQ_EXPR, arg,
    7890           60 :                                    build_zero_cst (TREE_TYPE (arg)), complain);
    7891     17698838 :       arg = contextual_conv_bool (arg, complain);
    7892     17698838 :       if (arg != error_mark_node)
    7893              :         {
    7894     17698829 :           if (processing_template_decl)
    7895      8333890 :             return build1_loc (location, TRUTH_NOT_EXPR, boolean_type_node, arg);
    7896      9364939 :           val = invert_truthvalue_loc (location, arg);
    7897      9364939 :           if (obvalue_p (val))
    7898        12022 :             val = non_lvalue_loc (location, val);
    7899      9364939 :           return val;
    7900              :         }
    7901            9 :       errstring = _("in argument to unary !");
    7902            9 :       break;
    7903              : 
    7904              :     case NOP_EXPR:
    7905              :       break;
    7906              : 
    7907       444076 :     case REALPART_EXPR:
    7908       444076 :     case IMAGPART_EXPR:
    7909       444076 :       val = build_real_imag_expr (input_location, code, arg);
    7910       444076 :       if (eptype && TREE_CODE (eptype) == COMPLEX_EXPR)
    7911            0 :         val = build1_loc (input_location, EXCESS_PRECISION_EXPR,
    7912            0 :                           TREE_TYPE (eptype), val);
    7913              :       return val;
    7914              : 
    7915      8396098 :     case PREINCREMENT_EXPR:
    7916      8396098 :     case POSTINCREMENT_EXPR:
    7917      8396098 :     case PREDECREMENT_EXPR:
    7918      8396098 :     case POSTDECREMENT_EXPR:
    7919              :       /* Handle complex lvalues (when permitted)
    7920              :          by reduction to simpler cases.  */
    7921              : 
    7922      8396098 :       val = unary_complex_lvalue (code, arg);
    7923      8396098 :       if (val != 0)
    7924           32 :         goto return_build_unary_op;
    7925              : 
    7926      8396066 :       tree stripped_arg;
    7927      8396066 :       stripped_arg = tree_strip_any_location_wrapper (arg);
    7928      2058750 :       if ((VAR_P (stripped_arg) || TREE_CODE (stripped_arg) == PARM_DECL)
    7929      7779945 :           && !DECL_READ_P (stripped_arg)
    7930      9511824 :           && (VAR_P (stripped_arg) ? warn_unused_but_set_variable
    7931              :                                    : warn_unused_but_set_parameter) > 1)
    7932              :         {
    7933        10017 :           arg = mark_lvalue_use (arg);
    7934        10017 :           DECL_READ_P (stripped_arg) = 0;
    7935              :         }
    7936              :       else
    7937      8386049 :         arg = mark_lvalue_use (arg);
    7938              : 
    7939              :       /* Increment or decrement the real part of the value,
    7940              :          and don't change the imaginary part.  */
    7941      8396066 :       if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
    7942              :         {
    7943           18 :           tree real, imag;
    7944              : 
    7945           18 :           arg = cp_stabilize_reference (arg);
    7946           18 :           real = cp_build_unary_op (REALPART_EXPR, arg, true, complain);
    7947           18 :           imag = cp_build_unary_op (IMAGPART_EXPR, arg, true, complain);
    7948           18 :           real = cp_build_unary_op (code, real, true, complain);
    7949           18 :           if (real == error_mark_node || imag == error_mark_node)
    7950              :             return error_mark_node;
    7951           15 :           val = build2 (COMPLEX_EXPR, TREE_TYPE (arg), real, imag);
    7952           15 :           goto return_build_unary_op;
    7953              :         }
    7954              : 
    7955              :       /* Report invalid types.  */
    7956              : 
    7957      8396048 :       if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_POINTER,
    7958              :                                               arg, true)))
    7959              :         {
    7960           36 :           if (code == PREINCREMENT_EXPR)
    7961            9 :             errstring = _("no pre-increment operator for type");
    7962           27 :           else if (code == POSTINCREMENT_EXPR)
    7963            9 :             errstring = _("no post-increment operator for type");
    7964           18 :           else if (code == PREDECREMENT_EXPR)
    7965            9 :             errstring = _("no pre-decrement operator for type");
    7966              :           else
    7967            9 :             errstring = _("no post-decrement operator for type");
    7968              :           break;
    7969              :         }
    7970      8396012 :       else if (arg == error_mark_node)
    7971              :         return error_mark_node;
    7972              : 
    7973              :       /* Report something read-only.  */
    7974              : 
    7975      8396009 :       if (CP_TYPE_CONST_P (TREE_TYPE (arg))
    7976      8396009 :           || TREE_READONLY (arg))
    7977              :         {
    7978          119 :           if (complain & tf_error)
    7979          119 :             cxx_readonly_error (location, arg,
    7980          119 :                                 ((code == PREINCREMENT_EXPR
    7981          119 :                                   || code == POSTINCREMENT_EXPR)
    7982              :                                  ? lv_increment : lv_decrement));
    7983              :           else
    7984            0 :             return error_mark_node;
    7985              :         }
    7986              : 
    7987      8396009 :       {
    7988      8396009 :         tree inc;
    7989      8396009 :         tree declared_type = unlowered_expr_type (arg);
    7990              : 
    7991      8396009 :         argtype = TREE_TYPE (arg);
    7992              : 
    7993              :         /* ARM $5.2.5 last annotation says this should be forbidden.  */
    7994      8396009 :         if (TREE_CODE (argtype) == ENUMERAL_TYPE)
    7995              :           {
    7996            0 :             if (complain & tf_error)
    7997            0 :               permerror (location, (code == PREINCREMENT_EXPR
    7998            0 :                                     || code == POSTINCREMENT_EXPR)
    7999              :                          ? G_("ISO C++ forbids incrementing an enum")
    8000              :                          : G_("ISO C++ forbids decrementing an enum"));
    8001              :             else
    8002            0 :               return error_mark_node;
    8003              :           }
    8004              : 
    8005              :         /* Compute the increment.  */
    8006              : 
    8007      8396009 :         if (TYPE_PTR_P (argtype))
    8008              :           {
    8009      2662969 :             tree type = complete_type (TREE_TYPE (argtype));
    8010              : 
    8011      2662969 :             if (!COMPLETE_OR_VOID_TYPE_P (type))
    8012              :               {
    8013           10 :                 if (complain & tf_error)
    8014            9 :                   error_at (location, ((code == PREINCREMENT_EXPR
    8015            9 :                                         || code == POSTINCREMENT_EXPR))
    8016              :                             ? G_("cannot increment a pointer to incomplete "
    8017              :                                  "type %qT")
    8018              :                             : G_("cannot decrement a pointer to incomplete "
    8019              :                                  "type %qT"),
    8020            9 :                             TREE_TYPE (argtype));
    8021              :                 else
    8022            1 :                   return error_mark_node;
    8023              :               }
    8024      2662959 :             else if (!TYPE_PTROB_P (argtype))
    8025              :               {
    8026           69 :                 if (complain & tf_error)
    8027           63 :                   pedwarn (location, OPT_Wpointer_arith,
    8028           63 :                            (code == PREINCREMENT_EXPR
    8029           63 :                               || code == POSTINCREMENT_EXPR)
    8030              :                            ? G_("ISO C++ forbids incrementing a pointer "
    8031              :                                 "of type %qT")
    8032              :                            : G_("ISO C++ forbids decrementing a pointer "
    8033              :                                 "of type %qT"),
    8034              :                            argtype);
    8035              :                 else
    8036            6 :                   return error_mark_node;
    8037              :               }
    8038      2662890 :             else if (!verify_type_context (location, TCTX_POINTER_ARITH,
    8039      2662890 :                                            TREE_TYPE (argtype),
    8040              :                                            !(complain & tf_error)))
    8041            0 :               return error_mark_node;
    8042              : 
    8043      2662962 :             inc = cxx_sizeof_nowarn (TREE_TYPE (argtype));
    8044              :           }
    8045              :         else
    8046      5732897 :           inc = VECTOR_TYPE_P (argtype)
    8047      5733040 :             ? build_one_cst (argtype)
    8048              :             : integer_one_node;
    8049              : 
    8050      8396002 :         inc = cp_convert (argtype, inc, complain);
    8051              : 
    8052              :         /* If 'arg' is an Objective-C PROPERTY_REF expression, then we
    8053              :            need to ask Objective-C to build the increment or decrement
    8054              :            expression for it.  */
    8055      8396002 :         if (objc_is_property_ref (arg))
    8056            0 :           return objc_build_incr_expr_for_property_ref (input_location, code,
    8057            0 :                                                         arg, inc);
    8058              : 
    8059              :         /* Complain about anything else that is not a true lvalue.  */
    8060      8396002 :         if (!lvalue_or_else (arg, ((code == PREINCREMENT_EXPR
    8061      8396002 :                                     || code == POSTINCREMENT_EXPR)
    8062              :                                    ? lv_increment : lv_decrement),
    8063              :                              complain))
    8064           36 :           return error_mark_node;
    8065              : 
    8066              :         /* [depr.volatile.type] "Postfix ++ and -- expressions and
    8067              :            prefix ++ and -- expressions of volatile-qualified arithmetic
    8068              :            and pointer types are deprecated."  */
    8069      8395681 :         if ((TREE_THIS_VOLATILE (arg) || CP_TYPE_VOLATILE_P (TREE_TYPE (arg)))
    8070      8395966 :             && (complain & tf_warning))
    8071          398 :           warning_at (location, OPT_Wvolatile,
    8072              :                       "%qs expression of %<volatile%>-qualified type is "
    8073              :                       "deprecated",
    8074              :                       ((code == PREINCREMENT_EXPR
    8075              :                         || code == POSTINCREMENT_EXPR)
    8076              :                        ? "++" : "--"));
    8077              : 
    8078              :         /* Forbid using -- or ++ in C++17 on `bool'.  */
    8079      8395966 :         if (TREE_CODE (declared_type) == BOOLEAN_TYPE)
    8080              :           {
    8081           95 :             if (code == POSTDECREMENT_EXPR || code == PREDECREMENT_EXPR)
    8082              :               {
    8083           33 :                 if (complain & tf_error)
    8084           33 :                   error_at (location,
    8085              :                             "use of an operand of type %qT in %<operator--%> "
    8086              :                             "is forbidden", boolean_type_node);
    8087           33 :                 return error_mark_node;
    8088              :               }
    8089              :             else
    8090              :               {
    8091           62 :                 if (cxx_dialect >= cxx17)
    8092              :                   {
    8093           33 :                     if (complain & tf_error)
    8094           32 :                       error_at (location,
    8095              :                                 "use of an operand of type %qT in "
    8096              :                                 "%<operator++%> is forbidden in C++17",
    8097              :                                 boolean_type_node);
    8098           33 :                     return error_mark_node;
    8099              :                   }
    8100              :                 /* Otherwise, [depr.incr.bool] says this is deprecated.  */
    8101           29 :                 else if (complain & tf_warning)
    8102           25 :                   warning_at (location, OPT_Wdeprecated,
    8103              :                               "use of an operand of type %qT "
    8104              :                               "in %<operator++%> is deprecated",
    8105              :                               boolean_type_node);
    8106              :               }
    8107           29 :             val = boolean_increment (code, arg);
    8108              :           }
    8109      8395871 :         else if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
    8110              :           /* An rvalue has no cv-qualifiers.  */
    8111      1335448 :           val = build2 (code, cv_unqualified (TREE_TYPE (arg)), arg, inc);
    8112              :         else
    8113      7060423 :           val = build2 (code, TREE_TYPE (arg), arg, inc);
    8114              : 
    8115      8395900 :         TREE_SIDE_EFFECTS (val) = 1;
    8116      8395900 :         goto return_build_unary_op;
    8117              :       }
    8118              : 
    8119       553481 :     case ADDR_EXPR:
    8120              :       /* Note that this operation never does default_conversion
    8121              :          regardless of NOCONVERT.  */
    8122       553481 :       return cp_build_addr_expr (arg, complain);
    8123              : 
    8124              :     default:
    8125              :       break;
    8126              :     }
    8127              : 
    8128      3275080 :   if (!errstring)
    8129              :     {
    8130      3275000 :       if (argtype == 0)
    8131      3275000 :         argtype = TREE_TYPE (arg);
    8132      3275000 :       val = build1 (code, argtype, arg);
    8133     11670947 :     return_build_unary_op:
    8134     11670947 :       if (eptype)
    8135         6797 :         val = build1 (EXCESS_PRECISION_EXPR, eptype, val);
    8136     11670947 :       return val;
    8137              :     }
    8138              : 
    8139           95 :   if (complain & tf_error)
    8140           50 :     error_at (location, "%s", errstring);
    8141           95 :   return error_mark_node;
    8142              : }
    8143              : 
    8144              : /* Hook for the c-common bits that build a unary op.  */
    8145              : tree
    8146         4136 : build_unary_op (location_t /*location*/,
    8147              :                 enum tree_code code, tree xarg, bool noconvert)
    8148              : {
    8149         4136 :   return cp_build_unary_op (code, xarg, noconvert, tf_warning_or_error);
    8150              : }
    8151              : 
    8152              : /* Adjust LVALUE, an MODIFY_EXPR, PREINCREMENT_EXPR or PREDECREMENT_EXPR,
    8153              :    so that it is a valid lvalue even for GENERIC by replacing
    8154              :    (lhs = rhs) with ((lhs = rhs), lhs)
    8155              :    (--lhs) with ((--lhs), lhs)
    8156              :    (++lhs) with ((++lhs), lhs)
    8157              :    and if lhs has side-effects, calling cp_stabilize_reference on it, so
    8158              :    that it can be evaluated multiple times.  */
    8159              : 
    8160              : tree
    8161       396014 : genericize_compound_lvalue (tree lvalue)
    8162              : {
    8163       396014 :   if (TREE_SIDE_EFFECTS (TREE_OPERAND (lvalue, 0)))
    8164          196 :     lvalue = build2 (TREE_CODE (lvalue), TREE_TYPE (lvalue),
    8165          196 :                      cp_stabilize_reference (TREE_OPERAND (lvalue, 0)),
    8166          196 :                      TREE_OPERAND (lvalue, 1));
    8167       396014 :   return build2 (COMPOUND_EXPR, TREE_TYPE (TREE_OPERAND (lvalue, 0)),
    8168       396014 :                  lvalue, TREE_OPERAND (lvalue, 0));
    8169              : }
    8170              : 
    8171              : /* Apply unary lvalue-demanding operator CODE to the expression ARG
    8172              :    for certain kinds of expressions which are not really lvalues
    8173              :    but which we can accept as lvalues.
    8174              : 
    8175              :    If ARG is not a kind of expression we can handle, return
    8176              :    NULL_TREE.  */
    8177              : 
    8178              : tree
    8179    297583014 : unary_complex_lvalue (enum tree_code code, tree arg)
    8180              : {
    8181              :   /* Inside a template, making these kinds of adjustments is
    8182              :      pointless; we are only concerned with the type of the
    8183              :      expression.  */
    8184    297978798 :   if (processing_template_decl)
    8185              :     return NULL_TREE;
    8186              : 
    8187              :   /* Handle (a, b) used as an "lvalue".  */
    8188    210803370 :   if (TREE_CODE (arg) == COMPOUND_EXPR)
    8189              :     {
    8190       397146 :       tree real_result = cp_build_unary_op (code, TREE_OPERAND (arg, 1), false,
    8191              :                                             tf_warning_or_error);
    8192       397146 :       return build2 (COMPOUND_EXPR, TREE_TYPE (real_result),
    8193       794292 :                      TREE_OPERAND (arg, 0), real_result);
    8194              :     }
    8195              : 
    8196              :   /* Handle (a ? b : c) used as an "lvalue".  */
    8197    210406224 :   if (TREE_CODE (arg) == COND_EXPR
    8198    210329947 :       || TREE_CODE (arg) == MIN_EXPR || TREE_CODE (arg) == MAX_EXPR)
    8199        76277 :     return rationalize_conditional_expr (code, arg, tf_warning_or_error);
    8200              : 
    8201              :   /* Handle (a = b), (++a), and (--a) used as an "lvalue".  */
    8202    210329947 :   if (TREE_CODE (arg) == MODIFY_EXPR
    8203    209934286 :       || TREE_CODE (arg) == PREINCREMENT_EXPR
    8204    209934225 :       || TREE_CODE (arg) == PREDECREMENT_EXPR)
    8205       395784 :     return unary_complex_lvalue (code, genericize_compound_lvalue (arg));
    8206              : 
    8207    209934163 :   if (code != ADDR_EXPR)
    8208              :     return NULL_TREE;
    8209              : 
    8210              :   /* Handle (a = b) used as an "lvalue" for `&'.  */
    8211    206149746 :   if (TREE_CODE (arg) == MODIFY_EXPR
    8212    206149746 :       || TREE_CODE (arg) == INIT_EXPR)
    8213              :     {
    8214            0 :       tree real_result = cp_build_unary_op (code, TREE_OPERAND (arg, 0), false,
    8215              :                                             tf_warning_or_error);
    8216            0 :       arg = build2 (COMPOUND_EXPR, TREE_TYPE (real_result),
    8217              :                     arg, real_result);
    8218            0 :       suppress_warning (arg /* What warning? */);
    8219            0 :       return arg;
    8220              :     }
    8221              : 
    8222    318736254 :   if (FUNC_OR_METHOD_TYPE_P (TREE_TYPE (arg))
    8223    318735197 :       || TREE_CODE (arg) == OFFSET_REF)
    8224              :     return NULL_TREE;
    8225              : 
    8226              :   /* We permit compiler to make function calls returning
    8227              :      objects of aggregate type look like lvalues.  */
    8228    112585451 :   {
    8229    112585451 :     tree targ = arg;
    8230              : 
    8231    112585451 :     if (TREE_CODE (targ) == SAVE_EXPR)
    8232            0 :       targ = TREE_OPERAND (targ, 0);
    8233              : 
    8234    112585451 :     if (TREE_CODE (targ) == CALL_EXPR && MAYBE_CLASS_TYPE_P (TREE_TYPE (targ)))
    8235              :       {
    8236           26 :         if (TREE_CODE (arg) == SAVE_EXPR)
    8237              :           targ = arg;
    8238              :         else
    8239           26 :           targ = build_cplus_new (TREE_TYPE (arg), arg, tf_warning_or_error);
    8240           26 :         return build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg)), targ);
    8241              :       }
    8242              : 
    8243    112585425 :     if (TREE_CODE (arg) == SAVE_EXPR && INDIRECT_REF_P (targ))
    8244            0 :       return build3 (SAVE_EXPR, build_pointer_type (TREE_TYPE (arg)),
    8245            0 :                      TREE_OPERAND (targ, 0), current_function_decl, NULL);
    8246              :   }
    8247              : 
    8248              :   /* Don't let anything else be handled specially.  */
    8249              :   return NULL_TREE;
    8250              : }
    8251              : 
    8252              : /* Mark EXP saying that we need to be able to take the
    8253              :    address of it; it should not be allocated in a register.
    8254              :    Value is true if successful.  ARRAY_REF_P is true if this
    8255              :    is for ARRAY_REF construction - in that case we don't want
    8256              :    to look through VIEW_CONVERT_EXPR from VECTOR_TYPE to ARRAY_TYPE,
    8257              :    it is fine to use ARRAY_REFs for vector subscripts on vector
    8258              :    register variables.
    8259              : 
    8260              :    C++: we do not allow `current_class_ptr' to be addressable.  */
    8261              : 
    8262              : bool
    8263    348468619 : cxx_mark_addressable (tree exp, bool array_ref_p)
    8264              : {
    8265    348468619 :   tree x = exp;
    8266              : 
    8267    408386235 :   while (1)
    8268    408386235 :     switch (TREE_CODE (x))
    8269              :       {
    8270     29650267 :       case VIEW_CONVERT_EXPR:
    8271     29650267 :         if (array_ref_p
    8272       773820 :             && TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE
    8273     30230295 :             && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (x, 0))))
    8274              :           return true;
    8275     29647209 :         x = TREE_OPERAND (x, 0);
    8276     29647209 :         break;
    8277              : 
    8278     29919717 :       case COMPONENT_REF:
    8279     29919717 :         if (bitfield_p (x))
    8280            9 :           error ("attempt to take address of bit-field");
    8281              :         /* FALLTHRU */
    8282     30270407 :       case ADDR_EXPR:
    8283     30270407 :       case ARRAY_REF:
    8284     30270407 :       case REALPART_EXPR:
    8285     30270407 :       case IMAGPART_EXPR:
    8286     30270407 :         x = TREE_OPERAND (x, 0);
    8287     30270407 :         break;
    8288              : 
    8289      7682438 :       case PARM_DECL:
    8290      7682438 :         if (x == current_class_ptr)
    8291              :           {
    8292           18 :             error ("cannot take the address of %<this%>, which is an rvalue expression");
    8293           18 :             TREE_ADDRESSABLE (x) = 1; /* so compiler doesn't die later.  */
    8294           18 :             return true;
    8295              :           }
    8296              :         /* Fall through.  */
    8297              : 
    8298     70130970 :       case VAR_DECL:
    8299              :         /* Caller should not be trying to mark initialized
    8300              :            constant fields addressable.  */
    8301     70130970 :         gcc_assert (DECL_LANG_SPECIFIC (x) == 0
    8302              :                     || DECL_IN_AGGR_P (x) == 0
    8303              :                     || TREE_STATIC (x)
    8304              :                     || DECL_EXTERNAL (x));
    8305     70130970 :         if (VAR_P (x)
    8306     62448550 :             && DECL_ANON_UNION_VAR_P (x)
    8307     70131037 :             && !TREE_ADDRESSABLE (x))
    8308           35 :           cxx_mark_addressable (DECL_VALUE_EXPR (x));
    8309              :         /* Fall through.  */
    8310              : 
    8311     70263155 :       case RESULT_DECL:
    8312     70263246 :         if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)
    8313     70263237 :             && !DECL_ARTIFICIAL (x))
    8314              :           {
    8315           31 :             if (VAR_P (x) && DECL_HARD_REGISTER (x))
    8316              :               {
    8317           15 :                 error
    8318           15 :                   ("address of explicit register variable %qD requested", x);
    8319           15 :                 return false;
    8320              :               }
    8321           16 :             else if (extra_warnings)
    8322            3 :               warning
    8323            3 :                 (OPT_Wextra, "address requested for %qD, which is declared %<register%>", x);
    8324              :           }
    8325     70263140 :         TREE_ADDRESSABLE (x) = 1;
    8326     70263140 :         return true;
    8327              : 
    8328    168581510 :       case CONST_DECL:
    8329    168581510 :       case FUNCTION_DECL:
    8330    168581510 :         TREE_ADDRESSABLE (x) = 1;
    8331    168581510 :         return true;
    8332              : 
    8333        53470 :       case CONSTRUCTOR:
    8334        53470 :         TREE_ADDRESSABLE (x) = 1;
    8335        53470 :         return true;
    8336              : 
    8337     16462099 :       case TARGET_EXPR:
    8338     16462099 :         TREE_ADDRESSABLE (x) = 1;
    8339     16462099 :         cxx_mark_addressable (TARGET_EXPR_SLOT (x));
    8340     16462099 :         return true;
    8341              : 
    8342              :       default:
    8343              :         return true;
    8344              :     }
    8345              : }
    8346              : 
    8347              : /* Build and return a conditional expression IFEXP ? OP1 : OP2.  */
    8348              : 
    8349              : tree
    8350      9354201 : build_x_conditional_expr (location_t loc, tree ifexp, tree op1, tree op2,
    8351              :                           tsubst_flags_t complain)
    8352              : {
    8353      9354201 :   tree orig_ifexp = ifexp;
    8354      9354201 :   tree orig_op1 = op1;
    8355      9354201 :   tree orig_op2 = op2;
    8356      9354201 :   tree expr;
    8357              : 
    8358      9354201 :   if (processing_template_decl)
    8359              :     {
    8360              :       /* The standard says that the expression is type-dependent if
    8361              :          IFEXP is type-dependent, even though the eventual type of the
    8362              :          expression doesn't dependent on IFEXP.  */
    8363      3372477 :       if (type_dependent_expression_p (ifexp)
    8364              :           /* As a GNU extension, the middle operand may be omitted.  */
    8365      1846979 :           || (op1 && type_dependent_expression_p (op1))
    8366      4721496 :           || type_dependent_expression_p (op2))
    8367      2051649 :         return build_min_nt_loc (loc, COND_EXPR, ifexp, op1, op2);
    8368              :     }
    8369              : 
    8370      7302552 :   expr = build_conditional_expr (loc, ifexp, op1, op2, complain);
    8371      7302552 :   if (processing_template_decl && expr != error_mark_node)
    8372              :     {
    8373      1320822 :       tree min = build_min_non_dep (COND_EXPR, expr,
    8374              :                                     orig_ifexp, orig_op1, orig_op2);
    8375      1320822 :       expr = convert_from_reference (min);
    8376              :     }
    8377              :   return expr;
    8378              : }
    8379              : 
    8380              : /* Given a list of expressions, return a compound expression
    8381              :    that performs them all and returns the value of the last of them.  */
    8382              : 
    8383              : tree
    8384     31096962 : build_x_compound_expr_from_list (tree list, expr_list_kind exp,
    8385              :                                  tsubst_flags_t complain)
    8386              : {
    8387     31096962 :   tree expr = TREE_VALUE (list);
    8388              : 
    8389       464209 :   if (BRACE_ENCLOSED_INITIALIZER_P (expr)
    8390     31561159 :       && !CONSTRUCTOR_IS_DIRECT_INIT (expr))
    8391              :     {
    8392           14 :       if (complain & tf_error)
    8393           28 :         pedwarn (cp_expr_loc_or_input_loc (expr), 0,
    8394              :                  "list-initializer for non-class type must not "
    8395              :                  "be parenthesized");
    8396              :       else
    8397            0 :         return error_mark_node;
    8398              :     }
    8399              : 
    8400     31096962 :   if (TREE_CHAIN (list))
    8401              :     {
    8402           23 :       if (complain & tf_error)
    8403           14 :         switch (exp)
    8404              :           {
    8405           12 :           case ELK_INIT:
    8406           12 :             permerror (input_location, "expression list treated as compound "
    8407              :                                        "expression in initializer");
    8408           12 :             break;
    8409            1 :           case ELK_MEM_INIT:
    8410            1 :             permerror (input_location, "expression list treated as compound "
    8411              :                                        "expression in mem-initializer");
    8412            1 :             break;
    8413            1 :           case ELK_FUNC_CAST:
    8414            1 :             permerror (input_location, "expression list treated as compound "
    8415              :                                        "expression in functional cast");
    8416            1 :             break;
    8417            0 :           default:
    8418            0 :             gcc_unreachable ();
    8419              :           }
    8420              :       else
    8421            9 :         return error_mark_node;
    8422              : 
    8423           28 :       for (list = TREE_CHAIN (list); list; list = TREE_CHAIN (list))
    8424           28 :         expr = build_x_compound_expr (EXPR_LOCATION (TREE_VALUE (list)),
    8425           14 :                                       expr, TREE_VALUE (list), NULL_TREE,
    8426              :                                       complain);
    8427              :     }
    8428              : 
    8429              :   return expr;
    8430              : }
    8431              : 
    8432              : /* Like build_x_compound_expr_from_list, but using a VEC.  */
    8433              : 
    8434              : tree
    8435       391835 : build_x_compound_expr_from_vec (vec<tree, va_gc> *vec, const char *msg,
    8436              :                                 tsubst_flags_t complain)
    8437              : {
    8438       391835 :   if (vec_safe_is_empty (vec))
    8439              :     return NULL_TREE;
    8440       391835 :   else if (vec->length () == 1)
    8441       391771 :     return (*vec)[0];
    8442              :   else
    8443              :     {
    8444           64 :       tree expr;
    8445           64 :       unsigned int ix;
    8446           64 :       tree t;
    8447              : 
    8448           64 :       if (msg != NULL)
    8449              :         {
    8450            4 :           if (complain & tf_error)
    8451            0 :             permerror (input_location,
    8452              :                        "%s expression list treated as compound expression",
    8453              :                        msg);
    8454              :           else
    8455            4 :             return error_mark_node;
    8456              :         }
    8457              : 
    8458           60 :       expr = (*vec)[0];
    8459          134 :       for (ix = 1; vec->iterate (ix, &t); ++ix)
    8460           74 :         expr = build_x_compound_expr (EXPR_LOCATION (t), expr,
    8461              :                                       t, NULL_TREE, complain);
    8462              : 
    8463              :       return expr;
    8464              :     }
    8465              : }
    8466              : 
    8467              : /* Handle overloading of the ',' operator when needed.  */
    8468              : 
    8469              : tree
    8470      3070041 : build_x_compound_expr (location_t loc, tree op1, tree op2,
    8471              :                        tree lookups, tsubst_flags_t complain)
    8472              : {
    8473      3070041 :   tree result;
    8474      3070041 :   tree orig_op1 = op1;
    8475      3070041 :   tree orig_op2 = op2;
    8476      3070041 :   tree overload = NULL_TREE;
    8477              : 
    8478      3070041 :   if (processing_template_decl)
    8479              :     {
    8480      2828441 :       if (type_dependent_expression_p (op1)
    8481      2828441 :           || type_dependent_expression_p (op2))
    8482              :         {
    8483      2565105 :           result = build_min_nt_loc (loc, COMPOUND_EXPR, op1, op2);
    8484      2565105 :           TREE_TYPE (result)
    8485      2565105 :             = build_dependent_operator_type (lookups, COMPOUND_EXPR, false);
    8486      2565105 :           return result;
    8487              :         }
    8488              :     }
    8489              : 
    8490       504936 :   result = build_new_op (loc, COMPOUND_EXPR, LOOKUP_NORMAL, op1, op2,
    8491              :                          NULL_TREE, lookups, &overload, complain);
    8492       504936 :   if (!result)
    8493       496681 :     result = cp_build_compound_expr (op1, op2, complain);
    8494              : 
    8495       504936 :   if (processing_template_decl && result != error_mark_node)
    8496              :     {
    8497       261515 :       if (overload != NULL_TREE)
    8498           52 :         return (build_min_non_dep_op_overload
    8499           52 :                 (COMPOUND_EXPR, result, overload, orig_op1, orig_op2));
    8500              : 
    8501       261463 :       return build_min_non_dep (COMPOUND_EXPR, result, orig_op1, orig_op2);
    8502              :     }
    8503              : 
    8504              :   return result;
    8505              : }
    8506              : 
    8507              : /* Like cp_build_compound_expr, but for the c-common bits.  */
    8508              : 
    8509              : tree
    8510        16597 : build_compound_expr (location_t /*loc*/, tree lhs, tree rhs)
    8511              : {
    8512        16597 :   return cp_build_compound_expr (lhs, rhs, tf_warning_or_error);
    8513              : }
    8514              : 
    8515              : /* Build a compound expression.  */
    8516              : 
    8517              : tree
    8518       647524 : cp_build_compound_expr (tree lhs, tree rhs, tsubst_flags_t complain)
    8519              : {
    8520       647524 :   lhs = convert_to_void (lhs, ICV_LEFT_OF_COMMA, complain);
    8521              : 
    8522       647524 :   if (lhs == error_mark_node || rhs == error_mark_node)
    8523              :     return error_mark_node;
    8524              : 
    8525       647521 :   if (TREE_CODE (lhs) == EXCESS_PRECISION_EXPR)
    8526            0 :     lhs = TREE_OPERAND (lhs, 0);
    8527       647521 :   tree eptype = NULL_TREE;
    8528       647521 :   if (TREE_CODE (rhs) == EXCESS_PRECISION_EXPR)
    8529              :     {
    8530            3 :       eptype = TREE_TYPE (rhs);
    8531            3 :       rhs = TREE_OPERAND (rhs, 0);
    8532              :     }
    8533              : 
    8534       647521 :   if (TREE_CODE (rhs) == TARGET_EXPR)
    8535              :     {
    8536              :       /* If the rhs is a TARGET_EXPR, then build the compound
    8537              :          expression inside the target_expr's initializer. This
    8538              :          helps the compiler to eliminate unnecessary temporaries.  */
    8539        30517 :       tree init = TARGET_EXPR_INITIAL (rhs);
    8540              : 
    8541        30517 :       init = build2 (COMPOUND_EXPR, TREE_TYPE (init), lhs, init);
    8542        30517 :       TARGET_EXPR_INITIAL (rhs) = init;
    8543              : 
    8544        30517 :       if (eptype)
    8545            0 :         rhs = build1 (EXCESS_PRECISION_EXPR, eptype, rhs);
    8546        30517 :       return rhs;
    8547              :     }
    8548              : 
    8549       617004 :   rhs = resolve_nondeduced_context (rhs, complain);
    8550              : 
    8551       617004 :   if (type_unknown_p (rhs))
    8552              :     {
    8553           33 :       if (complain & tf_error)
    8554           51 :         error_at (cp_expr_loc_or_input_loc (rhs),
    8555              :                   "no context to resolve type of %qE", rhs);
    8556           33 :       return error_mark_node;
    8557              :     }
    8558              : 
    8559       616971 :   tree ret = build2 (COMPOUND_EXPR, TREE_TYPE (rhs), lhs, rhs);
    8560       616971 :   if (eptype)
    8561            3 :     ret = build1 (EXCESS_PRECISION_EXPR, eptype, ret);
    8562              :   return ret;
    8563              : }
    8564              : 
    8565              : /* Issue a diagnostic message if casting from SRC_TYPE to DEST_TYPE
    8566              :    casts away constness.  CAST gives the type of cast.  Returns true
    8567              :    if the cast is ill-formed, false if it is well-formed.
    8568              : 
    8569              :    ??? This function warns for casting away any qualifier not just
    8570              :    const.  We would like to specify exactly what qualifiers are casted
    8571              :    away.
    8572              : */
    8573              : 
    8574              : static bool
    8575       786810 : check_for_casting_away_constness (location_t loc, tree src_type,
    8576              :                                   tree dest_type, enum tree_code cast,
    8577              :                                   tsubst_flags_t complain)
    8578              : {
    8579              :   /* C-style casts are allowed to cast away constness.  With
    8580              :      WARN_CAST_QUAL, we still want to issue a warning.  */
    8581       786810 :   if (cast == CAST_EXPR && !warn_cast_qual)
    8582              :     return false;
    8583              : 
    8584       627422 :   if (!casts_away_constness (src_type, dest_type, complain))
    8585              :     return false;
    8586              : 
    8587          400 :   switch (cast)
    8588              :     {
    8589          343 :     case CAST_EXPR:
    8590          343 :       if (complain & tf_warning)
    8591          343 :         warning_at (loc, OPT_Wcast_qual,
    8592              :                     "cast from type %qT to type %qT casts away qualifiers",
    8593              :                     src_type, dest_type);
    8594              :       return false;
    8595              : 
    8596           36 :     case STATIC_CAST_EXPR:
    8597           36 :       if (complain & tf_error)
    8598           24 :         error_at (loc, "%<static_cast%> from type %qT to type %qT casts "
    8599              :                   "away qualifiers",
    8600              :                   src_type, dest_type);
    8601              :       return true;
    8602              : 
    8603           21 :     case REINTERPRET_CAST_EXPR:
    8604           21 :       if (complain & tf_error)
    8605           15 :         error_at (loc, "%<reinterpret_cast%> from type %qT to type %qT "
    8606              :                   "casts away qualifiers",
    8607              :                   src_type, dest_type);
    8608              :       return true;
    8609              : 
    8610            0 :     default:
    8611            0 :       gcc_unreachable();
    8612              :     }
    8613              : }
    8614              : 
    8615              : /* Warns if the cast from expression EXPR to type TYPE is useless.  */
    8616              : void
    8617     49588171 : maybe_warn_about_useless_cast (location_t loc, tree type, tree expr,
    8618              :                                tsubst_flags_t complain)
    8619              : {
    8620     49588171 :   if (warn_useless_cast
    8621          152 :       && complain & tf_warning)
    8622              :     {
    8623          152 :       if (TYPE_REF_P (type)
    8624          152 :           ? ((TYPE_REF_IS_RVALUE (type)
    8625           86 :               ? xvalue_p (expr) : lvalue_p (expr))
    8626          172 :              && same_type_p (TREE_TYPE (expr), TREE_TYPE (type)))
    8627              :           /* Don't warn when converting a class object to a non-reference type,
    8628              :              because that's a common way to create a temporary.  */
    8629           66 :           : (!glvalue_p (expr) && same_type_p (TREE_TYPE (expr), type)))
    8630           96 :         warning_at (loc, OPT_Wuseless_cast,
    8631              :                     "useless cast to type %q#T", type);
    8632              :     }
    8633     49588171 : }
    8634              : 
    8635              : /* Warns if the cast ignores cv-qualifiers on TYPE.  */
    8636              : static void
    8637     49581973 : maybe_warn_about_cast_ignoring_quals (location_t loc, tree type,
    8638              :                                       tsubst_flags_t complain)
    8639              : {
    8640     49581973 :   if (warn_ignored_qualifiers
    8641       274138 :       && complain & tf_warning
    8642       273650 :       && !CLASS_TYPE_P (type)
    8643     49850293 :       && (cp_type_quals (type) & (TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE)))
    8644           36 :     warning_at (loc, OPT_Wignored_qualifiers,
    8645              :                 "type qualifiers ignored on cast result type");
    8646     49581973 : }
    8647              : 
    8648              : /* Convert EXPR (an expression with pointer-to-member type) to TYPE
    8649              :    (another pointer-to-member type in the same hierarchy) and return
    8650              :    the converted expression.  If ALLOW_INVERSE_P is permitted, a
    8651              :    pointer-to-derived may be converted to pointer-to-base; otherwise,
    8652              :    only the other direction is permitted.  If C_CAST_P is true, this
    8653              :    conversion is taking place as part of a C-style cast.  */
    8654              : 
    8655              : tree
    8656        28122 : convert_ptrmem (tree type, tree expr, bool allow_inverse_p,
    8657              :                 bool c_cast_p, tsubst_flags_t complain)
    8658              : {
    8659        28122 :   if (same_type_p (type, TREE_TYPE (expr)))
    8660              :     return expr;
    8661              : 
    8662        28122 :   if (TYPE_PTRDATAMEM_P (type))
    8663              :     {
    8664          382 :       tree obase = TYPE_PTRMEM_CLASS_TYPE (TREE_TYPE (expr));
    8665          382 :       tree nbase = TYPE_PTRMEM_CLASS_TYPE (type);
    8666          382 :       tree delta = (get_delta_difference
    8667          382 :                     (obase, nbase,
    8668              :                      allow_inverse_p, c_cast_p, complain));
    8669              : 
    8670          382 :       if (delta == error_mark_node)
    8671              :         return error_mark_node;
    8672              : 
    8673          376 :       if (!same_type_p (obase, nbase))
    8674              :         {
    8675          293 :           if (TREE_CODE (expr) == PTRMEM_CST)
    8676          157 :             expr = cplus_expand_constant (expr);
    8677              : 
    8678          293 :           tree cond = cp_build_binary_op (input_location, EQ_EXPR, expr,
    8679          293 :                                           build_int_cst (TREE_TYPE (expr), -1),
    8680              :                                           complain);
    8681          293 :           tree op1 = build_nop (ptrdiff_type_node, expr);
    8682          293 :           tree op2 = cp_build_binary_op (input_location, PLUS_EXPR, op1, delta,
    8683              :                                          complain);
    8684              : 
    8685          293 :           expr = fold_build3_loc (input_location,
    8686              :                                   COND_EXPR, ptrdiff_type_node, cond, op1, op2);
    8687              :         }
    8688              : 
    8689          376 :       return build_nop (type, expr);
    8690              :     }
    8691              :   else
    8692        27740 :     return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr,
    8693        27740 :                              allow_inverse_p, c_cast_p, complain);
    8694              : }
    8695              : 
    8696              : /* Perform a static_cast from EXPR to TYPE.  When C_CAST_P is true,
    8697              :    this static_cast is being attempted as one of the possible casts
    8698              :    allowed by a C-style cast.  (In that case, accessibility of base
    8699              :    classes is not considered, and it is OK to cast away
    8700              :    constness.)  Return the result of the cast.  *VALID_P is set to
    8701              :    indicate whether or not the cast was valid.  */
    8702              : 
    8703              : static tree
    8704     49101040 : build_static_cast_1 (location_t loc, tree type, tree expr, bool c_cast_p,
    8705              :                      bool *valid_p, tsubst_flags_t complain)
    8706              : {
    8707     49101040 :   tree intype;
    8708     49101040 :   tree result;
    8709     49101040 :   cp_lvalue_kind clk;
    8710              : 
    8711              :   /* Assume the cast is valid.  */
    8712     49101040 :   *valid_p = true;
    8713              : 
    8714     49101040 :   intype = unlowered_expr_type (expr);
    8715              : 
    8716              :   /* Save casted types in the function's used types hash table.  */
    8717     49101040 :   used_types_insert (type);
    8718              : 
    8719              :   /* A prvalue of non-class type is cv-unqualified.  */
    8720     49101040 :   if (!CLASS_TYPE_P (type))
    8721     46094756 :     type = cv_unqualified (type);
    8722              : 
    8723              :   /* [expr.static.cast]
    8724              : 
    8725              :      An lvalue of type "cv1 B", where B is a class type, can be cast
    8726              :      to type "reference to cv2 D", where D is a class derived (clause
    8727              :      _class.derived_) from B, if a valid standard conversion from
    8728              :      "pointer to D" to "pointer to B" exists (_conv.ptr_), cv2 is the
    8729              :      same cv-qualification as, or greater cv-qualification than, cv1,
    8730              :      and B is not a virtual base class of D.  */
    8731              :   /* We check this case before checking the validity of "TYPE t =
    8732              :      EXPR;" below because for this case:
    8733              : 
    8734              :        struct B {};
    8735              :        struct D : public B { D(const B&); };
    8736              :        extern B& b;
    8737              :        void f() { static_cast<const D&>(b); }
    8738              : 
    8739              :      we want to avoid constructing a new D.  The standard is not
    8740              :      completely clear about this issue, but our interpretation is
    8741              :      consistent with other compilers.  */
    8742     49101040 :   if (TYPE_REF_P (type)
    8743      5426096 :       && CLASS_TYPE_P (TREE_TYPE (type))
    8744      3569196 :       && CLASS_TYPE_P (intype)
    8745      3569179 :       && (TYPE_REF_IS_RVALUE (type) || lvalue_p (expr))
    8746      3556863 :       && DERIVED_FROM_P (intype, TREE_TYPE (type))
    8747      3535571 :       && can_convert (build_pointer_type (TYPE_MAIN_VARIANT (intype)),
    8748      3535571 :                       build_pointer_type (TYPE_MAIN_VARIANT
    8749              :                                           (TREE_TYPE (type))),
    8750              :                       complain)
    8751     52636611 :       && (c_cast_p
    8752      3535547 :           || at_least_as_qualified_p (TREE_TYPE (type), intype)))
    8753              :     {
    8754      3535571 :       tree base;
    8755              : 
    8756      3535571 :       if (processing_template_decl)
    8757              :         return expr;
    8758              : 
    8759              :       /* There is a standard conversion from "D*" to "B*" even if "B"
    8760              :          is ambiguous or inaccessible.  If this is really a
    8761              :          static_cast, then we check both for inaccessibility and
    8762              :          ambiguity.  However, if this is a static_cast being performed
    8763              :          because the user wrote a C-style cast, then accessibility is
    8764              :          not considered.  */
    8765      6622814 :       base = lookup_base (TREE_TYPE (type), intype,
    8766              :                           c_cast_p ? ba_unique : ba_check,
    8767              :                           NULL, complain);
    8768      3311419 :       expr = cp_build_addr_expr (expr, complain);
    8769              : 
    8770      3311419 :       if (sanitize_flags_p (SANITIZE_VPTR))
    8771              :         {
    8772          485 :           tree ubsan_check
    8773          485 :             = cp_ubsan_maybe_instrument_downcast (loc, type,
    8774              :                                                   intype, expr);
    8775          485 :           if (ubsan_check)
    8776      3311419 :             expr = ubsan_check;
    8777              :         }
    8778              : 
    8779              :       /* Convert from "B*" to "D*".  This function will check that "B"
    8780              :          is not a virtual base of "D".  Even if we don't have a guarantee
    8781              :          that expr is NULL, if the static_cast is to a reference type,
    8782              :          it is UB if it would be NULL, so omit the non-NULL check.  */
    8783      3311419 :       expr = build_base_path (MINUS_EXPR, expr, base,
    8784              :                               /*nonnull=*/flag_delete_null_pointer_checks,
    8785              :                               complain);
    8786              : 
    8787              :       /* Convert the pointer to a reference -- but then remember that
    8788              :          there are no expressions with reference type in C++.
    8789              : 
    8790              :          We call rvalue so that there's an actual tree code
    8791              :          (NON_LVALUE_EXPR) for the static_cast; otherwise, if the operand
    8792              :          is a variable with the same type, the conversion would get folded
    8793              :          away, leaving just the variable and causing lvalue_kind to give
    8794              :          the wrong answer.  */
    8795      3311419 :       expr = cp_fold_convert (type, expr);
    8796              : 
    8797              :       /* When -fsanitize=null, make sure to diagnose reference binding to
    8798              :          NULL even when the reference is converted to pointer later on.  */
    8799      3311419 :       if (sanitize_flags_p (SANITIZE_NULL)
    8800          491 :           && TREE_CODE (expr) == COND_EXPR
    8801            6 :           && TREE_OPERAND (expr, 2)
    8802            6 :           && TREE_CODE (TREE_OPERAND (expr, 2)) == INTEGER_CST
    8803      3311425 :           && TREE_TYPE (TREE_OPERAND (expr, 2)) == type)
    8804            6 :         ubsan_maybe_instrument_reference (&TREE_OPERAND (expr, 2));
    8805              : 
    8806      3311419 :       return convert_from_reference (rvalue (expr));
    8807              :     }
    8808              : 
    8809              :   /* "A glvalue of type cv1 T1 can be cast to type rvalue reference to
    8810              :      cv2 T2 if cv2 T2 is reference-compatible with cv1 T1 (8.5.3)."  */
    8811     45565469 :   if (TYPE_REF_P (type)
    8812      1890525 :       && TYPE_REF_IS_RVALUE (type)
    8813       798909 :       && (clk = real_lvalue_p (expr))
    8814       787821 :       && reference_compatible_p (TREE_TYPE (type), intype)
    8815     46353287 :       && (c_cast_p || at_least_as_qualified_p (TREE_TYPE (type), intype)))
    8816              :     {
    8817       787818 :       if (processing_template_decl)
    8818              :         return expr;
    8819       787322 :       if (clk == clk_ordinary)
    8820              :         {
    8821              :           /* Handle the (non-bit-field) lvalue case here by casting to
    8822              :              lvalue reference and then changing it to an rvalue reference.
    8823              :              Casting an xvalue to rvalue reference will be handled by the
    8824              :              main code path.  */
    8825       787319 :           tree lref = cp_build_reference_type (TREE_TYPE (type), false);
    8826       787319 :           result = (perform_direct_initialization_if_possible
    8827       787319 :                     (lref, expr, c_cast_p, complain));
    8828       787319 :           result = build1 (NON_LVALUE_EXPR, type, result);
    8829       787319 :           return convert_from_reference (result);
    8830              :         }
    8831              :       else
    8832              :         /* For a bit-field or packed field, bind to a temporary.  */
    8833            3 :         expr = rvalue (expr);
    8834              :     }
    8835              : 
    8836              :   /* Resolve overloaded address here rather than once in
    8837              :      implicit_conversion and again in the inverse code below.  */
    8838     44777654 :   if (TYPE_PTRMEMFUNC_P (type) && type_unknown_p (expr))
    8839              :     {
    8840           21 :       expr = instantiate_type (type, expr, complain);
    8841           21 :       intype = TREE_TYPE (expr);
    8842              :     }
    8843              : 
    8844              :   /* [expr.static.cast]
    8845              : 
    8846              :      Any expression can be explicitly converted to type cv void.  */
    8847     44777654 :   if (VOID_TYPE_P (type))
    8848              :     {
    8849       548737 :       if (TREE_CODE (expr) == EXCESS_PRECISION_EXPR)
    8850            0 :         expr = TREE_OPERAND (expr, 0);
    8851       548737 :       return convert_to_void (expr, ICV_CAST, complain);
    8852              :     }
    8853              : 
    8854              :   /* [class.abstract]
    8855              :      An abstract class shall not be used ... as the type of an explicit
    8856              :      conversion.  */
    8857     44228917 :   if (abstract_virtuals_error (ACU_CAST, type, complain))
    8858            6 :     return error_mark_node;
    8859              : 
    8860              :   /* [expr.static.cast]
    8861              : 
    8862              :      An expression e can be explicitly converted to a type T using a
    8863              :      static_cast of the form static_cast<T>(e) if the declaration T
    8864              :      t(e);" is well-formed, for some invented temporary variable
    8865              :      t.  */
    8866     44228911 :   result = perform_direct_initialization_if_possible (type, expr,
    8867              :                                                       c_cast_p, complain);
    8868              :   /* P1975 allows static_cast<Aggr>(42), as well as static_cast<T[5]>(42),
    8869              :      which initialize the first element of the aggregate.  We need to handle
    8870              :      the array case specifically.  */
    8871     44228911 :   if (result == NULL_TREE
    8872      4561558 :       && cxx_dialect >= cxx20
    8873      3233692 :       && TREE_CODE (type) == ARRAY_TYPE)
    8874              :     {
    8875              :       /* Create { EXPR } and perform direct-initialization from it.  */
    8876           15 :       tree e = build_constructor_single (init_list_type_node, NULL_TREE, expr);
    8877           15 :       CONSTRUCTOR_IS_DIRECT_INIT (e) = true;
    8878           15 :       CONSTRUCTOR_IS_PAREN_INIT (e) = true;
    8879           15 :       result = perform_direct_initialization_if_possible (type, e, c_cast_p,
    8880              :                                                           complain);
    8881              :     }
    8882      4561558 :   if (result)
    8883              :     {
    8884     39667368 :       if (processing_template_decl)
    8885              :         return expr;
    8886              : 
    8887     38989968 :       result = convert_from_reference (result);
    8888              : 
    8889              :       /* [expr.static.cast]
    8890              : 
    8891              :          If T is a reference type, the result is an lvalue; otherwise,
    8892              :          the result is an rvalue.  */
    8893     38989968 :       if (!TYPE_REF_P (type))
    8894              :         {
    8895     37887355 :           result = rvalue (result);
    8896              : 
    8897     37887355 :           if (result == expr && SCALAR_TYPE_P (type))
    8898              :             /* Leave some record of the cast.  */
    8899      2312730 :             result = build_nop (type, expr);
    8900              :         }
    8901     38989968 :       return result;
    8902              :     }
    8903              : 
    8904              :   /* [expr.static.cast]
    8905              : 
    8906              :      The inverse of any standard conversion sequence (clause _conv_),
    8907              :      other than the lvalue-to-rvalue (_conv.lval_), array-to-pointer
    8908              :      (_conv.array_), function-to-pointer (_conv.func_), and boolean
    8909              :      (_conv.bool_) conversions, can be performed explicitly using
    8910              :      static_cast subject to the restriction that the explicit
    8911              :      conversion does not cast away constness (_expr.const.cast_), and
    8912              :      the following additional rules for specific cases:  */
    8913              :   /* For reference, the conversions not excluded are: integral
    8914              :      promotions, floating-point promotion, integral conversions,
    8915              :      floating-point conversions, floating-integral conversions,
    8916              :      pointer conversions, and pointer to member conversions.  */
    8917              :   /* DR 128
    8918              : 
    8919              :      A value of integral _or enumeration_ type can be explicitly
    8920              :      converted to an enumeration type.  */
    8921              :   /* The effect of all that is that any conversion between any two
    8922              :      types which are integral, floating, or enumeration types can be
    8923              :      performed.  */
    8924      4561543 :   if ((INTEGRAL_OR_ENUMERATION_TYPE_P (type)
    8925      2509365 :        || SCALAR_FLOAT_TYPE_P (type))
    8926      2138329 :       && (INTEGRAL_OR_ENUMERATION_TYPE_P (intype)
    8927       185540 :           || SCALAR_FLOAT_TYPE_P (intype)))
    8928              :     {
    8929      2038928 :       if (processing_template_decl)
    8930              :         return expr;
    8931      1949393 :       if (TREE_CODE (expr) == EXCESS_PRECISION_EXPR)
    8932            0 :         expr = TREE_OPERAND (expr, 0);
    8933              :       /* [expr.static.cast]: "If the value is not a bit-field, the result
    8934              :          refers to the object or the specified base class subobject thereof;
    8935              :          otherwise, the lvalue-to-rvalue conversion is applied to the
    8936              :          bit-field and the resulting prvalue is used as the operand of the
    8937              :          static_cast."  There are no prvalue bit-fields; the l-to-r conversion
    8938              :          will give us an object of the underlying type of the bit-field.  */
    8939      1949393 :       expr = decay_conversion (expr, complain);
    8940      1949393 :       return ocp_convert (type, expr, CONV_C_CAST, LOOKUP_NORMAL, complain);
    8941              :     }
    8942              : 
    8943       781352 :   if (TYPE_PTR_P (type) && TYPE_PTR_P (intype)
    8944       776879 :       && CLASS_TYPE_P (TREE_TYPE (type))
    8945       182710 :       && CLASS_TYPE_P (TREE_TYPE (intype))
    8946      2555420 :       && can_convert (build_pointer_type (TYPE_MAIN_VARIANT
    8947              :                                           (TREE_TYPE (intype))),
    8948        32805 :                       build_pointer_type (TYPE_MAIN_VARIANT
    8949              :                                           (TREE_TYPE (type))),
    8950              :                       complain))
    8951              :     {
    8952        32466 :       tree base;
    8953              : 
    8954        32466 :       if (processing_template_decl)
    8955              :         return expr;
    8956              : 
    8957        32448 :       if (!c_cast_p
    8958        32448 :           && check_for_casting_away_constness (loc, intype, type,
    8959              :                                                STATIC_CAST_EXPR,
    8960              :                                                complain))
    8961            6 :         return error_mark_node;
    8962        64345 :       base = lookup_base (TREE_TYPE (type), TREE_TYPE (intype),
    8963              :                           c_cast_p ? ba_unique : ba_check,
    8964              :                           NULL, complain);
    8965        32442 :       expr = build_base_path (MINUS_EXPR, expr, base, /*nonnull=*/false,
    8966              :                               complain);
    8967              : 
    8968        32442 :       if (sanitize_flags_p (SANITIZE_VPTR))
    8969              :         {
    8970           43 :           tree ubsan_check
    8971           43 :             = cp_ubsan_maybe_instrument_downcast (loc, type,
    8972              :                                                   intype, expr);
    8973           43 :           if (ubsan_check)
    8974        32442 :             expr = ubsan_check;
    8975              :         }
    8976              : 
    8977        32442 :       return cp_fold_convert (type, expr);
    8978              :     }
    8979              : 
    8980           89 :   if ((TYPE_PTRDATAMEM_P (type) && TYPE_PTRDATAMEM_P (intype))
    8981      2490149 :       || (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype)))
    8982              :     {
    8983          232 :       tree c1;
    8984          232 :       tree c2;
    8985          232 :       tree t1;
    8986          232 :       tree t2;
    8987              : 
    8988          232 :       c1 = TYPE_PTRMEM_CLASS_TYPE (intype);
    8989          232 :       c2 = TYPE_PTRMEM_CLASS_TYPE (type);
    8990              : 
    8991          232 :       if (TYPE_PTRDATAMEM_P (type))
    8992              :         {
    8993           89 :           t1 = (build_ptrmem_type
    8994           89 :                 (c1,
    8995           89 :                  TYPE_MAIN_VARIANT (TYPE_PTRMEM_POINTED_TO_TYPE (intype))));
    8996           89 :           t2 = (build_ptrmem_type
    8997           89 :                 (c2,
    8998           89 :                  TYPE_MAIN_VARIANT (TYPE_PTRMEM_POINTED_TO_TYPE (type))));
    8999              :         }
    9000              :       else
    9001              :         {
    9002              :           t1 = intype;
    9003              :           t2 = type;
    9004              :         }
    9005          232 :       if (can_convert (t1, t2, complain) || can_convert (t2, t1, complain))
    9006              :         {
    9007          154 :           if (!c_cast_p
    9008          154 :               && check_for_casting_away_constness (loc, intype, type,
    9009              :                                                    STATIC_CAST_EXPR,
    9010              :                                                    complain))
    9011            9 :             return error_mark_node;
    9012          145 :           if (processing_template_decl)
    9013              :             return expr;
    9014          145 :           return convert_ptrmem (type, expr, /*allow_inverse_p=*/1,
    9015          145 :                                  c_cast_p, complain);
    9016              :         }
    9017              :     }
    9018              : 
    9019              :   /* [expr.static.cast]
    9020              : 
    9021              :      An rvalue of type "pointer to cv void" can be explicitly
    9022              :      converted to a pointer to object type.  A value of type pointer
    9023              :      to object converted to "pointer to cv void" and back to the
    9024              :      original pointer type will have its original value.  */
    9025      2489995 :   if (TYPE_PTR_P (intype)
    9026       841645 :       && VOID_TYPE_P (TREE_TYPE (intype))
    9027      3198228 :       && TYPE_PTROB_P (type))
    9028              :     {
    9029       675987 :       if (!c_cast_p
    9030       675987 :           && check_for_casting_away_constness (loc, intype, type,
    9031              :                                                STATIC_CAST_EXPR,
    9032              :                                                complain))
    9033           21 :         return error_mark_node;
    9034       675966 :       if (processing_template_decl)
    9035              :         return expr;
    9036       592839 :       return build_nop (type, expr);
    9037              :     }
    9038              : 
    9039      1814008 :   *valid_p = false;
    9040      1814008 :   return error_mark_node;
    9041              : }
    9042              : 
    9043              : /* Return an expression representing static_cast<TYPE>(EXPR).  */
    9044              : 
    9045              : tree
    9046     16656968 : build_static_cast (location_t loc, tree type, tree oexpr,
    9047              :                    tsubst_flags_t complain)
    9048              : {
    9049     16656968 :   tree expr = oexpr;
    9050     16656968 :   tree result;
    9051     16656968 :   bool valid_p;
    9052              : 
    9053     16656968 :   if (type == error_mark_node || expr == error_mark_node)
    9054              :     return error_mark_node;
    9055              : 
    9056     16656833 :   bool dependent = (dependent_type_p (type)
    9057     16656833 :                     || type_dependent_expression_p (expr));
    9058     11584878 :   if (dependent)
    9059              :     {
    9060      6146720 :     tmpl:
    9061      6146720 :       expr = build_min (STATIC_CAST_EXPR, type, oexpr);
    9062              :       /* We don't know if it will or will not have side effects.  */
    9063      6146720 :       TREE_SIDE_EFFECTS (expr) = 1;
    9064      6146720 :       result = convert_from_reference (expr);
    9065      6146720 :       protected_set_expr_location (result, loc);
    9066      6146720 :       return result;
    9067              :     }
    9068              : 
    9069              :   /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
    9070              :      Strip such NOP_EXPRs if VALUE is being used in non-lvalue context.  */
    9071     11584878 :   if (!TYPE_REF_P (type)
    9072      6159876 :       && TREE_CODE (expr) == NOP_EXPR
    9073     11692334 :       && TREE_TYPE (expr) == TREE_TYPE (TREE_OPERAND (expr, 0)))
    9074           67 :     expr = TREE_OPERAND (expr, 0);
    9075              : 
    9076     11584878 :   result = build_static_cast_1 (loc, type, expr, /*c_cast_p=*/false,
    9077              :                                 &valid_p, complain);
    9078     11584878 :   if (valid_p)
    9079              :     {
    9080     11584683 :       if (result != error_mark_node)
    9081              :         {
    9082     11584578 :           maybe_warn_about_useless_cast (loc, type, expr, complain);
    9083     11584578 :           maybe_warn_about_cast_ignoring_quals (loc, type, complain);
    9084              :         }
    9085     11584683 :       if (processing_template_decl)
    9086      1074765 :         goto tmpl;
    9087     10509918 :       protected_set_expr_location (result, loc);
    9088     10509918 :       return result;
    9089              :     }
    9090              : 
    9091          195 :   if (complain & tf_error)
    9092              :     {
    9093          162 :       auto_diagnostic_group d;
    9094          162 :       error_at (loc, "invalid %<static_cast%> from type %qT to type %qT",
    9095          162 :                 TREE_TYPE (expr), type);
    9096          162 :       if ((TYPE_PTR_P (type) || TYPE_REF_P (type))
    9097          120 :           && CLASS_TYPE_P (TREE_TYPE (type))
    9098          191 :             && !COMPLETE_TYPE_P (TREE_TYPE (type)))
    9099           17 :         inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (TREE_TYPE (type))),
    9100           17 :                 "class type %qT is incomplete", TREE_TYPE (type));
    9101          162 :       tree expr_type = TREE_TYPE (expr);
    9102          162 :       if (TYPE_PTR_P (expr_type))
    9103           35 :         expr_type = TREE_TYPE (expr_type);
    9104          162 :       if (CLASS_TYPE_P (expr_type) && !COMPLETE_TYPE_P (expr_type))
    9105           12 :         inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (expr_type)),
    9106              :                 "class type %qT is incomplete", expr_type);
    9107          162 :     }
    9108          195 :   return error_mark_node;
    9109              : }
    9110              : 
    9111              : /* EXPR is an expression with member function or pointer-to-member
    9112              :    function type.  TYPE is a pointer type.  Converting EXPR to TYPE is
    9113              :    not permitted by ISO C++, but we accept it in some modes.  If we
    9114              :    are not in one of those modes, issue a diagnostic.  Return the
    9115              :    converted expression.  */
    9116              : 
    9117              : tree
    9118          165 : convert_member_func_to_ptr (tree type, tree expr, tsubst_flags_t complain)
    9119              : {
    9120          165 :   tree intype;
    9121          165 :   tree decl;
    9122              : 
    9123          165 :   intype = TREE_TYPE (expr);
    9124          165 :   gcc_assert (TYPE_PTRMEMFUNC_P (intype)
    9125              :               || TREE_CODE (intype) == METHOD_TYPE);
    9126              : 
    9127          165 :   if (!(complain & tf_warning_or_error))
    9128            0 :     return error_mark_node;
    9129              : 
    9130          165 :   location_t loc = cp_expr_loc_or_input_loc (expr);
    9131              : 
    9132          165 :   if (pedantic || warn_pmf2ptr)
    9133          207 :     pedwarn (loc, pedantic ? OPT_Wpedantic : OPT_Wpmf_conversions,
    9134              :              "converting from %qH to %qI", intype, type);
    9135              : 
    9136          165 :   STRIP_ANY_LOCATION_WRAPPER (expr);
    9137              : 
    9138          165 :   if (TREE_CODE (intype) == METHOD_TYPE)
    9139           72 :     expr = build_addr_func (expr, complain);
    9140           93 :   else if (TREE_CODE (expr) == PTRMEM_CST)
    9141           75 :     expr = build_address (PTRMEM_CST_MEMBER (expr));
    9142              :   else
    9143              :     {
    9144           18 :       decl = maybe_dummy_object (TYPE_PTRMEM_CLASS_TYPE (intype), 0);
    9145           18 :       decl = build_address (decl);
    9146           18 :       expr = get_member_function_from_ptrfunc (&decl, expr, complain);
    9147              :     }
    9148              : 
    9149          165 :   if (expr == error_mark_node)
    9150              :     return error_mark_node;
    9151              : 
    9152          165 :   expr = build_nop (type, expr);
    9153          165 :   SET_EXPR_LOCATION (expr, loc);
    9154          165 :   return expr;
    9155              : }
    9156              : 
    9157              : /* Build a NOP_EXPR to TYPE, but mark it as a reinterpret_cast so that
    9158              :    constexpr evaluation knows to reject it.  */
    9159              : 
    9160              : static tree
    9161       112249 : build_nop_reinterpret (tree type, tree expr)
    9162              : {
    9163       112249 :   tree ret = build_nop (type, expr);
    9164       112249 :   if (ret != expr)
    9165       112249 :     REINTERPRET_CAST_P (ret) = true;
    9166       112249 :   return ret;
    9167              : }
    9168              : 
    9169              : /* Return a representation for a reinterpret_cast from EXPR to TYPE.
    9170              :    If C_CAST_P is true, this reinterpret cast is being done as part of
    9171              :    a C-style cast.  If VALID_P is non-NULL, *VALID_P is set to
    9172              :    indicate whether or not reinterpret_cast was valid.  */
    9173              : 
    9174              : static tree
    9175      1962427 : build_reinterpret_cast_1 (location_t loc, tree type, tree expr,
    9176              :                           bool c_cast_p, bool *valid_p,
    9177              :                           tsubst_flags_t complain)
    9178              : {
    9179      1962427 :   tree intype;
    9180              : 
    9181              :   /* Assume the cast is invalid.  */
    9182      1962427 :   if (valid_p)
    9183      1813869 :     *valid_p = true;
    9184              : 
    9185      1962427 :   if (type == error_mark_node || error_operand_p (expr))
    9186              :     return error_mark_node;
    9187              : 
    9188      1962427 :   intype = TREE_TYPE (expr);
    9189              : 
    9190              :   /* Save casted types in the function's used types hash table.  */
    9191      1962427 :   used_types_insert (type);
    9192              : 
    9193              :   /* A prvalue of non-class type is cv-unqualified.  */
    9194      1962427 :   if (!CLASS_TYPE_P (type))
    9195      1962418 :     type = cv_unqualified (type);
    9196              : 
    9197              :   /* [expr.reinterpret.cast]
    9198              :      A glvalue of type T1, designating an object x, can be cast to the type
    9199              :      "reference to T2" if an expression of type "pointer to T1" can be
    9200              :      explicitly converted to the type "pointer to T2" using a reinterpret_cast.
    9201              :      The result is that of *reinterpret_cast<T2 *>(p) where p is a pointer to x
    9202              :      of type "pointer to T1". No temporary is created, no copy is made, and no
    9203              :      constructors (11.4.4) or conversion functions (11.4.7) are called.  */
    9204      1962427 :   if (TYPE_REF_P (type))
    9205              :     {
    9206         9547 :       if (!glvalue_p (expr))
    9207              :         {
    9208            9 :           if (complain & tf_error)
    9209            9 :             error_at (loc, "invalid cast of a prvalue expression of type "
    9210              :                       "%qT to type %qT",
    9211              :                       intype, type);
    9212            9 :           return error_mark_node;
    9213              :         }
    9214              : 
    9215              :       /* Warn about a reinterpret_cast from "A*" to "B&" if "A" and
    9216              :          "B" are related class types; the reinterpret_cast does not
    9217              :          adjust the pointer.  */
    9218         9538 :       if (TYPE_PTR_P (intype)
    9219            3 :           && (complain & tf_warning)
    9220         9541 :           && (comptypes (TREE_TYPE (intype), TREE_TYPE (type),
    9221              :                          COMPARE_BASE | COMPARE_DERIVED)))
    9222            3 :         warning_at (loc, 0, "casting %qT to %qT does not dereference pointer",
    9223              :                     intype, type);
    9224              : 
    9225         9538 :       expr = cp_build_addr_expr (expr, complain);
    9226              : 
    9227         9538 :       if (warn_strict_aliasing > 2)
    9228           72 :         cp_strict_aliasing_warning (EXPR_LOCATION (expr), type, expr);
    9229              : 
    9230         9538 :       if (expr != error_mark_node)
    9231         9538 :         expr = build_reinterpret_cast_1
    9232         9538 :           (loc, build_pointer_type (TREE_TYPE (type)), expr, c_cast_p,
    9233              :            valid_p, complain);
    9234         9538 :       if (expr != error_mark_node)
    9235              :         /* cp_build_indirect_ref isn't right for rvalue refs.  */
    9236         9535 :         expr = convert_from_reference (fold_convert (type, expr));
    9237         9538 :       return expr;
    9238              :     }
    9239              : 
    9240              :   /* As a G++ extension, we consider conversions from member
    9241              :      functions, and pointers to member functions to
    9242              :      pointer-to-function and pointer-to-void types.  If
    9243              :      -Wno-pmf-conversions has not been specified,
    9244              :      convert_member_func_to_ptr will issue an error message.  */
    9245          250 :   if ((TYPE_PTRMEMFUNC_P (intype)
    9246      1952708 :        || TREE_CODE (intype) == METHOD_TYPE)
    9247          244 :       && TYPE_PTR_P (type)
    9248      1953045 :       && (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE
    9249          123 :           || VOID_TYPE_P (TREE_TYPE (type))))
    9250          156 :     return convert_member_func_to_ptr (type, expr, complain);
    9251              : 
    9252              :   /* If the cast is not to a reference type, the lvalue-to-rvalue,
    9253              :      array-to-pointer, and function-to-pointer conversions are
    9254              :      performed.  */
    9255      1952724 :   expr = decay_conversion (expr, complain);
    9256              : 
    9257              :   /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
    9258              :      Strip such NOP_EXPRs if VALUE is being used in non-lvalue context.  */
    9259      1952724 :   if (TREE_CODE (expr) == NOP_EXPR
    9260      1952724 :       && TREE_TYPE (expr) == TREE_TYPE (TREE_OPERAND (expr, 0)))
    9261          388 :     expr = TREE_OPERAND (expr, 0);
    9262              : 
    9263      1952724 :   if (error_operand_p (expr))
    9264           30 :     return error_mark_node;
    9265              : 
    9266      1952694 :   intype = TREE_TYPE (expr);
    9267              : 
    9268              :   /* [expr.reinterpret.cast]
    9269              :      A pointer can be converted to any integral type large enough to
    9270              :      hold it. ... A value of type std::nullptr_t can be converted to
    9271              :      an integral type; the conversion has the same meaning and
    9272              :      validity as a conversion of (void*)0 to the integral type.  */
    9273      1952694 :   if (CP_INTEGRAL_TYPE_P (type)
    9274       163802 :       && (TYPE_PTR_P (intype) || NULLPTR_TYPE_P (intype)))
    9275              :     {
    9276       161883 :       if (TYPE_PRECISION (type) < TYPE_PRECISION (intype))
    9277              :         {
    9278           21 :           if (complain & tf_error)
    9279           15 :             permerror (loc, "cast from %qH to %qI loses precision",
    9280              :                        intype, type);
    9281              :           else
    9282            6 :             return error_mark_node;
    9283              :         }
    9284       161877 :       if (NULLPTR_TYPE_P (intype))
    9285           98 :         return build_int_cst (type, 0);
    9286              :     }
    9287              :   /* [expr.reinterpret.cast]
    9288              :      A value of integral or enumeration type can be explicitly
    9289              :      converted to a pointer.  */
    9290      1790811 :   else if (TYPE_PTR_P (type) && INTEGRAL_OR_ENUMERATION_TYPE_P (intype))
    9291              :     /* OK */
    9292              :     ;
    9293      1756972 :   else if ((INTEGRAL_OR_ENUMERATION_TYPE_P (type)
    9294      1755038 :             || TYPE_PTR_OR_PTRMEM_P (type))
    9295      1869768 :            && same_type_p (type, intype))
    9296              :     /* DR 799 */
    9297          515 :     return rvalue (expr);
    9298      1756457 :   else if (TYPE_PTRFN_P (type) && TYPE_PTRFN_P (intype))
    9299              :     {
    9300          266 :       if ((complain & tf_warning)
    9301          532 :           && !cxx_safe_function_type_cast_p (TREE_TYPE (type),
    9302          266 :                                              TREE_TYPE (intype)))
    9303          145 :         warning_at (loc, OPT_Wcast_function_type,
    9304              :                     "cast between incompatible function types"
    9305              :                     " from %qH to %qI", intype, type);
    9306          266 :       return build_nop_reinterpret (type, expr);
    9307              :     }
    9308      1756191 :   else if (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype))
    9309              :     {
    9310           79 :       if ((complain & tf_warning)
    9311          158 :           && !cxx_safe_function_type_cast_p
    9312           79 :                 (TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE_RAW (type)),
    9313           79 :                  TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE_RAW (intype))))
    9314           52 :         warning_at (loc, OPT_Wcast_function_type,
    9315              :                     "cast between incompatible pointer to member types"
    9316              :                     " from %qH to %qI", intype, type);
    9317           79 :       return build_nop_reinterpret (type, expr);
    9318              :     }
    9319           21 :   else if ((TYPE_PTRDATAMEM_P (type) && TYPE_PTRDATAMEM_P (intype))
    9320      1756112 :            || (TYPE_PTROBV_P (type) && TYPE_PTROBV_P (intype)))
    9321              :     {
    9322       111649 :       if (!c_cast_p
    9323       111649 :           && check_for_casting_away_constness (loc, intype, type,
    9324              :                                                REINTERPRET_CAST_EXPR,
    9325              :                                                complain))
    9326           21 :         return error_mark_node;
    9327              :       /* Warn about possible alignment problems.  */
    9328       111628 :       if ((STRICT_ALIGNMENT || warn_cast_align == 2)
    9329           24 :           && (complain & tf_warning)
    9330           24 :           && !VOID_TYPE_P (type)
    9331           24 :           && TREE_CODE (TREE_TYPE (intype)) != FUNCTION_TYPE
    9332           24 :           && COMPLETE_TYPE_P (TREE_TYPE (type))
    9333           24 :           && COMPLETE_TYPE_P (TREE_TYPE (intype))
    9334       111676 :           && min_align_of_type (TREE_TYPE (type))
    9335           24 :              > min_align_of_type (TREE_TYPE (intype)))
    9336           18 :         warning_at (loc, OPT_Wcast_align, "cast from %qH to %qI "
    9337              :                     "increases required alignment of target type",
    9338              :                     intype, type);
    9339              : 
    9340       111628 :       if (warn_strict_aliasing <= 2)
    9341              :         /* strict_aliasing_warning STRIP_NOPs its expr.  */
    9342        99794 :         cp_strict_aliasing_warning (EXPR_LOCATION (expr), type, expr);
    9343              : 
    9344       111628 :       return build_nop_reinterpret (type, expr);
    9345              :     }
    9346          297 :   else if ((TYPE_PTRFN_P (type) && TYPE_PTROBV_P (intype))
    9347      1644623 :            || (TYPE_PTRFN_P (intype) && TYPE_PTROBV_P (type)))
    9348              :     {
    9349          276 :       if (complain & tf_warning)
    9350              :         /* C++11 5.2.10 p8 says that "Converting a function pointer to an
    9351              :            object pointer type or vice versa is conditionally-supported."  */
    9352          276 :         warning_at (loc, OPT_Wconditionally_supported,
    9353              :                     "casting between pointer-to-function and "
    9354              :                     "pointer-to-object is conditionally-supported");
    9355          276 :       return build_nop_reinterpret (type, expr);
    9356              :     }
    9357      1644187 :   else if (gnu_vector_type_p (type) && scalarish_type_p (intype))
    9358      1642218 :     return convert_to_vector (type, rvalue (expr));
    9359         1969 :   else if (gnu_vector_type_p (intype)
    9360         1969 :            && INTEGRAL_OR_ENUMERATION_TYPE_P (type))
    9361         1867 :     return convert_to_integer_nofold (type, expr);
    9362              :   else
    9363              :     {
    9364          102 :       if (valid_p)
    9365           84 :         *valid_p = false;
    9366          102 :       if (complain & tf_error)
    9367           93 :         error_at (loc, "invalid cast from type %qT to type %qT",
    9368              :                   intype, type);
    9369          102 :       return error_mark_node;
    9370              :     }
    9371              : 
    9372       195618 :   expr = cp_convert (type, expr, complain);
    9373       195618 :   if (TREE_CODE (expr) == NOP_EXPR)
    9374              :     /* Mark any nop_expr that created as a reintepret_cast.  */
    9375            0 :     REINTERPRET_CAST_P (expr) = true;
    9376              :   return expr;
    9377              : }
    9378              : 
    9379              : tree
    9380       729200 : build_reinterpret_cast (location_t loc, tree type, tree expr,
    9381              :                         tsubst_flags_t complain)
    9382              : {
    9383       729200 :   tree r;
    9384              : 
    9385       729200 :   if (type == error_mark_node || expr == error_mark_node)
    9386              :     return error_mark_node;
    9387              : 
    9388       729193 :   if (processing_template_decl)
    9389              :     {
    9390       590117 :       tree t = build_min (REINTERPRET_CAST_EXPR, type, expr);
    9391              : 
    9392       590117 :       if (!TREE_SIDE_EFFECTS (t)
    9393       590117 :           && type_dependent_expression_p (expr))
    9394              :         /* There might turn out to be side effects inside expr.  */
    9395       282899 :         TREE_SIDE_EFFECTS (t) = 1;
    9396       590117 :       r = convert_from_reference (t);
    9397       590117 :       protected_set_expr_location (r, loc);
    9398       590117 :       return r;
    9399              :     }
    9400              : 
    9401       139076 :   r = build_reinterpret_cast_1 (loc, type, expr, /*c_cast_p=*/false,
    9402              :                                 /*valid_p=*/NULL, complain);
    9403       139076 :   if (r != error_mark_node)
    9404              :     {
    9405       139013 :       maybe_warn_about_useless_cast (loc, type, expr, complain);
    9406       139013 :       maybe_warn_about_cast_ignoring_quals (loc, type, complain);
    9407              :     }
    9408       139076 :   protected_set_expr_location (r, loc);
    9409       139076 :   return r;
    9410              : }
    9411              : 
    9412              : /* Perform a const_cast from EXPR to TYPE.  If the cast is valid,
    9413              :    return an appropriate expression.  Otherwise, return
    9414              :    error_mark_node.  If the cast is not valid, and COMPLAIN is true,
    9415              :    then a diagnostic will be issued.  If VALID_P is non-NULL, we are
    9416              :    performing a C-style cast, its value upon return will indicate
    9417              :    whether or not the conversion succeeded.  */
    9418              : 
    9419              : static tree
    9420     37858882 : build_const_cast_1 (location_t loc, tree dst_type, tree expr,
    9421              :                     tsubst_flags_t complain, bool *valid_p)
    9422              : {
    9423     37858882 :   tree src_type;
    9424     37858882 :   tree reference_type;
    9425              : 
    9426              :   /* Callers are responsible for handling error_mark_node as a
    9427              :      destination type.  */
    9428     37858882 :   gcc_assert (dst_type != error_mark_node);
    9429              :   /* In a template, callers should be building syntactic
    9430              :      representations of casts, not using this machinery.  */
    9431     37858882 :   gcc_assert (!processing_template_decl);
    9432              : 
    9433              :   /* Assume the conversion is invalid.  */
    9434     37858882 :   if (valid_p)
    9435     37661384 :     *valid_p = false;
    9436              : 
    9437     37858882 :   if (!INDIRECT_TYPE_P (dst_type) && !TYPE_PTRDATAMEM_P (dst_type))
    9438              :     {
    9439     36856213 :       if (complain & tf_error)
    9440            9 :         error_at (loc, "invalid use of %<const_cast%> with type %qT, "
    9441              :                   "which is not a pointer, reference, "
    9442              :                   "nor a pointer-to-data-member type", dst_type);
    9443     36856213 :       return error_mark_node;
    9444              :     }
    9445              : 
    9446      1002669 :   if (TREE_CODE (TREE_TYPE (dst_type)) == FUNCTION_TYPE)
    9447              :     {
    9448         4133 :       if (complain & tf_error)
    9449            6 :         error_at (loc, "invalid use of %<const_cast%> with type %qT, "
    9450              :                   "which is a pointer or reference to a function type",
    9451              :                   dst_type);
    9452         4133 :        return error_mark_node;
    9453              :     }
    9454              : 
    9455              :   /* A prvalue of non-class type is cv-unqualified.  */
    9456       998536 :   dst_type = cv_unqualified (dst_type);
    9457              : 
    9458              :   /* Save casted types in the function's used types hash table.  */
    9459       998536 :   used_types_insert (dst_type);
    9460              : 
    9461       998536 :   src_type = TREE_TYPE (expr);
    9462              :   /* Expressions do not really have reference types.  */
    9463       998536 :   if (TYPE_REF_P (src_type))
    9464            0 :     src_type = TREE_TYPE (src_type);
    9465              : 
    9466              :   /* [expr.const.cast]
    9467              : 
    9468              :      For two object types T1 and T2, if a pointer to T1 can be explicitly
    9469              :      converted to the type "pointer to T2" using a const_cast, then the
    9470              :      following conversions can also be made:
    9471              : 
    9472              :      -- an lvalue of type T1 can be explicitly converted to an lvalue of
    9473              :      type T2 using the cast const_cast<T2&>;
    9474              : 
    9475              :      -- a glvalue of type T1 can be explicitly converted to an xvalue of
    9476              :      type T2 using the cast const_cast<T2&&>; and
    9477              : 
    9478              :      -- if T1 is a class type, a prvalue of type T1 can be explicitly
    9479              :      converted to an xvalue of type T2 using the cast const_cast<T2&&>.  */
    9480              : 
    9481       998536 :   if (TYPE_REF_P (dst_type))
    9482              :     {
    9483       126364 :       reference_type = dst_type;
    9484       126364 :       if (!TYPE_REF_IS_RVALUE (dst_type)
    9485       126364 :           ? lvalue_p (expr)
    9486         1263 :           : obvalue_p (expr))
    9487              :         /* OK.  */;
    9488              :       else
    9489              :         {
    9490           35 :           if (complain & tf_error)
    9491            9 :             error_at (loc, "invalid %<const_cast%> of an rvalue of type %qT "
    9492              :                       "to type %qT",
    9493              :                       src_type, dst_type);
    9494           35 :           return error_mark_node;
    9495              :         }
    9496       126329 :       dst_type = build_pointer_type (TREE_TYPE (dst_type));
    9497       126329 :       src_type = build_pointer_type (src_type);
    9498              :     }
    9499              :   else
    9500              :     {
    9501       872172 :       reference_type = NULL_TREE;
    9502              :       /* If the destination type is not a reference type, the
    9503              :          lvalue-to-rvalue, array-to-pointer, and function-to-pointer
    9504              :          conversions are performed.  */
    9505       872172 :       src_type = type_decays_to (src_type);
    9506       872172 :       if (src_type == error_mark_node)
    9507              :         return error_mark_node;
    9508              :     }
    9509              : 
    9510       998501 :   if (TYPE_PTR_P (src_type) || TYPE_PTRDATAMEM_P (src_type))
    9511              :     {
    9512       581084 :       if (comp_ptr_ttypes_const (dst_type, src_type, bounds_none))
    9513              :         {
    9514       342642 :           if (valid_p)
    9515              :             {
    9516       145222 :               *valid_p = true;
    9517              :               /* This cast is actually a C-style cast.  Issue a warning if
    9518              :                  the user is making a potentially unsafe cast.  */
    9519       145222 :               check_for_casting_away_constness (loc, src_type, dst_type,
    9520              :                                                 CAST_EXPR, complain);
    9521              :               /* ??? comp_ptr_ttypes_const ignores TYPE_ALIGN.  */
    9522       145222 :               if ((STRICT_ALIGNMENT || warn_cast_align == 2)
    9523            3 :                   && (complain & tf_warning)
    9524       145228 :                   && min_align_of_type (TREE_TYPE (dst_type))
    9525            3 :                      > min_align_of_type (TREE_TYPE (src_type)))
    9526            3 :                 warning_at (loc, OPT_Wcast_align, "cast from %qH to %qI "
    9527              :                             "increases required alignment of target type",
    9528              :                             src_type, dst_type);
    9529              :             }
    9530       342642 :           if (reference_type)
    9531              :             {
    9532       125263 :               expr = cp_build_addr_expr (expr, complain);
    9533       125263 :               if (expr == error_mark_node)
    9534              :                 return error_mark_node;
    9535       125245 :               expr = build_nop (reference_type, expr);
    9536       125245 :               return convert_from_reference (expr);
    9537              :             }
    9538              :           else
    9539              :             {
    9540       217379 :               expr = decay_conversion (expr, complain);
    9541       217379 :               if (expr == error_mark_node)
    9542              :                 return error_mark_node;
    9543              : 
    9544              :               /* build_c_cast puts on a NOP_EXPR to make the result not an
    9545              :                  lvalue.  Strip such NOP_EXPRs if VALUE is being used in
    9546              :                  non-lvalue context.  */
    9547       217379 :               if (TREE_CODE (expr) == NOP_EXPR
    9548       217379 :                   && TREE_TYPE (expr) == TREE_TYPE (TREE_OPERAND (expr, 0)))
    9549            3 :                 expr = TREE_OPERAND (expr, 0);
    9550       217379 :               return build_nop (dst_type, expr);
    9551              :             }
    9552              :         }
    9553       238442 :       else if (valid_p
    9554       476836 :                && !at_least_as_qualified_p (TREE_TYPE (dst_type),
    9555       238394 :                                             TREE_TYPE (src_type)))
    9556        15111 :         check_for_casting_away_constness (loc, src_type, dst_type,
    9557              :                                           CAST_EXPR, complain);
    9558              :     }
    9559              : 
    9560       655859 :   if (complain & tf_error)
    9561           30 :     error_at (loc, "invalid %<const_cast%> from type %qT to type %qT",
    9562              :               src_type, dst_type);
    9563       655859 :   return error_mark_node;
    9564              : }
    9565              : 
    9566              : tree
    9567       672407 : build_const_cast (location_t loc, tree type, tree expr,
    9568              :                   tsubst_flags_t complain)
    9569              : {
    9570       672407 :   tree r;
    9571              : 
    9572       672407 :   if (type == error_mark_node || error_operand_p (expr))
    9573              :     return error_mark_node;
    9574              : 
    9575       672399 :   if (processing_template_decl)
    9576              :     {
    9577       474901 :       tree t = build_min (CONST_CAST_EXPR, type, expr);
    9578              : 
    9579       474901 :       if (!TREE_SIDE_EFFECTS (t)
    9580       474901 :           && type_dependent_expression_p (expr))
    9581              :         /* There might turn out to be side effects inside expr.  */
    9582       367389 :         TREE_SIDE_EFFECTS (t) = 1;
    9583       474901 :       r = convert_from_reference (t);
    9584       474901 :       protected_set_expr_location (r, loc);
    9585       474901 :       return r;
    9586              :     }
    9587              : 
    9588       197498 :   r = build_const_cast_1 (loc, type, expr, complain, /*valid_p=*/NULL);
    9589       197498 :   if (r != error_mark_node)
    9590              :     {
    9591       197420 :       maybe_warn_about_useless_cast (loc, type, expr, complain);
    9592       197420 :       maybe_warn_about_cast_ignoring_quals (loc, type, complain);
    9593              :     }
    9594       197498 :   protected_set_expr_location (r, loc);
    9595       197498 :   return r;
    9596              : }
    9597              : 
    9598              : /* Like cp_build_c_cast, but for the c-common bits.  */
    9599              : 
    9600              : tree
    9601            0 : build_c_cast (location_t loc, tree type, tree expr)
    9602              : {
    9603            0 :   return cp_build_c_cast (loc, type, expr, tf_warning_or_error);
    9604              : }
    9605              : 
    9606              : /* Like the "build_c_cast" used for c-common, but using cp_expr to
    9607              :    preserve location information even for tree nodes that don't
    9608              :    support it.  */
    9609              : 
    9610              : cp_expr
    9611     10412304 : build_c_cast (location_t loc, tree type, cp_expr expr)
    9612              : {
    9613     10412304 :   cp_expr result = cp_build_c_cast (loc, type, expr, tf_warning_or_error);
    9614     10412304 :   result.set_location (loc);
    9615     10412304 :   return result;
    9616              : }
    9617              : 
    9618              : /* Build an expression representing an explicit C-style cast to type
    9619              :    TYPE of expression EXPR.  */
    9620              : 
    9621              : tree
    9622     40385521 : cp_build_c_cast (location_t loc, tree type, tree expr,
    9623              :                  tsubst_flags_t complain)
    9624              : {
    9625     40385521 :   tree value = expr;
    9626     40385521 :   tree result;
    9627     40385521 :   bool valid_p;
    9628              : 
    9629     40385521 :   if (type == error_mark_node || error_operand_p (expr))
    9630              :     return error_mark_node;
    9631              : 
    9632     40385339 :   if (processing_template_decl)
    9633              :     {
    9634      2723946 :       tree t = build_min (CAST_EXPR, type,
    9635              :                           tree_cons (NULL_TREE, value, NULL_TREE));
    9636              :       /* We don't know if it will or will not have side effects.  */
    9637      2723946 :       TREE_SIDE_EFFECTS (t) = 1;
    9638      2723946 :       return convert_from_reference (t);
    9639              :     }
    9640              : 
    9641              :   /* Casts to a (pointer to a) specific ObjC class (or 'id' or
    9642              :      'Class') should always be retained, because this information aids
    9643              :      in method lookup.  */
    9644     37661393 :   if (objc_is_object_ptr (type)
    9645     37661393 :       && objc_is_object_ptr (TREE_TYPE (expr)))
    9646            0 :     return build_nop (type, expr);
    9647              : 
    9648              :   /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
    9649              :      Strip such NOP_EXPRs if VALUE is being used in non-lvalue context.  */
    9650     37661393 :   if (!TYPE_REF_P (type)
    9651     37659224 :       && TREE_CODE (value) == NOP_EXPR
    9652     38107785 :       && TREE_TYPE (value) == TREE_TYPE (TREE_OPERAND (value, 0)))
    9653       220317 :     value = TREE_OPERAND (value, 0);
    9654              : 
    9655     37661393 :   if (TREE_CODE (type) == ARRAY_TYPE)
    9656              :     {
    9657              :       /* Allow casting from T1* to T2[] because Cfront allows it.
    9658              :          NIHCL uses it. It is not valid ISO C++ however.  */
    9659            3 :       if (TYPE_PTR_P (TREE_TYPE (expr)))
    9660              :         {
    9661            0 :           if (complain & tf_error)
    9662            0 :             permerror (loc, "ISO C++ forbids casting to an array type %qT",
    9663              :                        type);
    9664              :           else
    9665            0 :             return error_mark_node;
    9666            0 :           type = build_pointer_type (TREE_TYPE (type));
    9667              :         }
    9668              :       else
    9669              :         {
    9670            3 :           if (complain & tf_error)
    9671            3 :             error_at (loc, "ISO C++ forbids casting to an array type %qT",
    9672              :                       type);
    9673            3 :           return error_mark_node;
    9674              :         }
    9675              :     }
    9676              : 
    9677     37661390 :   if (FUNC_OR_METHOD_TYPE_P (type))
    9678              :     {
    9679           15 :       if (complain & tf_error)
    9680           15 :         error_at (loc, "invalid cast to function type %qT", type);
    9681           15 :       return error_mark_node;
    9682              :     }
    9683              : 
    9684     37661375 :   if (TYPE_PTR_P (type)
    9685       802865 :       && TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE
    9686              :       /* Casting to an integer of smaller size is an error detected elsewhere.  */
    9687       416029 :       && TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (value))
    9688              :       /* Don't warn about converting any constant.  */
    9689     38022177 :       && !TREE_CONSTANT (value))
    9690           47 :     warning_at (loc, OPT_Wint_to_pointer_cast,
    9691              :                 "cast to pointer from integer of different size");
    9692              : 
    9693              :   /* A C-style cast can be a const_cast.  */
    9694     37661375 :   result = build_const_cast_1 (loc, type, value, complain & tf_warning,
    9695              :                                &valid_p);
    9696     37661375 :   if (valid_p)
    9697              :     {
    9698       145213 :       if (result != error_mark_node)
    9699              :         {
    9700       145204 :           maybe_warn_about_useless_cast (loc, type, value, complain);
    9701       145204 :           maybe_warn_about_cast_ignoring_quals (loc, type, complain);
    9702              :         }
    9703            9 :       else if (complain & tf_error)
    9704            9 :         build_const_cast_1 (loc, type, value, tf_error, &valid_p);
    9705       145213 :       return result;
    9706              :     }
    9707              : 
    9708              :   /* Or a static cast.  */
    9709     37516162 :   result = build_static_cast_1 (loc, type, value, /*c_cast_p=*/true,
    9710              :                                 &valid_p, complain);
    9711              :   /* Or a reinterpret_cast.  */
    9712     37516162 :   if (!valid_p)
    9713      1813813 :     result = build_reinterpret_cast_1 (loc, type, value, /*c_cast_p=*/true,
    9714              :                                        &valid_p, complain);
    9715              :   /* The static_cast or reinterpret_cast may be followed by a
    9716              :      const_cast.  */
    9717     37516162 :   if (valid_p
    9718              :       /* A valid cast may result in errors if, for example, a
    9719              :          conversion to an ambiguous base class is required.  */
    9720     37516162 :       && !error_operand_p (result))
    9721              :     {
    9722     37515758 :       tree result_type;
    9723              : 
    9724     37515758 :       maybe_warn_about_useless_cast (loc, type, value, complain);
    9725     37515758 :       maybe_warn_about_cast_ignoring_quals (loc, type, complain);
    9726              : 
    9727              :       /* Non-class rvalues always have cv-unqualified type.  */
    9728     37515758 :       if (!CLASS_TYPE_P (type))
    9729     34869648 :         type = TYPE_MAIN_VARIANT (type);
    9730     37515758 :       result_type = TREE_TYPE (result);
    9731     37515758 :       if (!CLASS_TYPE_P (result_type) && !TYPE_REF_P (type))
    9732     34868560 :         result_type = TYPE_MAIN_VARIANT (result_type);
    9733              :       /* If the type of RESULT does not match TYPE, perform a
    9734              :          const_cast to make it match.  If the static_cast or
    9735              :          reinterpret_cast succeeded, we will differ by at most
    9736              :          cv-qualification, so the follow-on const_cast is guaranteed
    9737              :          to succeed.  */
    9738     37515758 :       if (!same_type_p (non_reference (type), non_reference (result_type)))
    9739              :         {
    9740            0 :           result = build_const_cast_1 (loc, type, result, tf_none, &valid_p);
    9741            0 :           gcc_assert (valid_p);
    9742              :         }
    9743     37515758 :       return result;
    9744              :     }
    9745              : 
    9746          404 :   return error_mark_node;
    9747              : }
    9748              : 
    9749              : /* Warn when a value is moved to itself with std::move.  LHS is the target,
    9750              :    RHS may be the std::move call, and LOC is the location of the whole
    9751              :    assignment.  Return true if we warned.  */
    9752              : 
    9753              : bool
    9754     27743315 : maybe_warn_self_move (location_t loc, tree lhs, tree rhs)
    9755              : {
    9756     27743315 :   if (!warn_self_move)
    9757              :     return false;
    9758              : 
    9759              :   /* C++98 doesn't know move.  */
    9760       365490 :   if (cxx_dialect < cxx11)
    9761              :     return false;
    9762              : 
    9763       345604 :   if (processing_template_decl)
    9764              :     return false;
    9765              : 
    9766        26178 :   if (!REFERENCE_REF_P (rhs)
    9767       301004 :       || TREE_CODE (TREE_OPERAND (rhs, 0)) != CALL_EXPR)
    9768              :     return false;
    9769         4626 :   tree fn = TREE_OPERAND (rhs, 0);
    9770         4626 :   if (!is_std_move_p (fn))
    9771              :     return false;
    9772              : 
    9773              :   /* Just a little helper to strip * and various NOPs.  */
    9774         6519 :   auto extract_op = [] (tree &op) {
    9775         4346 :     STRIP_NOPS (op);
    9776         5567 :     while (INDIRECT_REF_P (op))
    9777         1221 :       op = TREE_OPERAND (op, 0);
    9778         4346 :     op = maybe_undo_parenthesized_ref (op);
    9779         4346 :     STRIP_ANY_LOCATION_WRAPPER (op);
    9780         4346 :   };
    9781              : 
    9782         2173 :   tree arg = CALL_EXPR_ARG (fn, 0);
    9783         2173 :   extract_op (arg);
    9784         2173 :   if (TREE_CODE (arg) == ADDR_EXPR)
    9785         1495 :     arg = TREE_OPERAND (arg, 0);
    9786         2173 :   tree type = TREE_TYPE (lhs);
    9787         2173 :   tree orig_lhs = lhs;
    9788         2173 :   extract_op (lhs);
    9789         2173 :   if (cp_tree_equal (lhs, arg)
    9790              :       /* Also warn in a member-initializer-list, as in : i(std::move(i)).  */
    9791         2173 :       || (TREE_CODE (lhs) == FIELD_DECL
    9792          640 :           && TREE_CODE (arg) == COMPONENT_REF
    9793          305 :           && cp_tree_equal (TREE_OPERAND (arg, 0), current_class_ref)
    9794            6 :           && TREE_OPERAND (arg, 1) == lhs))
    9795          117 :     if (warning_at (loc, OPT_Wself_move,
    9796              :                     "moving %qE of type %qT to itself", orig_lhs, type))
    9797              :       return true;
    9798              : 
    9799              :   return false;
    9800              : }
    9801              : 
    9802              : /* For use from the C common bits.  */
    9803              : tree
    9804         4766 : build_modify_expr (location_t location,
    9805              :                    tree lhs, tree /*lhs_origtype*/,
    9806              :                    enum tree_code modifycode,
    9807              :                    location_t /*rhs_location*/, tree rhs,
    9808              :                    tree /*rhs_origtype*/)
    9809              : {
    9810         4766 :   return cp_build_modify_expr (location, lhs, modifycode, rhs,
    9811         4766 :                                tf_warning_or_error);
    9812              : }
    9813              : 
    9814              : /* Build an assignment expression of lvalue LHS from value RHS.
    9815              :    MODIFYCODE is the code for a binary operator that we use
    9816              :    to combine the old value of LHS with RHS to get the new value.
    9817              :    Or else MODIFYCODE is NOP_EXPR meaning do a simple assignment.
    9818              : 
    9819              :    C++: If MODIFYCODE is INIT_EXPR, then leave references unbashed.  */
    9820              : 
    9821              : tree
    9822     36150948 : cp_build_modify_expr (location_t loc, tree lhs, enum tree_code modifycode,
    9823              :                       tree rhs, tsubst_flags_t complain)
    9824              : {
    9825     36150948 :   lhs = mark_lvalue_use_nonread (lhs);
    9826              : 
    9827     36150948 :   tree result = NULL_TREE;
    9828     36150948 :   tree newrhs = rhs;
    9829     36150948 :   tree lhstype = TREE_TYPE (lhs);
    9830     36150948 :   tree olhs = lhs;
    9831     36150948 :   tree olhstype = lhstype;
    9832     36150948 :   bool plain_assign = (modifycode == NOP_EXPR);
    9833     36150948 :   bool compound_side_effects_p = false;
    9834     36150948 :   tree preeval = NULL_TREE;
    9835              : 
    9836              :   /* Avoid duplicate error messages from operands that had errors.  */
    9837     36150948 :   if (error_operand_p (lhs) || error_operand_p (rhs))
    9838           19 :     return error_mark_node;
    9839              : 
    9840     36151011 :   while (TREE_CODE (lhs) == COMPOUND_EXPR)
    9841              :     {
    9842           82 :       if (TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0)))
    9843           70 :         compound_side_effects_p = true;
    9844           82 :       lhs = TREE_OPERAND (lhs, 1);
    9845              :     }
    9846              : 
    9847              :   /* Handle control structure constructs used as "lvalues".  Note that we
    9848              :      leave COMPOUND_EXPR on the LHS because it is sequenced after the RHS.  */
    9849     36150929 :   switch (TREE_CODE (lhs))
    9850              :     {
    9851              :       /* Handle --foo = 5; as these are valid constructs in C++.  */
    9852           27 :     case PREDECREMENT_EXPR:
    9853           27 :     case PREINCREMENT_EXPR:
    9854           27 :       if (compound_side_effects_p)
    9855            9 :         newrhs = rhs = stabilize_expr (rhs, &preeval);
    9856           27 :       lhs = genericize_compound_lvalue (lhs);
    9857          173 :     maybe_add_compound:
    9858              :       /* If we had (bar, --foo) = 5; or (bar, (baz, --foo)) = 5;
    9859              :          and looked through the COMPOUND_EXPRs, readd them now around
    9860              :          the resulting lhs.  */
    9861          173 :       if (TREE_CODE (olhs) == COMPOUND_EXPR)
    9862              :         {
    9863            9 :           lhs = build2 (COMPOUND_EXPR, lhstype, TREE_OPERAND (olhs, 0), lhs);
    9864            9 :           tree *ptr = &TREE_OPERAND (lhs, 1);
    9865            9 :           for (olhs = TREE_OPERAND (olhs, 1);
    9866           12 :                TREE_CODE (olhs) == COMPOUND_EXPR;
    9867            3 :                olhs = TREE_OPERAND (olhs, 1))
    9868              :             {
    9869            3 :               *ptr = build2 (COMPOUND_EXPR, lhstype,
    9870            3 :                              TREE_OPERAND (olhs, 0), *ptr);
    9871            3 :               ptr = &TREE_OPERAND (*ptr, 1);
    9872              :             }
    9873              :         }
    9874              :       break;
    9875              : 
    9876          146 :     case MODIFY_EXPR:
    9877          146 :       if (compound_side_effects_p)
    9878            0 :         newrhs = rhs = stabilize_expr (rhs, &preeval);
    9879          146 :       lhs = genericize_compound_lvalue (lhs);
    9880          146 :       goto maybe_add_compound;
    9881              : 
    9882            0 :     case MIN_EXPR:
    9883            0 :     case MAX_EXPR:
    9884              :       /* MIN_EXPR and MAX_EXPR are currently only permitted as lvalues,
    9885              :          when neither operand has side-effects.  */
    9886            0 :       if (!lvalue_or_else (lhs, lv_assign, complain))
    9887            0 :         return error_mark_node;
    9888              : 
    9889            0 :       gcc_assert (!TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0))
    9890              :                   && !TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 1)));
    9891              : 
    9892            0 :       lhs = build3 (COND_EXPR, TREE_TYPE (lhs),
    9893            0 :                     build2 (TREE_CODE (lhs) == MIN_EXPR ? LE_EXPR : GE_EXPR,
    9894              :                             boolean_type_node,
    9895            0 :                             TREE_OPERAND (lhs, 0),
    9896            0 :                             TREE_OPERAND (lhs, 1)),
    9897            0 :                     TREE_OPERAND (lhs, 0),
    9898            0 :                     TREE_OPERAND (lhs, 1));
    9899          212 :       gcc_fallthrough ();
    9900              : 
    9901              :       /* Handle (a ? b : c) used as an "lvalue".  */
    9902          212 :     case COND_EXPR:
    9903          212 :       {
    9904              :         /* Produce (a ? (b = rhs) : (c = rhs))
    9905              :            except that the RHS goes through a save-expr
    9906              :            so the code to compute it is only emitted once.  */
    9907          212 :         if (VOID_TYPE_P (TREE_TYPE (rhs)))
    9908              :           {
    9909           18 :             if (complain & tf_error)
    9910           24 :               error_at (cp_expr_loc_or_loc (rhs, loc),
    9911              :                         "void value not ignored as it ought to be");
    9912           18 :             return error_mark_node;
    9913              :           }
    9914              : 
    9915          194 :         rhs = stabilize_expr (rhs, &preeval);
    9916              : 
    9917              :         /* Check this here to avoid odd errors when trying to convert
    9918              :            a throw to the type of the COND_EXPR.  */
    9919          194 :         if (!lvalue_or_else (lhs, lv_assign, complain))
    9920            6 :           return error_mark_node;
    9921              : 
    9922          188 :         tree op1 = TREE_OPERAND (lhs, 1);
    9923          188 :         if (TREE_CODE (op1) != THROW_EXPR)
    9924          182 :           op1 = cp_build_modify_expr (loc, op1, modifycode, rhs, complain);
    9925              :         /* When sanitizing undefined behavior, even when rhs doesn't need
    9926              :            stabilization at this point, the sanitization might add extra
    9927              :            SAVE_EXPRs in there and so make sure there is no tree sharing
    9928              :            in the rhs, otherwise those SAVE_EXPRs will have initialization
    9929              :            only in one of the two branches.  */
    9930          188 :         if (sanitize_flags_p (SANITIZE_UNDEFINED
    9931              :                               | SANITIZE_UNDEFINED_NONDEFAULT))
    9932            3 :           rhs = unshare_expr (rhs);
    9933          188 :         tree op2 = TREE_OPERAND (lhs, 2);
    9934          188 :         if (TREE_CODE (op2) != THROW_EXPR)
    9935          182 :           op2 = cp_build_modify_expr (loc, op2, modifycode, rhs, complain);
    9936          188 :         tree cond = build_conditional_expr (input_location,
    9937          188 :                                             TREE_OPERAND (lhs, 0), op1, op2,
    9938              :                                             complain);
    9939              : 
    9940          188 :         if (cond == error_mark_node)
    9941              :           return cond;
    9942              :         /* If we had (e, (a ? b : c)) = d; or (e, (f, (a ? b : c))) = d;
    9943              :            and looked through the COMPOUND_EXPRs, readd them now around
    9944              :            the resulting cond before adding the preevaluated rhs.  */
    9945          185 :         if (TREE_CODE (olhs) == COMPOUND_EXPR)
    9946              :           {
    9947           18 :             cond = build2 (COMPOUND_EXPR, TREE_TYPE (cond),
    9948           18 :                            TREE_OPERAND (olhs, 0), cond);
    9949           18 :             tree *ptr = &TREE_OPERAND (cond, 1);
    9950           18 :             for (olhs = TREE_OPERAND (olhs, 1);
    9951           21 :                  TREE_CODE (olhs) == COMPOUND_EXPR;
    9952            3 :                  olhs = TREE_OPERAND (olhs, 1))
    9953              :               {
    9954            3 :                 *ptr = build2 (COMPOUND_EXPR, TREE_TYPE (cond),
    9955            3 :                                TREE_OPERAND (olhs, 0), *ptr);
    9956            3 :                 ptr = &TREE_OPERAND (*ptr, 1);
    9957              :               }
    9958              :           }
    9959              :         /* Make sure the code to compute the rhs comes out
    9960              :            before the split.  */
    9961          185 :         result = cond;
    9962          185 :         goto ret;
    9963              :       }
    9964              : 
    9965              :     default:
    9966              :       lhs = olhs;
    9967              :       break;
    9968              :     }
    9969              : 
    9970     36150717 :   if (modifycode == INIT_EXPR)
    9971              :     {
    9972      4097039 :       if (BRACE_ENCLOSED_INITIALIZER_P (rhs))
    9973              :         /* Do the default thing.  */;
    9974      3904371 :       else if (TREE_CODE (rhs) == CONSTRUCTOR)
    9975              :         {
    9976              :           /* Compound literal.  */
    9977           96 :           if (! same_type_p (TREE_TYPE (rhs), lhstype))
    9978              :             /* Call convert to generate an error; see PR 11063.  */
    9979            0 :             rhs = convert (lhstype, rhs);
    9980           96 :           result = cp_build_init_expr (lhs, rhs);
    9981           96 :           TREE_SIDE_EFFECTS (result) = 1;
    9982           96 :           goto ret;
    9983              :         }
    9984      3904275 :       else if (! MAYBE_CLASS_TYPE_P (lhstype))
    9985              :         /* Do the default thing.  */;
    9986              :       else
    9987              :         {
    9988        40038 :           releasing_vec rhs_vec = make_tree_vector_single (rhs);
    9989        40038 :           result = build_special_member_call (lhs, complete_ctor_identifier,
    9990              :                                               &rhs_vec, lhstype, LOOKUP_NORMAL,
    9991              :                                               complain);
    9992        40038 :           if (result == NULL_TREE)
    9993            0 :             return error_mark_node;
    9994        40038 :           goto ret;
    9995        40038 :         }
    9996              :     }
    9997              :   else
    9998              :     {
    9999     32053678 :       lhs = require_complete_type (lhs, complain);
   10000     32053678 :       if (lhs == error_mark_node)
   10001              :         return error_mark_node;
   10002              : 
   10003     32053608 :       if (modifycode == NOP_EXPR)
   10004              :         {
   10005     27694169 :           maybe_warn_self_move (loc, lhs, rhs);
   10006              : 
   10007     27694169 :           if (c_dialect_objc ())
   10008              :             {
   10009            0 :               result = objc_maybe_build_modify_expr (lhs, rhs);
   10010            0 :               if (result)
   10011            0 :                 goto ret;
   10012              :             }
   10013              : 
   10014              :           /* `operator=' is not an inheritable operator.  */
   10015     27694169 :           if (! MAYBE_CLASS_TYPE_P (lhstype))
   10016              :             /* Do the default thing.  */;
   10017              :           else
   10018              :             {
   10019      3357922 :               result = build_new_op (input_location, MODIFY_EXPR,
   10020              :                                      LOOKUP_NORMAL, lhs, rhs,
   10021              :                                      make_node (NOP_EXPR), NULL_TREE,
   10022              :                                      /*overload=*/NULL, complain);
   10023      3357922 :               if (result == NULL_TREE)
   10024            0 :                 return error_mark_node;
   10025      3357922 :               goto ret;
   10026              :             }
   10027              :           lhstype = olhstype;
   10028              :         }
   10029              :       else
   10030              :         {
   10031      4359439 :           tree init = NULL_TREE;
   10032              : 
   10033              :           /* A binary op has been requested.  Combine the old LHS
   10034              :              value with the RHS producing the value we should actually
   10035              :              store into the LHS.  */
   10036      4359439 :           gcc_assert (!((TYPE_REF_P (lhstype)
   10037              :                          && MAYBE_CLASS_TYPE_P (TREE_TYPE (lhstype)))
   10038              :                         || MAYBE_CLASS_TYPE_P (lhstype)));
   10039              : 
   10040              :           /* Preevaluate the RHS to make sure its evaluation is complete
   10041              :              before the lvalue-to-rvalue conversion of the LHS:
   10042              : 
   10043              :              [expr.ass] With respect to an indeterminately-sequenced
   10044              :              function call, the operation of a compound assignment is a
   10045              :              single evaluation. [ Note: Therefore, a function call shall
   10046              :              not intervene between the lvalue-to-rvalue conversion and the
   10047              :              side effect associated with any single compound assignment
   10048              :              operator. -- end note ]  */
   10049      4359439 :           lhs = cp_stabilize_reference (lhs);
   10050      4359439 :           rhs = decay_conversion (rhs, complain);
   10051      4359439 :           if (rhs == error_mark_node)
   10052          123 :             return error_mark_node;
   10053              : 
   10054      4359436 :           {
   10055      4359436 :             auto_diagnostic_group d;
   10056      4359436 :             rhs = stabilize_expr (rhs, &init);
   10057      4359436 :             bool clear_decl_read = false;
   10058      4359436 :             tree stripped_lhs = tree_strip_any_location_wrapper (lhs);
   10059      1341484 :             if ((VAR_P (stripped_lhs) || TREE_CODE (stripped_lhs) == PARM_DECL)
   10060      3660285 :                 && !DECL_READ_P (stripped_lhs)
   10061       934554 :                 && (VAR_P (stripped_lhs) ? warn_unused_but_set_variable
   10062              :                                          : warn_unused_but_set_parameter) > 2
   10063         7007 :                 && !CLASS_TYPE_P (TREE_TYPE (lhs))
   10064      4366443 :                 && !CLASS_TYPE_P (TREE_TYPE (rhs)))
   10065              :               {
   10066         7007 :                 mark_exp_read (rhs);
   10067         7007 :                 if (!DECL_READ_P (stripped_lhs))
   10068      4359436 :                   clear_decl_read = true;
   10069              :               }
   10070      4359436 :             newrhs = cp_build_binary_op (loc, modifycode, lhs, rhs, complain);
   10071      4359436 :             if (clear_decl_read)
   10072         7007 :               DECL_READ_P (stripped_lhs) = 0;
   10073      4359436 :             if (newrhs == error_mark_node)
   10074              :               {
   10075          120 :                 if (complain & tf_error)
   10076           24 :                   inform (loc, "  in evaluation of %<%Q(%#T, %#T)%>",
   10077           24 :                           modifycode, TREE_TYPE (lhs), TREE_TYPE (rhs));
   10078          120 :                 return error_mark_node;
   10079              :               }
   10080      4359436 :           }
   10081              : 
   10082      4359316 :           if (init)
   10083       250882 :             newrhs = build2 (COMPOUND_EXPR, TREE_TYPE (newrhs), init, newrhs);
   10084              : 
   10085              :           /* Now it looks like a plain assignment.  */
   10086      4359316 :           modifycode = NOP_EXPR;
   10087      4359316 :           if (c_dialect_objc ())
   10088              :             {
   10089            0 :               result = objc_maybe_build_modify_expr (lhs, newrhs);
   10090            0 :               if (result)
   10091            0 :                 goto ret;
   10092              :             }
   10093              :         }
   10094     28695563 :       gcc_assert (!TYPE_REF_P (lhstype));
   10095     28695563 :       gcc_assert (!TYPE_REF_P (TREE_TYPE (newrhs)));
   10096              :     }
   10097              : 
   10098              :   /* The left-hand side must be an lvalue.  */
   10099     32752468 :   if (!lvalue_or_else (lhs, lv_assign, complain))
   10100          454 :     return error_mark_node;
   10101              : 
   10102              :   /* Warn about modifying something that is `const'.  Don't warn if
   10103              :      this is initialization.  */
   10104     32752014 :   if (modifycode != INIT_EXPR
   10105     32752014 :       && (TREE_READONLY (lhs) || CP_TYPE_CONST_P (lhstype)
   10106              :           /* Functions are not modifiable, even though they are
   10107              :              lvalues.  */
   10108     28659381 :           || FUNC_OR_METHOD_TYPE_P (TREE_TYPE (lhs))
   10109              :           /* If it's an aggregate and any field is const, then it is
   10110              :              effectively const.  */
   10111     28659333 :           || (CLASS_TYPE_P (lhstype)
   10112            0 :               && C_TYPE_FIELDS_READONLY (lhstype))))
   10113              :     {
   10114        35776 :       if (complain & tf_error)
   10115           85 :         cxx_readonly_error (loc, lhs, lv_assign);
   10116        35776 :       return error_mark_node;
   10117              :     }
   10118              : 
   10119              :   /* If storing into a structure or union member, it may have been given a
   10120              :      lowered bitfield type.  We need to convert to the declared type first,
   10121              :      so retrieve it now.  */
   10122              : 
   10123     32716238 :   olhstype = unlowered_expr_type (lhs);
   10124              : 
   10125              :   /* Convert new value to destination type.  */
   10126              : 
   10127     32716238 :   if (TREE_CODE (lhstype) == ARRAY_TYPE)
   10128              :     {
   10129          198 :       int from_array;
   10130              : 
   10131          198 :       if (BRACE_ENCLOSED_INITIALIZER_P (newrhs))
   10132              :         {
   10133           12 :           if (modifycode != INIT_EXPR)
   10134              :             {
   10135           12 :               if (complain & tf_error)
   10136           12 :                 error_at (loc,
   10137              :                           "assigning to an array from an initializer list");
   10138           12 :               return error_mark_node;
   10139              :             }
   10140            0 :           if (check_array_initializer (lhs, lhstype, newrhs))
   10141            0 :             return error_mark_node;
   10142            0 :           newrhs = digest_init (lhstype, newrhs, complain);
   10143            0 :           if (newrhs == error_mark_node)
   10144              :             return error_mark_node;
   10145              :         }
   10146              : 
   10147              :       /* C++11 8.5/17: "If the destination type is an array of characters,
   10148              :          an array of char16_t, an array of char32_t, or an array of wchar_t,
   10149              :          and the initializer is a string literal...".  */
   10150          186 :       else if ((TREE_CODE (tree_strip_any_location_wrapper (newrhs))
   10151              :                 == STRING_CST)
   10152           43 :                && char_type_p (TREE_TYPE (TYPE_MAIN_VARIANT (lhstype)))
   10153          229 :                && modifycode == INIT_EXPR)
   10154              :         {
   10155           28 :           newrhs = digest_init (lhstype, newrhs, complain);
   10156           28 :           if (newrhs == error_mark_node)
   10157              :             return error_mark_node;
   10158              :         }
   10159              : 
   10160          158 :       else if (!same_or_base_type_p (TYPE_MAIN_VARIANT (lhstype),
   10161              :                                      TYPE_MAIN_VARIANT (TREE_TYPE (newrhs))))
   10162              :         {
   10163           22 :           if (complain & tf_error)
   10164           12 :             error_at (loc, "incompatible types in assignment of %qT to %qT",
   10165           12 :                       TREE_TYPE (rhs), lhstype);
   10166           22 :           return error_mark_node;
   10167              :         }
   10168              : 
   10169              :       /* Allow array assignment in compiler-generated code.  */
   10170          136 :       else if (DECL_P (lhs) && DECL_ARTIFICIAL (lhs))
   10171              :         /* OK, used by coroutines (co-await-initlist1.C).  */;
   10172          130 :       else if (!current_function_decl
   10173          130 :                || !DECL_DEFAULTED_FN (current_function_decl))
   10174              :         {
   10175              :           /* This routine is used for both initialization and assignment.
   10176              :              Make sure the diagnostic message differentiates the context.  */
   10177           80 :           if (complain & tf_error)
   10178              :             {
   10179           30 :               if (modifycode == INIT_EXPR)
   10180            9 :                 error_at (loc, "array used as initializer");
   10181              :               else
   10182           21 :                 error_at (loc, "invalid array assignment");
   10183              :             }
   10184           80 :           return error_mark_node;
   10185              :         }
   10186              : 
   10187          131 :       from_array = TREE_CODE (TREE_TYPE (newrhs)) == ARRAY_TYPE
   10188           84 :                    ? 1 + (modifycode != INIT_EXPR) : 0;
   10189           84 :       result = build_vec_init (lhs, NULL_TREE, newrhs,
   10190              :                                /*explicit_value_init_p=*/false,
   10191              :                                from_array, complain);
   10192           84 :       goto ret;
   10193              :     }
   10194              : 
   10195     32716040 :   if (modifycode == INIT_EXPR)
   10196              :     /* Calls with INIT_EXPR are all direct-initialization, so don't set
   10197              :        LOOKUP_ONLYCONVERTING.  */
   10198      4056846 :     newrhs = convert_for_initialization (lhs, olhstype, newrhs, LOOKUP_NORMAL,
   10199              :                                          ICR_INIT, NULL_TREE, 0,
   10200              :                                          complain | tf_no_cleanup);
   10201              :   else
   10202     28659194 :     newrhs = convert_for_assignment (olhstype, newrhs, ICR_ASSIGN,
   10203              :                                      NULL_TREE, 0, complain, LOOKUP_IMPLICIT);
   10204              : 
   10205     32716040 :   if (!same_type_p (lhstype, olhstype))
   10206       375823 :     newrhs = cp_convert_and_check (lhstype, newrhs, complain);
   10207              : 
   10208     32716040 :   if (modifycode != INIT_EXPR)
   10209              :     {
   10210     28659194 :       if (TREE_CODE (newrhs) == CALL_EXPR
   10211     28659194 :           && TYPE_NEEDS_CONSTRUCTING (lhstype))
   10212            0 :         newrhs = build_cplus_new (lhstype, newrhs, complain);
   10213              : 
   10214              :       /* Can't initialize directly from a TARGET_EXPR, since that would
   10215              :          cause the lhs to be constructed twice, and possibly result in
   10216              :          accidental self-initialization.  So we force the TARGET_EXPR to be
   10217              :          expanded without a target.  */
   10218     28659194 :       if (TREE_CODE (newrhs) == TARGET_EXPR)
   10219           87 :         newrhs = build2 (COMPOUND_EXPR, TREE_TYPE (newrhs), newrhs,
   10220           87 :                          TARGET_EXPR_SLOT (newrhs));
   10221              :     }
   10222              : 
   10223     32716040 :   if (newrhs == error_mark_node)
   10224              :     return error_mark_node;
   10225              : 
   10226     32715399 :   if (c_dialect_objc () && flag_objc_gc)
   10227              :     {
   10228            0 :       result = objc_generate_write_barrier (lhs, modifycode, newrhs);
   10229              : 
   10230            0 :       if (result)
   10231            0 :         goto ret;
   10232              :     }
   10233              : 
   10234     36772196 :   result = build2_loc (loc, modifycode == NOP_EXPR ? MODIFY_EXPR : INIT_EXPR,
   10235              :                        lhstype, lhs, newrhs);
   10236     32715399 :   if (modifycode == INIT_EXPR)
   10237      4056797 :     set_target_expr_eliding (newrhs);
   10238              : 
   10239     32715399 :   TREE_SIDE_EFFECTS (result) = 1;
   10240     32715399 :   if (!plain_assign)
   10241      8416083 :     suppress_warning (result, OPT_Wparentheses);
   10242              : 
   10243     24299316 :  ret:
   10244     36113724 :   if (preeval)
   10245           39 :     result = build2 (COMPOUND_EXPR, TREE_TYPE (result), preeval, result);
   10246              :   return result;
   10247              : }
   10248              : 
   10249              : cp_expr
   10250     68080518 : build_x_modify_expr (location_t loc, tree lhs, enum tree_code modifycode,
   10251              :                      tree rhs, tree lookups, tsubst_flags_t complain)
   10252              : {
   10253     68080518 :   tree orig_lhs = lhs;
   10254     68080518 :   tree orig_rhs = rhs;
   10255     68080518 :   tree overload = NULL_TREE;
   10256              : 
   10257     68080518 :   if (lhs == error_mark_node || rhs == error_mark_node)
   10258         2151 :     return cp_expr (error_mark_node, loc);
   10259              : 
   10260     68078367 :   tree op = build_min (modifycode, void_type_node, NULL_TREE, NULL_TREE);
   10261              : 
   10262     68078367 :   if (processing_template_decl)
   10263              :     {
   10264     47857265 :       if (type_dependent_expression_p (lhs)
   10265     47857265 :           || type_dependent_expression_p (rhs))
   10266              :         {
   10267     35827395 :           tree rval = build_min_nt_loc (loc, MODOP_EXPR, lhs, op, rhs);
   10268     35827395 :           if (modifycode != NOP_EXPR)
   10269      6065869 :             TREE_TYPE (rval)
   10270     12131738 :               = build_dependent_operator_type (lookups, modifycode, true);
   10271     35827395 :           return rval;
   10272              :         }
   10273              :     }
   10274              : 
   10275     32250972 :   tree rval;
   10276     32250972 :   if (modifycode == NOP_EXPR)
   10277     25082321 :     rval = cp_build_modify_expr (loc, lhs, modifycode, rhs, complain);
   10278              :   else
   10279      7168651 :     rval = build_new_op (loc, MODIFY_EXPR, LOOKUP_NORMAL,
   10280              :                          lhs, rhs, op, lookups, &overload, complain);
   10281     32250972 :   if (rval == error_mark_node)
   10282         4409 :     return error_mark_node;
   10283     32246563 :   if (processing_template_decl)
   10284              :     {
   10285     12029849 :       if (overload != NULL_TREE)
   10286      1914423 :         return (build_min_non_dep_op_overload
   10287      1914423 :                 (MODIFY_EXPR, rval, overload, orig_lhs, orig_rhs));
   10288              : 
   10289     10115426 :       return (build_min_non_dep
   10290     10115426 :               (MODOP_EXPR, rval, orig_lhs, op, orig_rhs));
   10291              :     }
   10292     20216714 :   return rval;
   10293              : }
   10294              : 
   10295              : /* Helper function for get_delta_difference which assumes FROM is a base
   10296              :    class of TO.  Returns a delta for the conversion of pointer-to-member
   10297              :    of FROM to pointer-to-member of TO.  If the conversion is invalid and
   10298              :    tf_error is not set in COMPLAIN returns error_mark_node, otherwise
   10299              :    returns zero.  If FROM is not a base class of TO, returns NULL_TREE.
   10300              :    If C_CAST_P is true, this conversion is taking place as part of a
   10301              :    C-style cast.  */
   10302              : 
   10303              : static tree
   10304        28185 : get_delta_difference_1 (tree from, tree to, bool c_cast_p,
   10305              :                         tsubst_flags_t complain)
   10306              : {
   10307        28185 :   tree binfo;
   10308        28185 :   base_kind kind;
   10309              : 
   10310        56120 :   binfo = lookup_base (to, from, c_cast_p ? ba_unique : ba_check,
   10311              :                        &kind, complain);
   10312              : 
   10313        28185 :   if (binfo == error_mark_node)
   10314              :     {
   10315           51 :       if (!(complain & tf_error))
   10316              :         return error_mark_node;
   10317              : 
   10318           51 :       inform (input_location, "   in pointer to member function conversion");
   10319           51 :       return size_zero_node;
   10320              :     }
   10321        28134 :   else if (binfo)
   10322              :     {
   10323        27986 :       if (kind != bk_via_virtual)
   10324        27893 :         return BINFO_OFFSET (binfo);
   10325              :       else
   10326              :         /* FROM is a virtual base class of TO.  Issue an error or warning
   10327              :            depending on whether or not this is a reinterpret cast.  */
   10328              :         {
   10329           93 :           if (!(complain & tf_error))
   10330              :             return error_mark_node;
   10331              : 
   10332           78 :           error ("pointer to member conversion via virtual base %qT",
   10333           78 :                  BINFO_TYPE (binfo_from_vbase (binfo)));
   10334              : 
   10335           78 :           return size_zero_node;
   10336              :         }
   10337              :       }
   10338              :   else
   10339              :     return NULL_TREE;
   10340              : }
   10341              : 
   10342              : /* Get difference in deltas for different pointer to member function
   10343              :    types.  If the conversion is invalid and tf_error is not set in
   10344              :    COMPLAIN, returns error_mark_node, otherwise returns an integer
   10345              :    constant of type PTRDIFF_TYPE_NODE and its value is zero if the
   10346              :    conversion is invalid.  If ALLOW_INVERSE_P is true, then allow reverse
   10347              :    conversions as well.  If C_CAST_P is true this conversion is taking
   10348              :    place as part of a C-style cast.
   10349              : 
   10350              :    Note that the naming of FROM and TO is kind of backwards; the return
   10351              :    value is what we add to a TO in order to get a FROM.  They are named
   10352              :    this way because we call this function to find out how to convert from
   10353              :    a pointer to member of FROM to a pointer to member of TO.  */
   10354              : 
   10355              : static tree
   10356        87807 : get_delta_difference (tree from, tree to,
   10357              :                       bool allow_inverse_p,
   10358              :                       bool c_cast_p, tsubst_flags_t complain)
   10359              : {
   10360        87807 :   auto_diagnostic_group d;
   10361        87807 :   tree result;
   10362              : 
   10363        87807 :   if (same_type_ignoring_top_level_qualifiers_p (from, to))
   10364              :     /* Pointer to member of incomplete class is permitted*/
   10365        59770 :     result = size_zero_node;
   10366              :   else
   10367        28037 :     result = get_delta_difference_1 (from, to, c_cast_p, complain);
   10368              : 
   10369        87807 :   if (result == error_mark_node)
   10370              :     return error_mark_node;
   10371              : 
   10372        87792 :   if (!result)
   10373              :   {
   10374          148 :     if (!allow_inverse_p)
   10375              :       {
   10376            0 :         if (!(complain & tf_error))
   10377              :           return error_mark_node;
   10378              : 
   10379            0 :         error_not_base_type (from, to);
   10380            0 :         inform (input_location, "   in pointer to member conversion");
   10381            0 :         result = size_zero_node;
   10382              :       }
   10383              :     else
   10384              :       {
   10385          148 :         result = get_delta_difference_1 (to, from, c_cast_p, complain);
   10386              : 
   10387          148 :         if (result == error_mark_node)
   10388              :           return error_mark_node;
   10389              : 
   10390          148 :         if (result)
   10391          148 :           result = size_diffop_loc (input_location,
   10392              :                                     size_zero_node, result);
   10393              :         else
   10394              :           {
   10395            0 :             if (!(complain & tf_error))
   10396              :               return error_mark_node;
   10397              : 
   10398            0 :             error_not_base_type (from, to);
   10399            0 :             inform (input_location, "   in pointer to member conversion");
   10400            0 :             result = size_zero_node;
   10401              :           }
   10402              :       }
   10403              :   }
   10404              : 
   10405        87792 :   return convert_to_integer (ptrdiff_type_node, result);
   10406        87807 : }
   10407              : 
   10408              : /* Return a constructor for the pointer-to-member-function TYPE using
   10409              :    the other components as specified.  */
   10410              : 
   10411              : tree
   10412        60039 : build_ptrmemfunc1 (tree type, tree delta, tree pfn)
   10413              : {
   10414        60039 :   tree u = NULL_TREE;
   10415        60039 :   tree delta_field;
   10416        60039 :   tree pfn_field;
   10417        60039 :   vec<constructor_elt, va_gc> *v;
   10418              : 
   10419              :   /* Pull the FIELD_DECLs out of the type.  */
   10420        60039 :   pfn_field = TYPE_FIELDS (type);
   10421        60039 :   delta_field = DECL_CHAIN (pfn_field);
   10422              : 
   10423              :   /* Make sure DELTA has the type we want.  */
   10424        60039 :   delta = convert_and_check (input_location, delta_type_node, delta);
   10425              : 
   10426              :   /* Convert to the correct target type if necessary.  */
   10427        60039 :   pfn = fold_convert (TREE_TYPE (pfn_field), pfn);
   10428              : 
   10429              :   /* Finish creating the initializer.  */
   10430        60039 :   vec_alloc (v, 2);
   10431        60039 :   CONSTRUCTOR_APPEND_ELT(v, pfn_field, pfn);
   10432        60039 :   CONSTRUCTOR_APPEND_ELT(v, delta_field, delta);
   10433        60039 :   u = build_constructor (type, v);
   10434        60039 :   TREE_CONSTANT (u) = TREE_CONSTANT (pfn) & TREE_CONSTANT (delta);
   10435        60039 :   TREE_STATIC (u) = (TREE_CONSTANT (u)
   10436        59925 :                      && (initializer_constant_valid_p (pfn, TREE_TYPE (pfn))
   10437              :                          != NULL_TREE)
   10438       119964 :                      && (initializer_constant_valid_p (delta, TREE_TYPE (delta))
   10439              :                          != NULL_TREE));
   10440        60039 :   return u;
   10441              : }
   10442              : 
   10443              : /* Build a constructor for a pointer to member function.  It can be
   10444              :    used to initialize global variables, local variable, or used
   10445              :    as a value in expressions.  TYPE is the POINTER to METHOD_TYPE we
   10446              :    want to be.
   10447              : 
   10448              :    If FORCE is nonzero, then force this conversion, even if
   10449              :    we would rather not do it.  Usually set when using an explicit
   10450              :    cast.  A C-style cast is being processed iff C_CAST_P is true.
   10451              : 
   10452              :    Return error_mark_node, if something goes wrong.  */
   10453              : 
   10454              : tree
   10455        29456 : build_ptrmemfunc (tree type, tree pfn, int force, bool c_cast_p,
   10456              :                   tsubst_flags_t complain)
   10457              : {
   10458        29456 :   tree fn;
   10459        29456 :   tree pfn_type;
   10460        29456 :   tree to_type;
   10461              : 
   10462        29456 :   if (error_operand_p (pfn))
   10463            0 :     return error_mark_node;
   10464              : 
   10465        29456 :   pfn_type = TREE_TYPE (pfn);
   10466        29456 :   to_type = build_ptrmemfunc_type (type);
   10467              : 
   10468              :   /* Handle multiple conversions of pointer to member functions.  */
   10469        29456 :   if (TYPE_PTRMEMFUNC_P (pfn_type))
   10470              :     {
   10471        27740 :       tree delta = NULL_TREE;
   10472        27740 :       tree npfn = NULL_TREE;
   10473        27740 :       tree n;
   10474              : 
   10475        27740 :       if (!force
   10476        27740 :           && !can_convert_arg (to_type, TREE_TYPE (pfn), pfn,
   10477              :                                LOOKUP_NORMAL, complain))
   10478              :         {
   10479            0 :           if (complain & tf_error)
   10480            0 :             error ("invalid conversion to type %qT from type %qT",
   10481              :                    to_type, pfn_type);
   10482              :           else
   10483            0 :             return error_mark_node;
   10484              :         }
   10485              : 
   10486        27740 :       n = get_delta_difference (TYPE_PTRMEMFUNC_OBJECT_TYPE (pfn_type),
   10487        27740 :                                 TYPE_PTRMEMFUNC_OBJECT_TYPE (to_type),
   10488              :                                 force,
   10489              :                                 c_cast_p, complain);
   10490        27740 :       if (n == error_mark_node)
   10491              :         return error_mark_node;
   10492              : 
   10493        27731 :       STRIP_ANY_LOCATION_WRAPPER (pfn);
   10494              : 
   10495              :       /* We don't have to do any conversion to convert a
   10496              :          pointer-to-member to its own type.  But, we don't want to
   10497              :          just return a PTRMEM_CST if there's an explicit cast; that
   10498              :          cast should make the expression an invalid template argument.  */
   10499        27731 :       if (TREE_CODE (pfn) != PTRMEM_CST
   10500        27731 :           && same_type_p (to_type, pfn_type))
   10501              :         return pfn;
   10502              : 
   10503        27731 :       if (TREE_SIDE_EFFECTS (pfn))
   10504           14 :         pfn = save_expr (pfn);
   10505              : 
   10506              :       /* Obtain the function pointer and the current DELTA.  */
   10507        27731 :       if (TREE_CODE (pfn) == PTRMEM_CST)
   10508        27637 :         expand_ptrmemfunc_cst (pfn, &delta, &npfn);
   10509              :       else
   10510              :         {
   10511           94 :           npfn = build_ptrmemfunc_access_expr (pfn, pfn_identifier);
   10512           94 :           delta = build_ptrmemfunc_access_expr (pfn, delta_identifier);
   10513              :         }
   10514              : 
   10515              :       /* Just adjust the DELTA field.  */
   10516        27731 :       gcc_assert  (same_type_ignoring_top_level_qualifiers_p
   10517              :                    (TREE_TYPE (delta), ptrdiff_type_node));
   10518        27731 :       if (!integer_zerop (n))
   10519              :         {
   10520           50 :           if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_delta)
   10521              :             n = cp_build_binary_op (input_location,
   10522              :                                     LSHIFT_EXPR, n, integer_one_node,
   10523              :                                     complain);
   10524           50 :           delta = cp_build_binary_op (input_location,
   10525              :                                       PLUS_EXPR, delta, n, complain);
   10526              :         }
   10527        27731 :       return build_ptrmemfunc1 (to_type, delta, npfn);
   10528              :     }
   10529              : 
   10530              :   /* Handle null pointer to member function conversions.  */
   10531         1716 :   if (null_ptr_cst_p (pfn))
   10532              :     {
   10533          638 :       pfn = cp_build_c_cast (input_location,
   10534          638 :                              TYPE_PTRMEMFUNC_FN_TYPE_RAW (to_type),
   10535              :                              pfn, complain);
   10536          638 :       return build_ptrmemfunc1 (to_type,
   10537              :                                 integer_zero_node,
   10538          638 :                                 pfn);
   10539              :     }
   10540              : 
   10541         1078 :   if (type_unknown_p (pfn))
   10542            0 :     return instantiate_type (type, pfn, complain);
   10543              : 
   10544         1078 :   fn = TREE_OPERAND (pfn, 0);
   10545         1078 :   gcc_assert (TREE_CODE (fn) == FUNCTION_DECL
   10546              :               /* In a template, we will have preserved the
   10547              :                  OFFSET_REF.  */
   10548              :               || (processing_template_decl && TREE_CODE (fn) == OFFSET_REF));
   10549         1078 :   return make_ptrmem_cst (to_type, fn);
   10550              : }
   10551              : 
   10552              : /* Return the DELTA, IDX, PFN, and DELTA2 values for the PTRMEM_CST
   10553              :    given by CST.
   10554              : 
   10555              :    ??? There is no consistency as to the types returned for the above
   10556              :    values.  Some code acts as if it were a sizetype and some as if it were
   10557              :    integer_type_node.  */
   10558              : 
   10559              : void
   10560        59685 : expand_ptrmemfunc_cst (tree cst, tree *delta, tree *pfn)
   10561              : {
   10562        59685 :   tree type = TREE_TYPE (cst);
   10563        59685 :   tree fn = PTRMEM_CST_MEMBER (cst);
   10564        59685 :   tree ptr_class, fn_class;
   10565              : 
   10566        59685 :   gcc_assert (TREE_CODE (fn) == FUNCTION_DECL);
   10567              : 
   10568              :   /* The class that the function belongs to.  */
   10569        59685 :   fn_class = DECL_CONTEXT (fn);
   10570              : 
   10571              :   /* The class that we're creating a pointer to member of.  */
   10572        59685 :   ptr_class = TYPE_PTRMEMFUNC_OBJECT_TYPE (type);
   10573              : 
   10574              :   /* First, calculate the adjustment to the function's class.  */
   10575        59685 :   *delta = get_delta_difference (fn_class, ptr_class, /*force=*/0,
   10576              :                                  /*c_cast_p=*/0, tf_warning_or_error);
   10577              : 
   10578        59685 :   if (!DECL_VIRTUAL_P (fn))
   10579              :     {
   10580        58574 :       tree t = build_addr_func (fn, tf_warning_or_error);
   10581        58574 :       if (TREE_CODE (t) == ADDR_EXPR)
   10582        58574 :         SET_EXPR_LOCATION (t, PTRMEM_CST_LOCATION (cst));
   10583        58574 :       *pfn = convert (TYPE_PTRMEMFUNC_FN_TYPE (type), t);
   10584              :     }
   10585              :   else
   10586              :     {
   10587              :       /* If we're dealing with a virtual function, we have to adjust 'this'
   10588              :          again, to point to the base which provides the vtable entry for
   10589              :          fn; the call will do the opposite adjustment.  */
   10590         1111 :       tree orig_class = DECL_CONTEXT (fn);
   10591         1111 :       tree binfo = binfo_or_else (orig_class, fn_class);
   10592         1111 :       *delta = fold_build2 (PLUS_EXPR, TREE_TYPE (*delta),
   10593              :                             *delta, BINFO_OFFSET (binfo));
   10594              : 
   10595              :       /* We set PFN to the vtable offset at which the function can be
   10596              :          found, plus one (unless ptrmemfunc_vbit_in_delta, in which
   10597              :          case delta is shifted left, and then incremented).  */
   10598         1111 :       *pfn = DECL_VINDEX (fn);
   10599         1111 :       *pfn = fold_build2 (MULT_EXPR, integer_type_node, *pfn,
   10600              :                           TYPE_SIZE_UNIT (vtable_entry_type));
   10601              : 
   10602         1111 :       switch (TARGET_PTRMEMFUNC_VBIT_LOCATION)
   10603              :         {
   10604         1111 :         case ptrmemfunc_vbit_in_pfn:
   10605         1111 :           *pfn = fold_build2 (PLUS_EXPR, integer_type_node, *pfn,
   10606              :                               integer_one_node);
   10607         1111 :           break;
   10608              : 
   10609              :         case ptrmemfunc_vbit_in_delta:
   10610              :           *delta = fold_build2 (LSHIFT_EXPR, TREE_TYPE (*delta),
   10611              :                                 *delta, integer_one_node);
   10612              :           *delta = fold_build2 (PLUS_EXPR, TREE_TYPE (*delta),
   10613              :                                 *delta, integer_one_node);
   10614              :           break;
   10615              : 
   10616              :         default:
   10617              :           gcc_unreachable ();
   10618              :         }
   10619              : 
   10620         1111 :       *pfn = fold_convert (TYPE_PTRMEMFUNC_FN_TYPE (type), *pfn);
   10621              :     }
   10622        59685 : }
   10623              : 
   10624              : /* Return an expression for PFN from the pointer-to-member function
   10625              :    given by T.  */
   10626              : 
   10627              : static tree
   10628        84339 : pfn_from_ptrmemfunc (tree t)
   10629              : {
   10630        84339 :   if (TREE_CODE (t) == PTRMEM_CST)
   10631              :     {
   10632          189 :       tree delta;
   10633          189 :       tree pfn;
   10634              : 
   10635          189 :       expand_ptrmemfunc_cst (t, &delta, &pfn);
   10636          189 :       if (pfn)
   10637          189 :         return pfn;
   10638              :     }
   10639              : 
   10640        84150 :   return build_ptrmemfunc_access_expr (t, pfn_identifier);
   10641              : }
   10642              : 
   10643              : /* Return an expression for DELTA from the pointer-to-member function
   10644              :    given by T.  */
   10645              : 
   10646              : static tree
   10647        84339 : delta_from_ptrmemfunc (tree t)
   10648              : {
   10649        84339 :   if (TREE_CODE (t) == PTRMEM_CST)
   10650              :     {
   10651          189 :       tree delta;
   10652          189 :       tree pfn;
   10653              : 
   10654          189 :       expand_ptrmemfunc_cst (t, &delta, &pfn);
   10655          189 :       if (delta)
   10656          189 :         return delta;
   10657              :     }
   10658              : 
   10659        84150 :   return build_ptrmemfunc_access_expr (t, delta_identifier);
   10660              : }
   10661              : 
   10662              : /* Convert value RHS to type TYPE as preparation for an assignment to
   10663              :    an lvalue of type TYPE.  ERRTYPE indicates what kind of error the
   10664              :    implicit conversion is.  If FNDECL is non-NULL, we are doing the
   10665              :    conversion in order to pass the PARMNUMth argument of FNDECL.
   10666              :    If FNDECL is NULL, we are doing the conversion in function pointer
   10667              :    argument passing, conversion in initialization, etc. */
   10668              : 
   10669              : static tree
   10670    174268549 : convert_for_assignment (tree type, tree rhs,
   10671              :                         impl_conv_rhs errtype, tree fndecl, int parmnum,
   10672              :                         tsubst_flags_t complain, int flags)
   10673              : {
   10674    174268549 :   tree rhstype;
   10675    174268549 :   enum tree_code coder;
   10676              : 
   10677    174268549 :   location_t rhs_loc = cp_expr_loc_or_input_loc (rhs);
   10678    174268549 :   bool has_loc = EXPR_LOCATION (rhs) != UNKNOWN_LOCATION;
   10679              :   /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue,
   10680              :      but preserve location wrappers.  */
   10681    174268549 :   if (TREE_CODE (rhs) == NON_LVALUE_EXPR
   10682    174268549 :       && !location_wrapper_p (rhs))
   10683         8437 :     rhs = TREE_OPERAND (rhs, 0);
   10684              : 
   10685              :   /* Handle [dcl.init.list] direct-list-initialization from
   10686              :      single element of enumeration with a fixed underlying type.  */
   10687    174268549 :   if (is_direct_enum_init (type, rhs))
   10688              :     {
   10689           20 :       tree elt = CONSTRUCTOR_ELT (rhs, 0)->value;
   10690           20 :       if (check_narrowing (ENUM_UNDERLYING_TYPE (type), elt, complain))
   10691              :         {
   10692           11 :           warning_sentinel w (warn_useless_cast);
   10693           11 :           warning_sentinel w2 (warn_ignored_qualifiers);
   10694           11 :           rhs = cp_build_c_cast (rhs_loc, type, elt, complain);
   10695           11 :         }
   10696              :       else
   10697            9 :         rhs = error_mark_node;
   10698              :     }
   10699              : 
   10700    174268549 :   rhstype = TREE_TYPE (rhs);
   10701    174268549 :   coder = TREE_CODE (rhstype);
   10702              : 
   10703      1353731 :   if (VECTOR_TYPE_P (type) && coder == VECTOR_TYPE
   10704    175622174 :       && vector_types_convertible_p (type, rhstype, true))
   10705              :     {
   10706      1353616 :       rhs = mark_rvalue_use (rhs);
   10707      1353616 :       return convert (type, rhs);
   10708              :     }
   10709              : 
   10710    172914933 :   if (rhs == error_mark_node || rhstype == error_mark_node)
   10711              :     return error_mark_node;
   10712    172914924 :   if (TREE_CODE (rhs) == TREE_LIST && TREE_VALUE (rhs) == error_mark_node)
   10713              :     return error_mark_node;
   10714              : 
   10715              :   /* The RHS of an assignment cannot have void type.  */
   10716    172914924 :   if (coder == VOID_TYPE)
   10717              :     {
   10718           48 :       if (complain & tf_error)
   10719           30 :         error_at (rhs_loc, "void value not ignored as it ought to be");
   10720           48 :       return error_mark_node;
   10721              :     }
   10722              : 
   10723    172914876 :   if (c_dialect_objc ())
   10724              :     {
   10725            0 :       int parmno;
   10726            0 :       tree selector;
   10727            0 :       tree rname = fndecl;
   10728              : 
   10729            0 :       switch (errtype)
   10730              :         {
   10731              :           case ICR_ASSIGN:
   10732              :             parmno = -1;
   10733              :             break;
   10734            0 :           case ICR_INIT:
   10735            0 :             parmno = -2;
   10736            0 :             break;
   10737            0 :           default:
   10738            0 :             selector = objc_message_selector ();
   10739            0 :             parmno = parmnum;
   10740            0 :             if (selector && parmno > 1)
   10741              :               {
   10742            0 :                 rname = selector;
   10743            0 :                 parmno -= 1;
   10744              :               }
   10745              :         }
   10746              : 
   10747            0 :       if (objc_compare_types (type, rhstype, parmno, rname))
   10748              :         {
   10749            0 :           rhs = mark_rvalue_use (rhs);
   10750            0 :           return convert (type, rhs);
   10751              :         }
   10752              :     }
   10753              : 
   10754              :   /* [expr.ass]
   10755              : 
   10756              :      The expression is implicitly converted (clause _conv_) to the
   10757              :      cv-unqualified type of the left operand.
   10758              : 
   10759              :      We allow bad conversions here because by the time we get to this point
   10760              :      we are committed to doing the conversion.  If we end up doing a bad
   10761              :      conversion, convert_like will complain.  */
   10762    172914876 :   if (!can_convert_arg_bad (type, rhstype, rhs, flags, complain))
   10763              :     {
   10764              :       /* When -Wno-pmf-conversions is use, we just silently allow
   10765              :          conversions from pointers-to-members to plain pointers.  If
   10766              :          the conversion doesn't work, cp_convert will complain.  */
   10767         1539 :       if (!warn_pmf2ptr
   10768            9 :           && TYPE_PTR_P (type)
   10769         1548 :           && TYPE_PTRMEMFUNC_P (rhstype))
   10770            9 :         rhs = cp_convert (strip_top_quals (type), rhs, complain);
   10771              :       else
   10772              :         {
   10773         1530 :           if (complain & tf_error)
   10774              :             {
   10775         1280 :               auto_diagnostic_group d;
   10776              : 
   10777              :               /* If the right-hand side has unknown type, then it is an
   10778              :                  overloaded function.  Call instantiate_type to get error
   10779              :                  messages.  */
   10780         1280 :               if (rhstype == unknown_type_node)
   10781              :                 {
   10782          197 :                   tree r = instantiate_type (type, rhs, tf_warning_or_error);
   10783              :                   /* -fpermissive might allow this; recurse.  */
   10784          197 :                   if (!seen_error ())
   10785           15 :                     return convert_for_assignment (type, r, errtype, fndecl,
   10786              :                                                    parmnum, complain, flags);
   10787              :                 }
   10788         1083 :               else if (fndecl)
   10789           92 :                 complain_about_bad_argument (rhs_loc,
   10790              :                                              rhstype, type,
   10791              :                                              fndecl, parmnum);
   10792              :               else
   10793              :                 {
   10794          991 :                   range_label_for_type_mismatch label (rhstype, type);
   10795          991 :                   gcc_rich_location richloc
   10796              :                     (rhs_loc,
   10797              :                      has_loc ? &label : NULL,
   10798          991 :                      has_loc ? highlight_colors::percent_h : NULL);
   10799              : 
   10800          991 :                   switch (errtype)
   10801              :                     {
   10802            0 :                     case ICR_DEFAULT_ARGUMENT:
   10803            0 :                       error_at (&richloc,
   10804              :                                 "cannot convert %qH to %qI in default argument",
   10805              :                                 rhstype, type);
   10806            0 :                       break;
   10807            6 :                     case ICR_ARGPASS:
   10808            6 :                       error_at (&richloc,
   10809              :                                 "cannot convert %qH to %qI in argument passing",
   10810              :                                 rhstype, type);
   10811            6 :                       break;
   10812            0 :                     case ICR_CONVERTING:
   10813            0 :                       error_at (&richloc, "cannot convert %qH to %qI",
   10814              :                                 rhstype, type);
   10815            0 :                       break;
   10816          553 :                     case ICR_INIT:
   10817          553 :                       error_at (&richloc,
   10818              :                                 "cannot convert %qH to %qI in initialization",
   10819              :                                 rhstype, type);
   10820          553 :                       break;
   10821           18 :                     case ICR_RETURN:
   10822           18 :                       error_at (&richloc, "cannot convert %qH to %qI in return",
   10823              :                                 rhstype, type);
   10824           18 :                       break;
   10825          414 :                     case ICR_ASSIGN:
   10826          414 :                       error_at (&richloc,
   10827              :                                 "cannot convert %qH to %qI in assignment",
   10828              :                                 rhstype, type);
   10829          414 :                       break;
   10830            0 :                     default:
   10831            0 :                       gcc_unreachable();
   10832              :                   }
   10833          991 :                 }
   10834              : 
   10835              :               /* See if we can be more helpful.  */
   10836         1265 :               maybe_show_nonconverting_candidate (type, rhstype, rhs, flags);
   10837              : 
   10838         1265 :               if (TYPE_PTR_P (rhstype)
   10839          412 :                   && TYPE_PTR_P (type)
   10840          397 :                   && CLASS_TYPE_P (TREE_TYPE (rhstype))
   10841          279 :                   && CLASS_TYPE_P (TREE_TYPE (type))
   10842         1328 :                   && !COMPLETE_TYPE_P (TREE_TYPE (rhstype)))
   10843            3 :                 inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL
   10844              :                                               (TREE_TYPE (rhstype))),
   10845            3 :                         "class type %qT is incomplete", TREE_TYPE (rhstype));
   10846         1280 :             }
   10847         1515 :           return error_mark_node;
   10848              :         }
   10849              :     }
   10850    172913346 :   if (warn_suggest_attribute_format)
   10851              :     {
   10852         2383 :       const enum tree_code codel = TREE_CODE (type);
   10853         2383 :       if ((codel == POINTER_TYPE || codel == REFERENCE_TYPE)
   10854          596 :           && coder == codel
   10855          508 :           && check_missing_format_attribute (type, rhstype)
   10856         2401 :           && (complain & tf_warning))
   10857           18 :         switch (errtype)
   10858              :           {
   10859            0 :             case ICR_ARGPASS:
   10860            0 :             case ICR_DEFAULT_ARGUMENT:
   10861            0 :               if (fndecl)
   10862            0 :                 warning (OPT_Wsuggest_attribute_format,
   10863              :                          "parameter %qP of %qD might be a candidate "
   10864              :                          "for a format attribute", parmnum, fndecl);
   10865              :               else
   10866            0 :                 warning (OPT_Wsuggest_attribute_format,
   10867              :                          "parameter might be a candidate "
   10868              :                          "for a format attribute");
   10869              :               break;
   10870            0 :             case ICR_CONVERTING:
   10871            0 :               warning (OPT_Wsuggest_attribute_format,
   10872              :                        "target of conversion might be a candidate "
   10873              :                        "for a format attribute");
   10874            0 :               break;
   10875            6 :             case ICR_INIT:
   10876            6 :               warning (OPT_Wsuggest_attribute_format,
   10877              :                        "target of initialization might be a candidate "
   10878              :                        "for a format attribute");
   10879            6 :               break;
   10880            6 :             case ICR_RETURN:
   10881            6 :               warning (OPT_Wsuggest_attribute_format,
   10882              :                        "return type might be a candidate "
   10883              :                        "for a format attribute");
   10884            6 :               break;
   10885            6 :             case ICR_ASSIGN:
   10886            6 :               warning (OPT_Wsuggest_attribute_format,
   10887              :                        "left-hand side of assignment might be a candidate "
   10888              :                        "for a format attribute");
   10889            6 :               break;
   10890            0 :             default:
   10891            0 :               gcc_unreachable();
   10892              :           }
   10893              :     }
   10894              : 
   10895    172913346 :   if (TREE_CODE (type) == BOOLEAN_TYPE)
   10896     35228857 :     maybe_warn_unparenthesized_assignment (rhs, /*nested_p=*/true, complain);
   10897              : 
   10898    172913346 :   if (complain & tf_warning)
   10899    170540138 :     warn_for_address_of_packed_member (type, rhs);
   10900              : 
   10901    172913346 :   return perform_implicit_conversion_flags (strip_top_quals (type), rhs,
   10902    172913346 :                                             complain, flags);
   10903              : }
   10904              : 
   10905              : /* Convert RHS to be of type TYPE.
   10906              :    If EXP is nonzero, it is the target of the initialization.
   10907              :    ERRTYPE indicates what kind of error the implicit conversion is.
   10908              : 
   10909              :    Two major differences between the behavior of
   10910              :    `convert_for_assignment' and `convert_for_initialization'
   10911              :    are that references are bashed in the former, while
   10912              :    copied in the latter, and aggregates are assigned in
   10913              :    the former (operator=) while initialized in the
   10914              :    latter (X(X&)).
   10915              : 
   10916              :    If using constructor make sure no conversion operator exists, if one does
   10917              :    exist, an ambiguity exists.  */
   10918              : 
   10919              : tree
   10920    161026058 : convert_for_initialization (tree exp, tree type, tree rhs, int flags,
   10921              :                             impl_conv_rhs errtype, tree fndecl, int parmnum,
   10922              :                             tsubst_flags_t complain)
   10923              : {
   10924    161026058 :   enum tree_code codel = TREE_CODE (type);
   10925    161026058 :   tree rhstype;
   10926    161026058 :   enum tree_code coder;
   10927              : 
   10928              :   /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
   10929              :      Strip such NOP_EXPRs, since RHS is used in non-lvalue context.  */
   10930    161026058 :   if (TREE_CODE (rhs) == NOP_EXPR
   10931      5649263 :       && TREE_TYPE (rhs) == TREE_TYPE (TREE_OPERAND (rhs, 0))
   10932    161498782 :       && codel != REFERENCE_TYPE)
   10933       472724 :     rhs = TREE_OPERAND (rhs, 0);
   10934              : 
   10935    161026058 :   if (type == error_mark_node
   10936    161026015 :       || rhs == error_mark_node
   10937    322052005 :       || (TREE_CODE (rhs) == TREE_LIST && TREE_VALUE (rhs) == error_mark_node))
   10938              :     return error_mark_node;
   10939              : 
   10940    161025947 :   if (MAYBE_CLASS_TYPE_P (non_reference (type)))
   10941              :     ;
   10942    147468452 :   else if ((TREE_CODE (TREE_TYPE (rhs)) == ARRAY_TYPE
   10943      2024805 :             && TREE_CODE (type) != ARRAY_TYPE
   10944      2024805 :             && (!TYPE_REF_P (type)
   10945          735 :                 || TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE))
   10946    145444379 :            || (TREE_CODE (TREE_TYPE (rhs)) == FUNCTION_TYPE
   10947        24551 :                && !TYPE_REFFN_P (type))
   10948    292889192 :            || TREE_CODE (TREE_TYPE (rhs)) == METHOD_TYPE)
   10949      2047718 :     rhs = decay_conversion (rhs, complain);
   10950              : 
   10951    161025947 :   rhstype = TREE_TYPE (rhs);
   10952    161025947 :   coder = TREE_CODE (rhstype);
   10953              : 
   10954    161025947 :   if (coder == ERROR_MARK)
   10955            9 :     return error_mark_node;
   10956              : 
   10957              :   /* We accept references to incomplete types, so we can
   10958              :      return here before checking if RHS is of complete type.  */
   10959              : 
   10960    161025938 :   if (codel == REFERENCE_TYPE)
   10961              :     {
   10962      5719533 :       auto_diagnostic_group d;
   10963              :       /* This should eventually happen in convert_arguments.  */
   10964      5719533 :       int savew = 0, savee = 0;
   10965              : 
   10966      5719533 :       if (fndecl)
   10967       274403 :         savew = warningcount + werrorcount, savee = errorcount;
   10968      5719533 :       rhs = initialize_reference (type, rhs, flags, complain);
   10969              : 
   10970      5719533 :       if (fndecl
   10971      5719533 :           && (warningcount + werrorcount > savew || errorcount > savee))
   10972           36 :         inform (get_fndecl_argument_location (fndecl, parmnum),
   10973              :                 "in passing argument %P of %qD", parmnum, fndecl);
   10974      5719533 :       return rhs;
   10975      5719533 :     }
   10976              : 
   10977    155306405 :   if (exp != 0)
   10978      4056846 :     exp = require_complete_type (exp, complain);
   10979    155306405 :   if (exp == error_mark_node)
   10980              :     return error_mark_node;
   10981              : 
   10982    155306405 :   type = complete_type (type);
   10983              : 
   10984    155306405 :   if (DIRECT_INIT_EXPR_P (type, rhs))
   10985              :     /* Don't try to do copy-initialization if we already have
   10986              :        direct-initialization.  */
   10987              :     return rhs;
   10988              : 
   10989    155305264 :   if (MAYBE_CLASS_TYPE_P (type))
   10990      9695924 :     return perform_implicit_conversion_flags (type, rhs, complain, flags);
   10991              : 
   10992    145609340 :   return convert_for_assignment (type, rhs, errtype, fndecl, parmnum,
   10993    145609340 :                                  complain, flags);
   10994              : }
   10995              : 
   10996              : /* If RETVAL is the address of, or a reference to, a local variable or
   10997              :    temporary give an appropriate warning and return true.  */
   10998              : 
   10999              : static bool
   11000     41348593 : maybe_warn_about_returning_address_of_local (tree retval, location_t loc)
   11001              : {
   11002     41349434 :   tree valtype = TREE_TYPE (DECL_RESULT (current_function_decl));
   11003     41349434 :   tree whats_returned = fold_for_warn (retval);
   11004     41349434 :   if (!loc)
   11005     41349434 :     loc = cp_expr_loc_or_input_loc (retval);
   11006              : 
   11007     50387411 :   for (;;)
   11008              :     {
   11009     50387411 :       if (TREE_CODE (whats_returned) == COMPOUND_EXPR)
   11010       750286 :         whats_returned = TREE_OPERAND (whats_returned, 1);
   11011     49637125 :       else if (CONVERT_EXPR_P (whats_returned)
   11012     41365834 :                || TREE_CODE (whats_returned) == NON_LVALUE_EXPR)
   11013      8287691 :         whats_returned = TREE_OPERAND (whats_returned, 0);
   11014              :       else
   11015              :         break;
   11016              :     }
   11017              : 
   11018     41349434 :   if (TREE_CODE (whats_returned) == TARGET_EXPR
   11019     41349434 :       && is_std_init_list (TREE_TYPE (whats_returned)))
   11020              :     {
   11021           16 :       tree init = TARGET_EXPR_INITIAL (whats_returned);
   11022           16 :       if (TREE_CODE (init) == CONSTRUCTOR)
   11023              :         /* Pull out the array address.  */
   11024            7 :         whats_returned = CONSTRUCTOR_ELT (init, 0)->value;
   11025            9 :       else if (TREE_CODE (init) == INDIRECT_REF)
   11026              :         /* The source of a trivial copy looks like *(T*)&var.  */
   11027            6 :         whats_returned = TREE_OPERAND (init, 0);
   11028              :       else
   11029              :         return false;
   11030           13 :       STRIP_NOPS (whats_returned);
   11031              :     }
   11032              : 
   11033              :   /* As a special case, we handle a call to std::move or std::forward.  */
   11034     41349431 :   if (TREE_CODE (whats_returned) == CALL_EXPR
   11035     41349431 :       && (is_std_move_p (whats_returned)
   11036      9885377 :           || is_std_forward_p (whats_returned)))
   11037              :     {
   11038          829 :       tree arg = CALL_EXPR_ARG (whats_returned, 0);
   11039          829 :       return maybe_warn_about_returning_address_of_local (arg, loc);
   11040              :     }
   11041              : 
   11042     41348602 :   if (TREE_CODE (whats_returned) != ADDR_EXPR)
   11043              :     return false;
   11044       872113 :   whats_returned = TREE_OPERAND (whats_returned, 0);
   11045              : 
   11046       872113 :   while (TREE_CODE (whats_returned) == COMPONENT_REF
   11047      1701901 :          || TREE_CODE (whats_returned) == ARRAY_REF)
   11048       829788 :     whats_returned = TREE_OPERAND (whats_returned, 0);
   11049              : 
   11050       872113 :   if (TREE_CODE (whats_returned) == AGGR_INIT_EXPR
   11051       872113 :       || TREE_CODE (whats_returned) == TARGET_EXPR)
   11052              :     {
   11053           50 :       if (TYPE_REF_P (valtype))
   11054              :         /* P2748 made this an error in C++26.  */
   11055           72 :         emit_diagnostic ((cxx_dialect >= cxx26
   11056              :                           ? diagnostics::kind::permerror
   11057              :                           : diagnostics::kind::warning),
   11058           41 :                          loc, OPT_Wreturn_local_addr,
   11059              :                          "returning reference to temporary");
   11060            9 :       else if (TYPE_PTR_P (valtype))
   11061            3 :         warning_at (loc, OPT_Wreturn_local_addr,
   11062              :                     "returning pointer to temporary");
   11063            6 :       else if (is_std_init_list (valtype))
   11064            6 :         warning_at (loc, OPT_Winit_list_lifetime,
   11065              :                     "returning temporary %<initializer_list%> does not extend "
   11066              :                     "the lifetime of the underlying array");
   11067           50 :       return true;
   11068              :     }
   11069              : 
   11070       872063 :   STRIP_ANY_LOCATION_WRAPPER (whats_returned);
   11071              : 
   11072       872063 :   if (DECL_P (whats_returned)
   11073       108449 :       && DECL_NAME (whats_returned)
   11074       108449 :       && DECL_FUNCTION_SCOPE_P (whats_returned)
   11075        12043 :       && !is_capture_proxy (whats_returned)
   11076       884085 :       && !(TREE_STATIC (whats_returned)
   11077          146 :            || TREE_PUBLIC (whats_returned)))
   11078              :     {
   11079          106 :       if (DECL_DECOMPOSITION_P (whats_returned)
   11080           39 :           && !DECL_DECOMP_IS_BASE (whats_returned)
   11081          185 :           && DECL_HAS_VALUE_EXPR_P (whats_returned))
   11082              :         {
   11083              :           /* When returning address of a structured binding, if the structured
   11084              :              binding is not a reference, continue normally, if it is a
   11085              :              reference, recurse on the initializer of the structured
   11086              :              binding.  */
   11087           39 :           tree base = DECL_DECOMP_BASE (whats_returned);
   11088           39 :           if (TYPE_REF_P (TREE_TYPE (base)))
   11089              :             {
   11090           15 :               if (tree init = DECL_INITIAL (base))
   11091              :                 return maybe_warn_about_returning_address_of_local (init, loc);
   11092              :               else
   11093              :                 return false;
   11094              :             }
   11095              :         }
   11096          131 :       bool w = false;
   11097          131 :       auto_diagnostic_group d;
   11098          131 :       if (TYPE_REF_P (valtype))
   11099           81 :         w = warning_at (loc, OPT_Wreturn_local_addr,
   11100              :                         "reference to local variable %qD returned",
   11101              :                         whats_returned);
   11102           50 :       else if (is_std_init_list (valtype))
   11103            3 :         w = warning_at (loc, OPT_Winit_list_lifetime,
   11104              :                         "returning local %<initializer_list%> variable %qD "
   11105              :                         "does not extend the lifetime of the underlying array",
   11106              :                         whats_returned);
   11107           47 :       else if (POINTER_TYPE_P (valtype)
   11108           41 :                && TREE_CODE (whats_returned) == LABEL_DECL)
   11109            6 :         w = warning_at (loc, OPT_Wreturn_local_addr,
   11110              :                         "address of label %qD returned",
   11111              :                         whats_returned);
   11112           41 :       else if (POINTER_TYPE_P (valtype))
   11113           35 :         w = warning_at (loc, OPT_Wreturn_local_addr,
   11114              :                         "address of local variable %qD returned",
   11115              :                         whats_returned);
   11116          125 :       if (w)
   11117          103 :         inform (DECL_SOURCE_LOCATION (whats_returned),
   11118              :                 "declared here");
   11119          131 :       return true;
   11120          131 :     }
   11121              : 
   11122              :   return false;
   11123              : }
   11124              : 
   11125              : /* Returns true if DECL is in the std namespace.  */
   11126              : 
   11127              : bool
   11128     81603032 : decl_in_std_namespace_p (tree decl)
   11129              : {
   11130     95155404 :   while (decl)
   11131              :     {
   11132     94755426 :       decl = decl_namespace_context (decl);
   11133     94755426 :       if (DECL_NAMESPACE_STD_P (decl))
   11134              :         return true;
   11135              :       /* Allow inline namespaces inside of std namespace, e.g. with
   11136              :          --enable-symvers=gnu-versioned-namespace std::forward would be
   11137              :          actually std::_8::forward.  */
   11138     45307162 :       if (!DECL_NAMESPACE_INLINE_P (decl))
   11139              :         return false;
   11140     13552372 :       decl = CP_DECL_CONTEXT (decl);
   11141              :     }
   11142              :   return false;
   11143              : }
   11144              : 
   11145              : /* Returns true if FN, a CALL_EXPR, is a call to std::forward.  */
   11146              : 
   11147              : static bool
   11148      9885377 : is_std_forward_p (tree fn)
   11149              : {
   11150              :   /* std::forward only takes one argument.  */
   11151      9885377 :   if (call_expr_nargs (fn) != 1)
   11152              :     return false;
   11153              : 
   11154      4535397 :   tree fndecl = cp_get_callee_fndecl_nofold (fn);
   11155      4535397 :   if (!decl_in_std_namespace_p (fndecl))
   11156              :     return false;
   11157              : 
   11158      1689088 :   tree name = DECL_NAME (fndecl);
   11159      1689088 :   return name && id_equal (name, "forward");
   11160              : }
   11161              : 
   11162              : /* Returns true if FN, a CALL_EXPR, is a call to std::move.  */
   11163              : 
   11164              : static bool
   11165      9892661 : is_std_move_p (tree fn)
   11166              : {
   11167              :   /* std::move only takes one argument.  */
   11168      9892661 :   if (call_expr_nargs (fn) != 1)
   11169              :     return false;
   11170              : 
   11171      4541850 :   tree fndecl = cp_get_callee_fndecl_nofold (fn);
   11172      4541850 :   if (!decl_in_std_namespace_p (fndecl))
   11173              :     return false;
   11174              : 
   11175      1695063 :   tree name = DECL_NAME (fndecl);
   11176      1695063 :   return name && id_equal (name, "move");
   11177              : }
   11178              : 
   11179              : /* Returns true if RETVAL is a good candidate for the NRVO as per
   11180              :    [class.copy.elision].  FUNCTYPE is the type the function is declared
   11181              :    to return.  */
   11182              : 
   11183              : static bool
   11184     53656276 : can_do_nrvo_p (tree retval, tree functype)
   11185              : {
   11186     53656276 :   if (functype == error_mark_node)
   11187              :     return false;
   11188     53656230 :   if (retval)
   11189     52045510 :     STRIP_ANY_LOCATION_WRAPPER (retval);
   11190     53656230 :   tree result = DECL_RESULT (current_function_decl);
   11191     53656230 :   return (retval != NULL_TREE
   11192     52045510 :           && !processing_template_decl
   11193              :           /* Must be a local, automatic variable.  */
   11194     42784637 :           && VAR_P (retval)
   11195      3775990 :           && DECL_CONTEXT (retval) == current_function_decl
   11196      2755476 :           && !TREE_STATIC (retval)
   11197              :           /* And not a lambda or anonymous union proxy.  */
   11198      2752659 :           && !DECL_HAS_VALUE_EXPR_P (retval)
   11199      2752412 :           && (DECL_ALIGN (retval) <= DECL_ALIGN (result))
   11200              :           /* The cv-unqualified type of the returned value must be the
   11201              :              same as the cv-unqualified return type of the
   11202              :              function.  */
   11203      2752291 :           && same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (retval)),
   11204              :                           TYPE_MAIN_VARIANT (functype))
   11205              :           /* And the returned value must be non-volatile.  */
   11206     56386394 :           && !TYPE_VOLATILE (TREE_TYPE (retval)));
   11207              : }
   11208              : 
   11209              : /* True if we would like to perform NRVO, i.e. can_do_nrvo_p is true and we
   11210              :    would otherwise return in memory.  */
   11211              : 
   11212              : static bool
   11213     53655906 : want_nrvo_p (tree retval, tree functype)
   11214              : {
   11215     53655906 :   return (can_do_nrvo_p (retval, functype)
   11216     53655906 :           && aggregate_value_p (functype, current_function_decl));
   11217              : }
   11218              : 
   11219              : /* Like can_do_nrvo_p, but we check if we're trying to move a class
   11220              :    prvalue.  */
   11221              : 
   11222              : static bool
   11223         1399 : can_elide_copy_prvalue_p (tree retval, tree functype)
   11224              : {
   11225         1399 :   if (functype == error_mark_node)
   11226              :     return false;
   11227         1399 :   if (retval)
   11228         1399 :     STRIP_ANY_LOCATION_WRAPPER (retval);
   11229         1399 :   return (retval != NULL_TREE
   11230         1399 :           && !glvalue_p (retval)
   11231          135 :           && same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (retval)),
   11232              :                           TYPE_MAIN_VARIANT (functype))
   11233         1507 :           && !TYPE_VOLATILE (TREE_TYPE (retval)));
   11234              : }
   11235              : 
   11236              : /* If we should treat RETVAL, an expression being returned, as if it were
   11237              :    designated by an rvalue, returns it adjusted accordingly; otherwise, returns
   11238              :    NULL_TREE.  See [class.copy.elision].  RETURN_P is true if this is a return
   11239              :    context (rather than throw).  */
   11240              : 
   11241              : tree
   11242     10487668 : treat_lvalue_as_rvalue_p (tree expr, bool return_p)
   11243              : {
   11244     10487668 :   if (cxx_dialect == cxx98)
   11245              :     return NULL_TREE;
   11246              : 
   11247     10478608 :   tree retval = expr;
   11248     10478608 :   STRIP_ANY_LOCATION_WRAPPER (retval);
   11249     10478608 :   if (REFERENCE_REF_P (retval))
   11250       456302 :     retval = TREE_OPERAND (retval, 0);
   11251              : 
   11252              :   /* An implicitly movable entity is a variable of automatic storage duration
   11253              :      that is either a non-volatile object or (C++20) an rvalue reference to a
   11254              :      non-volatile object type.  */
   11255     10478608 :   if (!(((VAR_P (retval) && !DECL_HAS_VALUE_EXPR_P (retval))
   11256      9288838 :          || TREE_CODE (retval) == PARM_DECL)
   11257      1702406 :         && !TREE_STATIC (retval)
   11258      1618253 :         && !CP_TYPE_VOLATILE_P (non_reference (TREE_TYPE (retval)))
   11259      1618248 :         && (TREE_CODE (TREE_TYPE (retval)) != REFERENCE_TYPE
   11260       110085 :             || (cxx_dialect >= cxx20
   11261       109538 :                 && TYPE_REF_IS_RVALUE (TREE_TYPE (retval))))))
   11262      8969872 :     return NULL_TREE;
   11263              : 
   11264              :   /* If the expression in a return or co_return statement is a (possibly
   11265              :      parenthesized) id-expression that names an implicitly movable entity
   11266              :      declared in the body or parameter-declaration-clause of the innermost
   11267              :      enclosing function or lambda-expression, */
   11268      1508736 :   if (return_p)
   11269              :     {
   11270      1499559 :       if (DECL_CONTEXT (retval) != current_function_decl)
   11271              :         return NULL_TREE;
   11272      1499492 :       expr = move (expr);
   11273      1499492 :       if (expr == error_mark_node)
   11274              :         return NULL_TREE;
   11275      1499490 :       return set_implicit_rvalue_p (expr);
   11276              :     }
   11277              : 
   11278              :   /* if the id-expression (possibly parenthesized) is the operand of
   11279              :      a throw-expression, and names an implicitly movable entity that belongs
   11280              :      to a scope that does not contain the compound-statement of the innermost
   11281              :      lambda-expression, try-block, or function-try-block (if any) whose
   11282              :      compound-statement or ctor-initializer contains the throw-expression.  */
   11283              : 
   11284              :   /* C++20 added move on throw of parms.  */
   11285         9177 :   if (TREE_CODE (retval) == PARM_DECL && cxx_dialect < cxx20)
   11286              :     return NULL_TREE;
   11287              : 
   11288              :   /* We don't check for lambda-expression here, because we should not get past
   11289              :      the DECL_HAS_VALUE_EXPR_P check above.  */
   11290         9161 :   for (cp_binding_level *b = current_binding_level;
   11291         9255 :        b->kind != sk_namespace; b = b->level_chain)
   11292              :     {
   11293         9253 :       for (tree decl = b->names; decl; decl = TREE_CHAIN (decl))
   11294          101 :         if (decl == retval)
   11295           89 :           return set_implicit_rvalue_p (move (expr));
   11296         9152 :       if (b->kind == sk_try)
   11297              :         return NULL_TREE;
   11298              :     }
   11299              : 
   11300           14 :   return set_implicit_rvalue_p (move (expr));
   11301              : }
   11302              : 
   11303              : /* Warn about dubious usage of std::move (in a return statement, if RETURN_P
   11304              :    is true).  EXPR is the std::move expression; TYPE is the type of the object
   11305              :    being initialized.  */
   11306              : 
   11307              : void
   11308    147058817 : maybe_warn_pessimizing_move (tree expr, tree type, bool return_p)
   11309              : {
   11310    147058817 :   if (!(warn_pessimizing_move || warn_redundant_move))
   11311              :     return;
   11312              : 
   11313      4553946 :   const location_t loc = cp_expr_loc_or_input_loc (expr);
   11314              : 
   11315              :   /* C++98 doesn't know move.  */
   11316      4553946 :   if (cxx_dialect < cxx11)
   11317              :     return;
   11318              : 
   11319              :   /* Wait until instantiation time, since we can't gauge if we should do
   11320              :      the NRVO until then.  */
   11321      4491301 :   if (processing_template_decl)
   11322              :     return;
   11323              : 
   11324              :   /* This is only interesting for class types.  */
   11325      4402380 :   if (!CLASS_TYPE_P (type))
   11326              :     return;
   11327              : 
   11328       110583 :   bool wrapped_p = false;
   11329              :   /* A a = std::move (A());  */
   11330       110583 :   if (TREE_CODE (expr) == TREE_LIST)
   11331              :     {
   11332         8895 :       if (list_length (expr) == 1)
   11333              :         {
   11334         5968 :           expr = TREE_VALUE (expr);
   11335         5968 :           wrapped_p = true;
   11336              :         }
   11337              :       else
   11338              :         return;
   11339              :     }
   11340              :   /* A a = {std::move (A())};
   11341              :      A a{std::move (A())};  */
   11342       101688 :   else if (TREE_CODE (expr) == CONSTRUCTOR)
   11343              :     {
   11344         7830 :       if (CONSTRUCTOR_NELTS (expr) == 1)
   11345              :         {
   11346          879 :           expr = CONSTRUCTOR_ELT (expr, 0)->value;
   11347          879 :           wrapped_p = true;
   11348              :         }
   11349              :       else
   11350              :         return;
   11351              :     }
   11352              : 
   11353              :   /* First, check if this is a call to std::move.  */
   11354         6766 :   if (!REFERENCE_REF_P (expr)
   11355       105418 :       || TREE_CODE (TREE_OPERAND (expr, 0)) != CALL_EXPR)
   11356              :     return;
   11357         2626 :   tree fn = TREE_OPERAND (expr, 0);
   11358         2626 :   if (!is_std_move_p (fn))
   11359              :     return;
   11360         2042 :   tree arg = CALL_EXPR_ARG (fn, 0);
   11361         2042 :   if (TREE_CODE (arg) != NOP_EXPR)
   11362              :     return;
   11363              :   /* If we're looking at *std::move<T&> ((T &) &arg), do the pessimizing N/RVO
   11364              :      and implicitly-movable warnings.  */
   11365         2042 :   if (TREE_CODE (TREE_OPERAND (arg, 0)) == ADDR_EXPR)
   11366              :     {
   11367         1399 :       arg = TREE_OPERAND (arg, 0);
   11368         1399 :       arg = TREE_OPERAND (arg, 0);
   11369         1399 :       arg = convert_from_reference (arg);
   11370         1399 :       if (can_elide_copy_prvalue_p (arg, type))
   11371              :         {
   11372          108 :           auto_diagnostic_group d;
   11373          108 :           if (warning_at (loc, OPT_Wpessimizing_move,
   11374              :                           "moving a temporary object prevents copy elision"))
   11375          108 :             inform (loc, "remove %<std::move%> call");
   11376          108 :         }
   11377              :       /* The rest of the warnings is only relevant for when we are returning
   11378              :          from a function.  */
   11379         1399 :       if (!return_p)
   11380              :         return;
   11381              : 
   11382          370 :       tree moved;
   11383              :       /* Warn if we could do copy elision were it not for the move.  */
   11384          370 :       if (can_do_nrvo_p (arg, type))
   11385              :         {
   11386           48 :           auto_diagnostic_group d;
   11387           48 :           if (!warning_suppressed_p (expr, OPT_Wpessimizing_move)
   11388           48 :               && warning_at (loc, OPT_Wpessimizing_move,
   11389              :                              "moving a local object in a return statement "
   11390              :                              "prevents copy elision"))
   11391           42 :             inform (loc, "remove %<std::move%> call");
   11392           48 :         }
   11393              :       /* Warn if the move is redundant.  It is redundant when we would
   11394              :          do maybe-rvalue overload resolution even without std::move.  */
   11395          322 :       else if (warn_redundant_move
   11396              :                /* This doesn't apply for return {std::move (t)};.  */
   11397          224 :                && !wrapped_p
   11398          221 :                && !warning_suppressed_p (expr, OPT_Wredundant_move)
   11399          418 :                && (moved = treat_lvalue_as_rvalue_p (arg, /*return*/true)))
   11400              :         {
   11401              :           /* Make sure that overload resolution would actually succeed
   11402              :              if we removed the std::move call.  */
   11403           54 :           tree t = convert_for_initialization (NULL_TREE, type,
   11404              :                                                moved,
   11405              :                                                (LOOKUP_NORMAL
   11406              :                                                 | LOOKUP_ONLYCONVERTING),
   11407              :                                                ICR_RETURN, NULL_TREE, 0,
   11408              :                                                tf_none);
   11409              :           /* If this worked, implicit rvalue would work, so the call to
   11410              :              std::move is redundant.  */
   11411           54 :           if (t != error_mark_node)
   11412              :             {
   11413           54 :               auto_diagnostic_group d;
   11414           54 :               if (warning_at (loc, OPT_Wredundant_move,
   11415              :                               "redundant move in return statement"))
   11416           54 :                 inform (loc, "remove %<std::move%> call");
   11417           54 :             }
   11418              :         }
   11419              :      }
   11420              :   /* Also try to warn about redundant std::move in code such as
   11421              :       T f (const T& t)
   11422              :       {
   11423              :         return std::move(t);
   11424              :       }
   11425              :     for which EXPR will be something like
   11426              :       *std::move<const T&> ((const struct T &) (const struct T *) t)
   11427              :      and where the std::move does nothing if T does not have a T(const T&&)
   11428              :      constructor, because the argument is const.  It will not use T(T&&)
   11429              :      because that would mean losing the const.  */
   11430          643 :   else if (warn_redundant_move
   11431          521 :            && !warning_suppressed_p (expr, OPT_Wredundant_move)
   11432           66 :            && TYPE_REF_P (TREE_TYPE (arg))
   11433          709 :            && CP_TYPE_CONST_P (TREE_TYPE (TREE_TYPE (arg))))
   11434              :     {
   11435           18 :       tree rtype = TREE_TYPE (TREE_TYPE (arg));
   11436           18 :       if (!same_type_ignoring_top_level_qualifiers_p (rtype, type))
   11437            9 :         return;
   11438              :       /* Check for the unlikely case there's T(const T&&) (we don't care if
   11439              :          it's deleted).  */
   11440           54 :       for (tree fn : ovl_range (CLASSTYPE_CONSTRUCTORS (rtype)))
   11441           30 :         if (move_fn_p (fn))
   11442              :           {
   11443           15 :             tree t = TREE_VALUE (FUNCTION_FIRST_USER_PARMTYPE (fn));
   11444           15 :             if (UNLIKELY (CP_TYPE_CONST_P (TREE_TYPE (t))))
   11445            6 :               return;
   11446              :           }
   11447            9 :       auto_diagnostic_group d;
   11448           18 :       if (return_p
   11449            9 :           ? warning_at (loc, OPT_Wredundant_move,
   11450              :                         "redundant move in return statement")
   11451            9 :           : warning_at (loc, OPT_Wredundant_move,
   11452              :                         "redundant move in initialization"))
   11453            9 :         inform (loc, "remove %<std::move%> call");
   11454            9 :     }
   11455              : }
   11456              : 
   11457              : /* Check that returning RETVAL from the current function is valid.
   11458              :    Return an expression explicitly showing all conversions required to
   11459              :    change RETVAL into the function return type, and to assign it to
   11460              :    the DECL_RESULT for the function.  Set *NO_WARNING to true if
   11461              :    code reaches end of non-void function warning shouldn't be issued
   11462              :    on this RETURN_EXPR.  Set *DANGLING to true if code returns the
   11463              :    address of a local variable.  */
   11464              : 
   11465              : tree
   11466    124522979 : check_return_expr (tree retval, bool *no_warning, bool *dangling)
   11467              : {
   11468    124522979 :   tree result;
   11469              :   /* The type actually returned by the function.  */
   11470    124522979 :   tree valtype;
   11471              :   /* The type the function is declared to return, or void if
   11472              :      the declared type is incomplete.  */
   11473    124522979 :   tree functype;
   11474    124522979 :   int fn_returns_value_p;
   11475    124522979 :   location_t loc = cp_expr_loc_or_input_loc (retval);
   11476              : 
   11477    124522979 :   *no_warning = false;
   11478    124522979 :   *dangling = false;
   11479              : 
   11480              :   /* A `volatile' function is one that isn't supposed to return, ever.
   11481              :      (This is a G++ extension, used to get better code for functions
   11482              :      that call the `volatile' function.)  */
   11483    124522979 :   if (TREE_THIS_VOLATILE (current_function_decl))
   11484           12 :     warning (0, "function declared %<noreturn%> has a %<return%> statement");
   11485              : 
   11486              :   /* Check for various simple errors.  */
   11487    249045958 :   if (DECL_DESTRUCTOR_P (current_function_decl))
   11488              :     {
   11489         2335 :       if (retval)
   11490            3 :         error_at (loc, "returning a value from a destructor");
   11491              : 
   11492         2335 :       if (targetm.cxx.cdtor_returns_this () && !processing_template_decl)
   11493            0 :         retval = current_class_ptr;
   11494              :       else
   11495              :         return NULL_TREE;
   11496              :     }
   11497    124520644 :   else if (DECL_CONSTRUCTOR_P (current_function_decl))
   11498              :     {
   11499       152719 :       if (in_function_try_handler)
   11500              :         /* If a return statement appears in a handler of the
   11501              :            function-try-block of a constructor, the program is ill-formed.  */
   11502            0 :         error ("cannot return from a handler of a function-try-block of a constructor");
   11503       152719 :       else if (retval)
   11504              :         /* You can't return a value from a constructor.  */
   11505            3 :         error_at (loc, "returning a value from a constructor");
   11506              : 
   11507       152719 :       if (targetm.cxx.cdtor_returns_this () && !processing_template_decl)
   11508            0 :         retval = current_class_ptr;
   11509              :       else
   11510              :         return NULL_TREE;
   11511              :     }
   11512              : 
   11513    124367925 :   const tree saved_retval = retval;
   11514              : 
   11515    124367925 :   if (processing_template_decl)
   11516              :     {
   11517     80953881 :       current_function_returns_value = 1;
   11518              : 
   11519     80953881 :       if (check_for_bare_parameter_packs (retval))
   11520           14 :         return error_mark_node;
   11521              : 
   11522              :       /* If one of the types might be void, we can't tell whether we're
   11523              :          returning a value.  */
   11524     80953867 :       if ((WILDCARD_TYPE_P (TREE_TYPE (DECL_RESULT (current_function_decl)))
   11525     34115784 :            && !FNDECL_USED_AUTO (current_function_decl))
   11526     46838092 :           || (retval != NULL_TREE
   11527     45716422 :               && (TREE_TYPE (retval) == NULL_TREE
   11528     31779602 :                   || WILDCARD_TYPE_P (TREE_TYPE (retval)))))
   11529     54873073 :         goto dependent;
   11530              :     }
   11531              : 
   11532     69494838 :   functype = TREE_TYPE (TREE_TYPE (current_function_decl));
   11533              : 
   11534              :   /* Deduce auto return type from a return statement.  */
   11535     69494838 :   if (FNDECL_USED_AUTO (current_function_decl))
   11536              :     {
   11537       941785 :       tree pattern = DECL_SAVED_AUTO_RETURN_TYPE (current_function_decl);
   11538       941785 :       tree auto_node;
   11539       941785 :       tree type;
   11540              : 
   11541       941785 :       if (!retval && !is_auto (pattern))
   11542              :         {
   11543              :           /* Give a helpful error message.  */
   11544            3 :           auto_diagnostic_group d;
   11545            3 :           error ("return-statement with no value, in function returning %qT",
   11546              :                  pattern);
   11547            3 :           inform (input_location, "only plain %<auto%> return type can be "
   11548              :                   "deduced to %<void%>");
   11549            3 :           type = error_mark_node;
   11550            3 :         }
   11551       941782 :       else if (retval && BRACE_ENCLOSED_INITIALIZER_P (retval))
   11552              :         {
   11553            6 :           error ("returning initializer list");
   11554            6 :           type = error_mark_node;
   11555              :         }
   11556              :       else
   11557              :         {
   11558       941776 :           if (!retval)
   11559         1968 :             retval = void_node;
   11560       941776 :           auto_node = type_uses_auto (pattern);
   11561       941776 :           type = do_auto_deduction (pattern, retval, auto_node,
   11562              :                                     tf_warning_or_error, adc_return_type);
   11563              :         }
   11564              : 
   11565       941785 :       if (type == error_mark_node)
   11566              :         /* Leave it.  */;
   11567       941556 :       else if (functype == pattern)
   11568       763409 :         apply_deduced_return_type (current_function_decl, type);
   11569       178147 :       else if (!same_type_p (type, functype))
   11570              :         {
   11571           24 :           if (LAMBDA_FUNCTION_P (current_function_decl))
   11572            6 :             error_at (loc, "inconsistent types %qT and %qT deduced for "
   11573              :                       "lambda return type", functype, type);
   11574              :           else
   11575           12 :             error_at (loc, "inconsistent deduction for auto return type: "
   11576              :                       "%qT and then %qT", functype, type);
   11577              :         }
   11578              :       functype = type;
   11579              :     }
   11580              : 
   11581     69494838 :   result = DECL_RESULT (current_function_decl);
   11582     69494838 :   valtype = TREE_TYPE (result);
   11583     69494838 :   gcc_assert (valtype != NULL_TREE);
   11584     69494838 :   fn_returns_value_p = !VOID_TYPE_P (valtype);
   11585              : 
   11586              :   /* Check for a return statement with no return value in a function
   11587              :      that's supposed to return a value.  */
   11588     69494838 :   if (!retval && fn_returns_value_p)
   11589              :     {
   11590           33 :       if (functype != error_mark_node)
   11591           30 :         permerror (input_location, "return-statement with no value, in "
   11592              :                    "function returning %qT", valtype);
   11593              :       /* Remember that this function did return.  */
   11594           33 :       current_function_returns_value = 1;
   11595              :       /* But suppress NRV  .*/
   11596           33 :       current_function_return_value = error_mark_node;
   11597              :       /* And signal caller that TREE_NO_WARNING should be set on the
   11598              :          RETURN_EXPR to avoid control reaches end of non-void function
   11599              :          warnings in tree-cfg.cc.  */
   11600           33 :       *no_warning = true;
   11601              :     }
   11602              :   /* Check for a return statement with a value in a function that
   11603              :      isn't supposed to return a value.  */
   11604     69494805 :   else if (retval && !fn_returns_value_p)
   11605              :     {
   11606       149139 :       if (VOID_TYPE_P (TREE_TYPE (retval)))
   11607              :         /* You can return a `void' value from a function of `void'
   11608              :            type.  In that case, we have to evaluate the expression for
   11609              :            its side-effects.  */
   11610       149104 :         finish_expr_stmt (retval);
   11611           35 :       else if (retval != error_mark_node)
   11612           32 :         permerror (loc, "return-statement with a value, in function "
   11613              :                    "returning %qT", valtype);
   11614       149139 :       current_function_returns_null = 1;
   11615              : 
   11616              :       /* There's really no value to return, after all.  */
   11617       149139 :       return NULL_TREE;
   11618              :     }
   11619     69345666 :   else if (!retval)
   11620              :     /* Remember that this function can sometimes return without a
   11621              :        value.  */
   11622      1610705 :     current_function_returns_null = 1;
   11623              :   else
   11624              :     /* Remember that this function did return a value.  */
   11625     67734961 :     current_function_returns_value = 1;
   11626              : 
   11627              :   /* Check for erroneous operands -- but after giving ourselves a
   11628              :      chance to provide an error about returning a value from a void
   11629              :      function.  */
   11630     69345699 :   if (error_operand_p (retval))
   11631              :     {
   11632         1009 :       current_function_return_value = error_mark_node;
   11633         1009 :       return error_mark_node;
   11634              :     }
   11635              : 
   11636              :   /* Only operator new(...) throw(), can return NULL [expr.new/13].  */
   11637    138689380 :   if (IDENTIFIER_NEW_OP_P (DECL_NAME (current_function_decl))
   11638        30653 :       && !TYPE_NOTHROW_P (TREE_TYPE (current_function_decl))
   11639         2349 :       && ! flag_check_new
   11640     69347030 :       && retval && null_ptr_cst_p (retval))
   11641           24 :     warning (0, "%<operator new%> must not return NULL unless it is "
   11642              :              "declared %<throw()%> (or %<-fcheck-new%> is in effect)");
   11643              : 
   11644              :   /* Effective C++ rule 15.  See also start_function.  */
   11645     69344690 :   if (warn_ecpp
   11646           42 :       && DECL_NAME (current_function_decl) == assign_op_identifier
   11647     69344720 :       && !type_dependent_expression_p (retval))
   11648              :     {
   11649           27 :       bool warn = true;
   11650              : 
   11651              :       /* The function return type must be a reference to the current
   11652              :         class.  */
   11653           27 :       if (TYPE_REF_P (valtype)
   11654           45 :           && same_type_ignoring_top_level_qualifiers_p
   11655           18 :               (TREE_TYPE (valtype), TREE_TYPE (current_class_ref)))
   11656              :         {
   11657              :           /* Returning '*this' is obviously OK.  */
   11658           18 :           if (retval == current_class_ref)
   11659              :             warn = false;
   11660              :           /* If we are calling a function whose return type is the same of
   11661              :              the current class reference, it is ok.  */
   11662            6 :           else if (INDIRECT_REF_P (retval)
   11663            6 :                    && TREE_CODE (TREE_OPERAND (retval, 0)) == CALL_EXPR)
   11664              :             warn = false;
   11665              :         }
   11666              : 
   11667              :       if (warn)
   11668            9 :         warning_at (loc, OPT_Weffc__,
   11669              :                     "%<operator=%> should return a reference to %<*this%>");
   11670              :     }
   11671              : 
   11672     69344690 :   if (dependent_type_p (functype)
   11673     69344690 :       || type_dependent_expression_p (retval))
   11674              :     {
   11675     70561857 :     dependent:
   11676              :       /* We should not have changed the return value.  */
   11677     70561857 :       gcc_assert (retval == saved_retval);
   11678              :       /* We don't know if this is an lvalue or rvalue use, but
   11679              :          either way we can mark it as read.  */
   11680     70561857 :       mark_exp_read (retval);
   11681     70561857 :       return retval;
   11682              :     }
   11683              : 
   11684              :   /* The fabled Named Return Value optimization, as per [class.copy]/15:
   11685              : 
   11686              :      [...]      For  a function with a class return type, if the expression
   11687              :      in the return statement is the name of a local  object,  and  the  cv-
   11688              :      unqualified  type  of  the  local  object  is the same as the function
   11689              :      return type, an implementation is permitted to omit creating the  tem-
   11690              :      porary  object  to  hold  the function return value [...]
   11691              : 
   11692              :      So, if this is a value-returning function that always returns the same
   11693              :      local variable, remember it.
   11694              : 
   11695              :      We choose the first suitable variable even if the function sometimes
   11696              :      returns something else, but only if the variable is out of scope at the
   11697              :      other return sites, or else we run the risk of clobbering the variable we
   11698              :      chose if the other returned expression uses the chosen variable somehow.
   11699              : 
   11700              :      We don't currently do this if the first return is a non-variable, as it
   11701              :      would be complicated to determine whether an NRV selected later was in
   11702              :      scope at the point of the earlier return.  We also don't currently support
   11703              :      multiple variables with non-overlapping scopes (53637).
   11704              : 
   11705              :      See finish_function and finalize_nrv for the rest of this optimization.  */
   11706     53655906 :   tree bare_retval = NULL_TREE;
   11707     53655906 :   if (retval)
   11708              :     {
   11709     52045183 :       retval = maybe_undo_parenthesized_ref (retval);
   11710     52045183 :       bare_retval = tree_strip_any_location_wrapper (retval);
   11711              :     }
   11712              : 
   11713     53655906 :   bool named_return_value_okay_p = want_nrvo_p (bare_retval, functype);
   11714     53655906 :   if (fn_returns_value_p && flag_elide_constructors
   11715     52045160 :       && current_function_return_value != bare_retval)
   11716              :     {
   11717     52040308 :       if (named_return_value_okay_p
   11718       256167 :           && current_function_return_value == NULL_TREE)
   11719       216862 :         current_function_return_value = bare_retval;
   11720     51823446 :       else if (current_function_return_value
   11721     10403552 :                && VAR_P (current_function_return_value)
   11722          200 :                && DECL_NAME (current_function_return_value)
   11723     51823646 :                && !decl_in_scope_p (current_function_return_value))
   11724              :         {
   11725              :           /* The earlier NRV is out of scope at this point, so it's safe to
   11726          137 :              leave it alone; the current return can't refer to it.  */;
   11727          137 :           if (named_return_value_okay_p
   11728          137 :               && !warning_suppressed_p (current_function_decl, OPT_Wnrvo))
   11729              :             {
   11730           12 :               warning (OPT_Wnrvo, "not eliding copy on return from %qD",
   11731              :                        bare_retval);
   11732           12 :               suppress_warning (current_function_decl, OPT_Wnrvo);
   11733              :             }
   11734              :         }
   11735              :       else
   11736              :         {
   11737     51823309 :           if ((named_return_value_okay_p
   11738     51784018 :                || (current_function_return_value
   11739     10364124 :                    && current_function_return_value != error_mark_node))
   11740     51823350 :               && !warning_suppressed_p (current_function_decl, OPT_Wnrvo))
   11741              :             {
   11742        39255 :               warning (OPT_Wnrvo, "not eliding copy on return in %qD",
   11743              :                        current_function_decl);
   11744        39255 :               suppress_warning (current_function_decl, OPT_Wnrvo);
   11745              :             }
   11746     51823309 :           current_function_return_value = error_mark_node;
   11747              :         }
   11748              :     }
   11749              : 
   11750              :   /* We don't need to do any conversions when there's nothing being
   11751              :      returned.  */
   11752     53655906 :   if (!retval)
   11753              :     return NULL_TREE;
   11754              : 
   11755     52045183 :   if (!named_return_value_okay_p)
   11756     51784164 :     maybe_warn_pessimizing_move (retval, functype, /*return_p*/true);
   11757              : 
   11758              :   /* Do any required conversions.  */
   11759    104090366 :   if (bare_retval == result || DECL_CONSTRUCTOR_P (current_function_decl))
   11760              :     /* No conversions are required.  */
   11761              :     ;
   11762              :   else
   11763              :     {
   11764     52045183 :       int flags = LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING;
   11765              : 
   11766              :       /* The functype's return type will have been set to void, if it
   11767              :          was an incomplete type.  Just treat this as 'return;' */
   11768     52045183 :       if (VOID_TYPE_P (functype))
   11769            6 :         return error_mark_node;
   11770              : 
   11771              :       /* Under C++11 [12.8/32 class.copy], a returned lvalue is sometimes
   11772              :          treated as an rvalue for the purposes of overload resolution to
   11773              :          favor move constructors over copy constructors.
   11774              : 
   11775              :          Note that these conditions are similar to, but not as strict as,
   11776              :          the conditions for the named return value optimization.  */
   11777     52045177 :       bool converted = false;
   11778     52045177 :       tree moved;
   11779              :       /* Until C++23, this was only interesting for class type, but in C++23,
   11780              :          we should do the below when we're converting from/to a class/reference
   11781              :          (a non-scalar type).  */
   11782     52045177 :         if ((cxx_dialect < cxx23
   11783      7773418 :              ? CLASS_TYPE_P (functype)
   11784      6949878 :              : !SCALAR_TYPE_P (functype) || !SCALAR_TYPE_P (TREE_TYPE (retval)))
   11785     61950241 :             && (moved = treat_lvalue_as_rvalue_p (retval, /*return*/true)))
   11786              :           /* In C++20 and earlier we treat the return value as an rvalue
   11787              :              that can bind to lvalue refs.  In C++23, such an expression is just
   11788              :              an xvalue (see reference_binding).  */
   11789              :           retval = moved;
   11790              : 
   11791              :       /* The call in a (lambda) thunk needs no conversions.  */
   11792     52045177 :       if (TREE_CODE (retval) == CALL_EXPR
   11793     52045177 :           && call_from_lambda_thunk_p (retval))
   11794              :         converted = true;
   11795              : 
   11796              :       /* Don't check copy-initialization for NRV in a coroutine ramp; we
   11797              :          implement this case as NRV, but it's specified as directly
   11798              :          initializing the return value from get_return_object().  */
   11799     52045177 :       if (DECL_RAMP_P (current_function_decl) && named_return_value_okay_p)
   11800              :         converted = true;
   11801              : 
   11802              :       /* First convert the value to the function's return type, then
   11803              :          to the type of return value's location to handle the
   11804              :          case that functype is smaller than the valtype.  */
   11805     52044928 :       if (!converted)
   11806     51995956 :         retval = convert_for_initialization
   11807     51995956 :           (NULL_TREE, functype, retval, flags, ICR_RETURN, NULL_TREE, 0,
   11808              :            tf_warning_or_error);
   11809     52045177 :       retval = convert (valtype, retval);
   11810              : 
   11811              :       /* If the conversion failed, treat this just like `return;'.  */
   11812     52045177 :       if (retval == error_mark_node)
   11813              :         {
   11814              :           /* And suppress NRV.  */
   11815          197 :           current_function_return_value = error_mark_node;
   11816          197 :           return retval;
   11817              :         }
   11818              :       /* We can't initialize a register from a AGGR_INIT_EXPR.  */
   11819     52044980 :       else if (! cfun->returns_struct
   11820     49999701 :                && TREE_CODE (retval) == TARGET_EXPR
   11821     58285997 :                && TREE_CODE (TARGET_EXPR_INITIAL (retval)) == AGGR_INIT_EXPR)
   11822      1435526 :         retval = build2 (COMPOUND_EXPR, TREE_TYPE (retval), retval,
   11823      1435526 :                          TARGET_EXPR_SLOT (retval));
   11824     50609454 :       else if (!processing_template_decl
   11825     41348593 :                && maybe_warn_about_returning_address_of_local (retval, loc)
   11826     50609635 :                && INDIRECT_TYPE_P (valtype))
   11827          166 :         *dangling = true;
   11828              :     }
   11829              : 
   11830     52044980 :   if (check_out_of_consteval_use (retval))
   11831              :     {
   11832            6 :       current_function_return_value = error_mark_node;
   11833            6 :       return error_mark_node;
   11834              :     }
   11835              : 
   11836              :   /* A naive attempt to reduce the number of -Wdangling-reference false
   11837              :      positives: if we know that this function can return a variable with
   11838              :      static storage duration rather than one of its parameters, suppress
   11839              :      the warning.  */
   11840     52044974 :   if (warn_dangling_reference
   11841       412939 :       && TYPE_REF_P (functype)
   11842        27507 :       && bare_retval
   11843        27507 :       && VAR_P (bare_retval)
   11844           50 :       && TREE_STATIC (bare_retval))
   11845           50 :     suppress_warning (current_function_decl, OPT_Wdangling_reference);
   11846              : 
   11847     52044974 :   if (processing_template_decl)
   11848              :     return saved_retval;
   11849              : 
   11850              :   /* Actually copy the value returned into the appropriate location.  */
   11851     42784114 :   if (retval && retval != result)
   11852     42784114 :     retval = cp_build_init_expr (result, retval);
   11853              : 
   11854     42784114 :   if (current_function_return_value == bare_retval)
   11855       221708 :     INIT_EXPR_NRV_P (retval) = true;
   11856              : 
   11857     42784114 :   if (tree set = maybe_set_retval_sentinel ())
   11858       124190 :     retval = build2 (COMPOUND_EXPR, void_type_node, retval, set);
   11859              : 
   11860              :   return retval;
   11861              : }
   11862              : 
   11863              : 
   11864              : /* Returns nonzero if the pointer-type FROM can be converted to the
   11865              :    pointer-type TO via a qualification conversion.  If CONSTP is -1,
   11866              :    then we return nonzero if the pointers are similar, and the
   11867              :    cv-qualification signature of FROM is a proper subset of that of TO.
   11868              : 
   11869              :    If CONSTP is positive, then all outer pointers have been
   11870              :    const-qualified.  */
   11871              : 
   11872              : static bool
   11873    182531510 : comp_ptr_ttypes_real (tree to, tree from, int constp)
   11874              : {
   11875    182531510 :   bool to_more_cv_qualified = false;
   11876    182531510 :   bool is_opaque_pointer = false;
   11877              : 
   11878       622102 :   for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from))
   11879              :     {
   11880    183153612 :       if (TREE_CODE (to) != TREE_CODE (from))
   11881              :         return false;
   11882              : 
   11883    122355901 :       if (TREE_CODE (from) == OFFSET_TYPE
   11884    122355901 :           && !same_type_p (TYPE_OFFSET_BASETYPE (from),
   11885              :                            TYPE_OFFSET_BASETYPE (to)))
   11886              :         return false;
   11887              : 
   11888              :       /* Const and volatile mean something different for function and
   11889              :          array types, so the usual checks are not appropriate.  We'll
   11890              :          check the array type elements in further iterations.  */
   11891    122355901 :       if (!FUNC_OR_METHOD_TYPE_P (to) && TREE_CODE (to) != ARRAY_TYPE)
   11892              :         {
   11893    122120309 :           if (!at_least_as_qualified_p (to, from))
   11894              :             return false;
   11895              : 
   11896    108794401 :           if (!at_least_as_qualified_p (from, to))
   11897              :             {
   11898     73627043 :               if (constp == 0)
   11899              :                 return false;
   11900              :               to_more_cv_qualified = true;
   11901              :             }
   11902              : 
   11903    108794138 :           if (constp > 0)
   11904    108790089 :             constp &= TYPE_READONLY (to);
   11905              :         }
   11906              : 
   11907    109029730 :       if (VECTOR_TYPE_P (to))
   11908         8511 :         is_opaque_pointer = vector_targets_convertible_p (to, from);
   11909              : 
   11910              :       /* P0388R4 allows a conversion from int[N] to int[] but not the
   11911              :          other way round.  When both arrays have bounds but they do
   11912              :          not match, then no conversion is possible.  */
   11913    109029730 :       if (TREE_CODE (to) == ARRAY_TYPE
   11914    109029730 :           && !comp_array_types (to, from, bounds_first, /*strict=*/false))
   11915              :         return false;
   11916              : 
   11917    109029174 :       if (!TYPE_PTR_P (to)
   11918              :           && !TYPE_PTRDATAMEM_P (to)
   11919              :           /* CWG 330 says we need to look through arrays.  */
   11920              :           && TREE_CODE (to) != ARRAY_TYPE)
   11921    108407072 :         return ((constp >= 0 || to_more_cv_qualified)
   11922    108407072 :                 && (is_opaque_pointer
   11923    108406542 :                     || same_type_ignoring_top_level_qualifiers_p (to, from)));
   11924              :     }
   11925              : }
   11926              : 
   11927              : /* When comparing, say, char ** to char const **, this function takes
   11928              :    the 'char *' and 'char const *'.  Do not pass non-pointer/reference
   11929              :    types to this function.  */
   11930              : 
   11931              : int
   11932    182530882 : comp_ptr_ttypes (tree to, tree from)
   11933              : {
   11934    182530882 :   return comp_ptr_ttypes_real (to, from, 1);
   11935              : }
   11936              : 
   11937              : /* Returns true iff FNTYPE is a non-class type that involves
   11938              :    error_mark_node.  We can get FUNCTION_TYPE with buried error_mark_node
   11939              :    if a parameter type is ill-formed.  */
   11940              : 
   11941              : bool
   11942       689333 : error_type_p (const_tree type)
   11943              : {
   11944       728128 :   tree t;
   11945              : 
   11946       728128 :   switch (TREE_CODE (type))
   11947              :     {
   11948              :     case ERROR_MARK:
   11949              :       return true;
   11950              : 
   11951        38706 :     case POINTER_TYPE:
   11952        38706 :     case REFERENCE_TYPE:
   11953        38706 :     case OFFSET_TYPE:
   11954        38706 :       return error_type_p (TREE_TYPE (type));
   11955              : 
   11956         2893 :     case FUNCTION_TYPE:
   11957         2893 :     case METHOD_TYPE:
   11958         2893 :       if (error_type_p (TREE_TYPE (type)))
   11959              :         return true;
   11960         7760 :       for (t = TYPE_ARG_TYPES (type); t; t = TREE_CHAIN (t))
   11961         4873 :         if (error_type_p (TREE_VALUE (t)))
   11962              :           return true;
   11963              :       return false;
   11964              : 
   11965       184849 :     case RECORD_TYPE:
   11966       184849 :       if (TYPE_PTRMEMFUNC_P (type))
   11967           89 :         return error_type_p (TYPE_PTRMEMFUNC_FN_TYPE (type));
   11968              :       return false;
   11969              : 
   11970              :     default:
   11971              :       return false;
   11972              :     }
   11973              : }
   11974              : 
   11975              : /* Returns true if to and from are (possibly multi-level) pointers to the same
   11976              :    type or inheritance-related types, regardless of cv-quals.  */
   11977              : 
   11978              : bool
   11979    131147200 : ptr_reasonably_similar (const_tree to, const_tree from)
   11980              : {
   11981         1207 :   for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from))
   11982              :     {
   11983              :       /* Any target type is similar enough to void.  */
   11984    131148407 :       if (VOID_TYPE_P (to))
   11985         1341 :         return !error_type_p (from);
   11986    131147066 :       if (VOID_TYPE_P (from))
   11987       678180 :         return !error_type_p (to);
   11988              : 
   11989    130468886 :       if (TREE_CODE (to) != TREE_CODE (from))
   11990              :         return false;
   11991              : 
   11992     70210442 :       if (TREE_CODE (from) == OFFSET_TYPE
   11993     70210442 :           && comptypes (TYPE_OFFSET_BASETYPE (to),
   11994            3 :                         TYPE_OFFSET_BASETYPE (from),
   11995              :                         COMPARE_BASE | COMPARE_DERIVED))
   11996            3 :         continue;
   11997              : 
   11998     70210436 :       if (VECTOR_TYPE_P (to)
   11999     70210436 :           && vector_types_convertible_p (to, from, false))
   12000              :         return true;
   12001              : 
   12002     70210352 :       if (TREE_CODE (to) == INTEGER_TYPE
   12003     70210352 :           && TYPE_PRECISION (to) == TYPE_PRECISION (from))
   12004              :         return true;
   12005              : 
   12006     70033058 :       if (TREE_CODE (to) == FUNCTION_TYPE)
   12007         1023 :         return !error_type_p (to) && !error_type_p (from);
   12008              : 
   12009     70032035 :       if (!TYPE_PTR_P (to))
   12010              :         {
   12011              :           /* When either type is incomplete avoid DERIVED_FROM_P,
   12012              :              which may call complete_type (c++/57942).  */
   12013     70030831 :           bool b = !COMPLETE_TYPE_P (to) || !COMPLETE_TYPE_P (from);
   12014              :           return comptypes
   12015     70030831 :             (TYPE_MAIN_VARIANT (to), TYPE_MAIN_VARIANT (from),
   12016     70030831 :              b ? COMPARE_STRICT : COMPARE_BASE | COMPARE_DERIVED);
   12017              :         }
   12018         1207 :     }
   12019              : }
   12020              : 
   12021              : /* Return true if TO and FROM (both of which are POINTER_TYPEs or
   12022              :    pointer-to-member types) are the same, ignoring cv-qualification at
   12023              :    all levels.  CB says how we should behave when comparing array bounds.  */
   12024              : 
   12025              : bool
   12026       999869 : comp_ptr_ttypes_const (tree to, tree from, compare_bounds_t cb)
   12027              : {
   12028       999869 :   bool is_opaque_pointer = false;
   12029              : 
   12030      1001517 :   for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from))
   12031              :     {
   12032      2001386 :       if (TREE_CODE (to) != TREE_CODE (from))
   12033              :         return false;
   12034              : 
   12035      1671622 :       if (TREE_CODE (from) == OFFSET_TYPE
   12036      1670618 :           && same_type_p (TYPE_OFFSET_BASETYPE (from),
   12037              :                           TYPE_OFFSET_BASETYPE (to)))
   12038         1004 :           continue;
   12039              : 
   12040      1669614 :       if (VECTOR_TYPE_P (to))
   12041         8706 :         is_opaque_pointer = vector_targets_convertible_p (to, from);
   12042              : 
   12043      1669614 :       if (TREE_CODE (to) == ARRAY_TYPE
   12044              :           /* Ignore cv-qualification, but if we see e.g. int[3] and int[4],
   12045              :              we must fail.  */
   12046      1669614 :           && !comp_array_types (to, from, cb, /*strict=*/false))
   12047              :         return false;
   12048              : 
   12049              :       /* CWG 330 says we need to look through arrays.  */
   12050      1667869 :       if (!TYPE_PTR_P (to) && TREE_CODE (to) != ARRAY_TYPE)
   12051       667356 :         return (is_opaque_pointer
   12052       667356 :                 || same_type_ignoring_top_level_qualifiers_p (to, from));
   12053              :     }
   12054              : }
   12055              : 
   12056              : /* Returns the type qualifiers for this type, including the qualifiers on the
   12057              :    elements for an array type.  */
   12058              : 
   12059              : int
   12060  60332502044 : cp_type_quals (const_tree type)
   12061              : {
   12062  60332502044 :   int quals;
   12063              :   /* This CONST_CAST is okay because strip_array_types returns its
   12064              :      argument unmodified and we assign it to a const_tree.  */
   12065  60332502044 :   type = strip_array_types (const_cast<tree> (type));
   12066  60332502044 :   if (type == error_mark_node
   12067              :       /* Quals on a FUNCTION_TYPE are memfn quals.  */
   12068  60298311113 :       || TREE_CODE (type) == FUNCTION_TYPE)
   12069              :     return TYPE_UNQUALIFIED;
   12070  60231251244 :   quals = TYPE_QUALS (type);
   12071              :   /* METHOD and REFERENCE_TYPEs should never have quals.  */
   12072  60231251244 :   gcc_assert ((TREE_CODE (type) != METHOD_TYPE
   12073              :                && !TYPE_REF_P (type))
   12074              :               || ((quals & (TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE))
   12075              :                   == TYPE_UNQUALIFIED));
   12076              :   return quals;
   12077              : }
   12078              : 
   12079              : /* Returns the function-ref-qualifier for TYPE */
   12080              : 
   12081              : cp_ref_qualifier
   12082   3310026195 : type_memfn_rqual (const_tree type)
   12083              : {
   12084   3310026195 :   gcc_assert (FUNC_OR_METHOD_TYPE_P (type));
   12085              : 
   12086   3310026195 :   if (!FUNCTION_REF_QUALIFIED (type))
   12087              :     return REF_QUAL_NONE;
   12088     31024056 :   else if (FUNCTION_RVALUE_QUALIFIED (type))
   12089              :     return REF_QUAL_RVALUE;
   12090              :   else
   12091     15419191 :     return REF_QUAL_LVALUE;
   12092              : }
   12093              : 
   12094              : /* Returns the function-cv-quals for TYPE, which must be a FUNCTION_TYPE or
   12095              :    METHOD_TYPE.  */
   12096              : 
   12097              : int
   12098   1078368932 : type_memfn_quals (const_tree type)
   12099              : {
   12100   1078368932 :   if (TREE_CODE (type) == FUNCTION_TYPE)
   12101    106840008 :     return TYPE_QUALS (type);
   12102    971528924 :   else if (TREE_CODE (type) == METHOD_TYPE)
   12103    971528924 :     return cp_type_quals (class_of_this_parm (type));
   12104              :   else
   12105            0 :     gcc_unreachable ();
   12106              : }
   12107              : 
   12108              : /* Returns the FUNCTION_TYPE TYPE with its function-cv-quals changed to
   12109              :    MEMFN_QUALS and its ref-qualifier to RQUAL. */
   12110              : 
   12111              : tree
   12112     71062631 : apply_memfn_quals (tree type, cp_cv_quals memfn_quals, cp_ref_qualifier rqual)
   12113              : {
   12114              :   /* Could handle METHOD_TYPE here if necessary.  */
   12115     71062631 :   gcc_assert (TREE_CODE (type) == FUNCTION_TYPE);
   12116     71062631 :   if (TYPE_QUALS (type) == memfn_quals
   12117     71062631 :       && type_memfn_rqual (type) == rqual)
   12118              :     return type;
   12119              : 
   12120              :   /* This should really have a different TYPE_MAIN_VARIANT, but that gets
   12121              :      complex.  */
   12122       584004 :   tree result = build_qualified_type (type, memfn_quals);
   12123       584004 :   return build_ref_qualified_type (result, rqual);
   12124              : }
   12125              : 
   12126              : /* Returns nonzero if TYPE is const or volatile.  */
   12127              : 
   12128              : bool
   12129   1180842171 : cv_qualified_p (const_tree type)
   12130              : {
   12131   1180842171 :   int quals = cp_type_quals (type);
   12132   1180842171 :   return (quals & (TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE)) != 0;
   12133              : }
   12134              : 
   12135              : /* Returns nonzero if the TYPE contains a mutable member.  */
   12136              : 
   12137              : bool
   12138    921116426 : cp_has_mutable_p (const_tree type)
   12139              : {
   12140              :   /* This CONST_CAST is okay because strip_array_types returns its
   12141              :      argument unmodified and we assign it to a const_tree.  */
   12142    921116426 :   type = strip_array_types (const_cast<tree> (type));
   12143              : 
   12144    921116426 :   return CLASS_TYPE_P (type) && CLASSTYPE_HAS_MUTABLE (type);
   12145              : }
   12146              : 
   12147              : /* Set TREE_READONLY and TREE_VOLATILE on DECL as indicated by the
   12148              :    TYPE_QUALS.  For a VAR_DECL, this may be an optimistic
   12149              :    approximation.  In particular, consider:
   12150              : 
   12151              :      int f();
   12152              :      struct S { int i; };
   12153              :      const S s = { f(); }
   12154              : 
   12155              :    Here, we will make "s" as TREE_READONLY (because it is declared
   12156              :    "const") -- only to reverse ourselves upon seeing that the
   12157              :    initializer is non-constant.  */
   12158              : 
   12159              : void
   12160    993156035 : cp_apply_type_quals_to_decl (int type_quals, tree decl)
   12161              : {
   12162    993156035 :   tree type = TREE_TYPE (decl);
   12163              : 
   12164    993156035 :   if (type == error_mark_node)
   12165              :     return;
   12166              : 
   12167    993155306 :   if (TREE_CODE (decl) == TYPE_DECL)
   12168              :     return;
   12169              : 
   12170    876640246 :   gcc_assert (!(TREE_CODE (type) == FUNCTION_TYPE
   12171              :                 && type_quals != TYPE_UNQUALIFIED));
   12172              : 
   12173              :   /* Avoid setting TREE_READONLY incorrectly.  */
   12174              :   /* We used to check TYPE_NEEDS_CONSTRUCTING here, but now a constexpr
   12175              :      constructor can produce constant init, so rely on cp_finish_decl to
   12176              :      clear TREE_READONLY if the variable has non-constant init.  */
   12177              : 
   12178              :   /* If the type has (or might have) a mutable component, that component
   12179              :      might be modified.  */
   12180    876640246 :   if (TYPE_HAS_MUTABLE_P (type) || !COMPLETE_TYPE_P (type))
   12181     80565943 :     type_quals &= ~TYPE_QUAL_CONST;
   12182              : 
   12183    876640246 :   c_apply_type_quals_to_decl (type_quals, decl);
   12184              : }
   12185              : 
   12186              : /* Subroutine of casts_away_constness.  Make T1 and T2 point at
   12187              :    exemplar types such that casting T1 to T2 is casting away constness
   12188              :    if and only if there is no implicit conversion from T1 to T2.  */
   12189              : 
   12190              : static void
   12191      1255141 : casts_away_constness_r (tree *t1, tree *t2, tsubst_flags_t complain)
   12192              : {
   12193      1255141 :   int quals1;
   12194      1255141 :   int quals2;
   12195              : 
   12196              :   /* [expr.const.cast]
   12197              : 
   12198              :      For multi-level pointer to members and multi-level mixed pointers
   12199              :      and pointers to members (conv.qual), the "member" aspect of a
   12200              :      pointer to member level is ignored when determining if a const
   12201              :      cv-qualifier has been cast away.  */
   12202              :   /* [expr.const.cast]
   12203              : 
   12204              :      For  two  pointer types:
   12205              : 
   12206              :             X1 is T1cv1,1 * ... cv1,N *   where T1 is not a pointer type
   12207              :             X2 is T2cv2,1 * ... cv2,M *   where T2 is not a pointer type
   12208              :             K is min(N,M)
   12209              : 
   12210              :      casting from X1 to X2 casts away constness if, for a non-pointer
   12211              :      type T there does not exist an implicit conversion (clause
   12212              :      _conv_) from:
   12213              : 
   12214              :             Tcv1,(N-K+1) * cv1,(N-K+2) * ... cv1,N *
   12215              : 
   12216              :      to
   12217              : 
   12218              :             Tcv2,(M-K+1) * cv2,(M-K+2) * ... cv2,M *.  */
   12219      1255141 :   if ((!TYPE_PTR_P (*t1) && !TYPE_PTRDATAMEM_P (*t1))
   12220       627921 :       || (!TYPE_PTR_P (*t2) && !TYPE_PTRDATAMEM_P (*t2)))
   12221              :     {
   12222       627398 :       *t1 = cp_build_qualified_type (void_type_node,
   12223              :                                      cp_type_quals (*t1));
   12224       627398 :       *t2 = cp_build_qualified_type (void_type_node,
   12225              :                                      cp_type_quals (*t2));
   12226       627398 :       return;
   12227              :     }
   12228              : 
   12229       627743 :   quals1 = cp_type_quals (*t1);
   12230       627743 :   quals2 = cp_type_quals (*t2);
   12231              : 
   12232       627743 :   if (TYPE_PTRDATAMEM_P (*t1))
   12233            0 :     *t1 = TYPE_PTRMEM_POINTED_TO_TYPE (*t1);
   12234              :   else
   12235       627743 :     *t1 = TREE_TYPE (*t1);
   12236       627743 :   if (TYPE_PTRDATAMEM_P (*t2))
   12237            0 :     *t2 = TYPE_PTRMEM_POINTED_TO_TYPE (*t2);
   12238              :   else
   12239       627743 :     *t2 = TREE_TYPE (*t2);
   12240              : 
   12241       627743 :   casts_away_constness_r (t1, t2, complain);
   12242       627743 :   *t1 = build_pointer_type (*t1);
   12243       627743 :   *t2 = build_pointer_type (*t2);
   12244       627743 :   *t1 = cp_build_qualified_type (*t1, quals1);
   12245       627743 :   *t2 = cp_build_qualified_type (*t2, quals2);
   12246              : }
   12247              : 
   12248              : /* Returns nonzero if casting from TYPE1 to TYPE2 casts away
   12249              :    constness.
   12250              : 
   12251              :    ??? This function returns non-zero if casting away qualifiers not
   12252              :    just const.  We would like to return to the caller exactly which
   12253              :    qualifiers are casted away to give more accurate diagnostics.
   12254              : */
   12255              : 
   12256              : static bool
   12257       627470 : casts_away_constness (tree t1, tree t2, tsubst_flags_t complain)
   12258              : {
   12259       627470 :   if (TYPE_REF_P (t2))
   12260              :     {
   12261              :       /* [expr.const.cast]
   12262              : 
   12263              :          Casting from an lvalue of type T1 to an lvalue of type T2
   12264              :          using a reference cast casts away constness if a cast from an
   12265              :          rvalue of type "pointer to T1" to the type "pointer to T2"
   12266              :          casts away constness.  */
   12267            0 :       t1 = (TYPE_REF_P (t1) ? TREE_TYPE (t1) : t1);
   12268            0 :       return casts_away_constness (build_pointer_type (t1),
   12269            0 :                                    build_pointer_type (TREE_TYPE (t2)),
   12270            0 :                                    complain);
   12271              :     }
   12272              : 
   12273       627470 :   if (TYPE_PTRDATAMEM_P (t1) && TYPE_PTRDATAMEM_P (t2))
   12274              :     /* [expr.const.cast]
   12275              : 
   12276              :        Casting from an rvalue of type "pointer to data member of X
   12277              :        of type T1" to the type "pointer to data member of Y of type
   12278              :        T2" casts away constness if a cast from an rvalue of type
   12279              :        "pointer to T1" to the type "pointer to T2" casts away
   12280              :        constness.  */
   12281           48 :     return casts_away_constness
   12282           48 :       (build_pointer_type (TYPE_PTRMEM_POINTED_TO_TYPE (t1)),
   12283           48 :        build_pointer_type (TYPE_PTRMEM_POINTED_TO_TYPE (t2)),
   12284           48 :        complain);
   12285              : 
   12286              :   /* Casting away constness is only something that makes sense for
   12287              :      pointer or reference types.  */
   12288       627422 :   if (!TYPE_PTR_P (t1) || !TYPE_PTR_P (t2))
   12289              :     return false;
   12290              : 
   12291              :   /* Top-level qualifiers don't matter.  */
   12292       627398 :   t1 = TYPE_MAIN_VARIANT (t1);
   12293       627398 :   t2 = TYPE_MAIN_VARIANT (t2);
   12294       627398 :   casts_away_constness_r (&t1, &t2, complain);
   12295       627398 :   if (!can_convert (t2, t1, complain))
   12296              :     return true;
   12297              : 
   12298              :   return false;
   12299              : }
   12300              : 
   12301              : /* If T is a REFERENCE_TYPE return the type to which T refers.
   12302              :    Otherwise, return T itself.  */
   12303              : 
   12304              : tree
   12305   4212332013 : non_reference (tree t)
   12306              : {
   12307   4212332013 :   if (t && TYPE_REF_P (t))
   12308    380327887 :     t = TREE_TYPE (t);
   12309   4212332013 :   return t;
   12310              : }
   12311              : 
   12312              : 
   12313              : /* Return nonzero if REF is an lvalue valid for this language;
   12314              :    otherwise, print an error message and return zero.  USE says
   12315              :    how the lvalue is being used and so selects the error message.  */
   12316              : 
   12317              : int
   12318     41167132 : lvalue_or_else (tree ref, enum lvalue_use use, tsubst_flags_t complain)
   12319              : {
   12320     41167132 :   cp_lvalue_kind kind = lvalue_kind (ref);
   12321              : 
   12322     41167132 :   if (kind == clk_none)
   12323              :     {
   12324          380 :       if (complain & tf_error)
   12325          122 :         lvalue_error (cp_expr_loc_or_input_loc (ref), use);
   12326          380 :       return 0;
   12327              :     }
   12328     41166752 :   else if (kind & (clk_rvalueref|clk_class))
   12329              :     {
   12330          143 :       if (!(complain & tf_error))
   12331              :         return 0;
   12332              :       /* Make this a permerror because we used to accept it.  */
   12333           18 :       permerror (cp_expr_loc_or_input_loc (ref),
   12334              :                  "using rvalue as lvalue");
   12335              :     }
   12336              :   return 1;
   12337              : }
   12338              : 
   12339              : /* Return true if a user-defined literal operator is a raw operator.  */
   12340              : 
   12341              : bool
   12342       112546 : check_raw_literal_operator (const_tree decl)
   12343              : {
   12344       112546 :   tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl));
   12345       112546 :   tree argtype;
   12346       112546 :   int arity;
   12347       112546 :   bool maybe_raw_p = false;
   12348              : 
   12349              :   /* Count the number and type of arguments and check for ellipsis.  */
   12350       112546 :   for (argtype = argtypes, arity = 0;
   12351       168836 :        argtype && argtype != void_list_node;
   12352        56290 :        ++arity, argtype = TREE_CHAIN (argtype))
   12353              :     {
   12354        56290 :       tree t = TREE_VALUE (argtype);
   12355              : 
   12356        56290 :       if (same_type_p (t, const_string_type_node))
   12357            9 :         maybe_raw_p = true;
   12358              :     }
   12359       112546 :   if (!argtype)
   12360              :     return false; /* Found ellipsis.  */
   12361              : 
   12362       112546 :   if (!maybe_raw_p || arity != 1)
   12363       112540 :     return false;
   12364              : 
   12365              :   return true;
   12366              : }
   12367              : 
   12368              : 
   12369              : /* Return true if a user-defined literal operator has one of the allowed
   12370              :    argument types.  */
   12371              : 
   12372              : bool
   12373       303705 : check_literal_operator_args (const_tree decl,
   12374              :                              bool *long_long_unsigned_p, bool *long_double_p)
   12375              : {
   12376       303705 :   tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl));
   12377              : 
   12378       303705 :   *long_long_unsigned_p = false;
   12379       303705 :   *long_double_p = false;
   12380       303705 :   if (processing_template_decl || processing_specialization)
   12381        56406 :     return argtypes == void_list_node;
   12382              :   else
   12383              :     {
   12384              :       tree argtype;
   12385              :       int arity;
   12386              :       int max_arity = 2;
   12387              : 
   12388              :       /* Count the number and type of arguments and check for ellipsis.  */
   12389       247190 :       for (argtype = argtypes, arity = 0;
   12390       494489 :            argtype && argtype != void_list_node;
   12391       247190 :            argtype = TREE_CHAIN (argtype))
   12392              :         {
   12393       247305 :           tree t = TREE_VALUE (argtype);
   12394       247305 :           ++arity;
   12395              : 
   12396       247305 :           if (TYPE_PTR_P (t))
   12397              :             {
   12398       117812 :               bool maybe_raw_p = false;
   12399       117812 :               t = TREE_TYPE (t);
   12400       117812 :               if (cp_type_quals (t) != TYPE_QUAL_CONST)
   12401              :                 return false;
   12402       117809 :               t = TYPE_MAIN_VARIANT (t);
   12403       117809 :               if ((maybe_raw_p = same_type_p (t, char_type_node))
   12404        94072 :                   || same_type_p (t, wchar_type_node)
   12405        70502 :                   || same_type_p (t, char8_type_node)
   12406        47152 :                   || same_type_p (t, char16_type_node)
   12407       141385 :                   || same_type_p (t, char32_type_node))
   12408              :                 {
   12409       117806 :                   argtype = TREE_CHAIN (argtype);
   12410       117806 :                   if (!argtype)
   12411              :                     return false;
   12412       117806 :                   t = TREE_VALUE (argtype);
   12413       117806 :                   if (maybe_raw_p && argtype == void_list_node)
   12414              :                     return true;
   12415       117718 :                   else if (same_type_p (t, size_type_node))
   12416              :                     {
   12417       117712 :                       ++arity;
   12418       117712 :                       continue;
   12419              :                     }
   12420              :                   else
   12421              :                     return false;
   12422              :                 }
   12423              :             }
   12424       129493 :           else if (same_type_p (t, long_long_unsigned_type_node))
   12425              :             {
   12426        45611 :               max_arity = 1;
   12427        45611 :               *long_long_unsigned_p = true;
   12428              :             }
   12429        83882 :           else if (same_type_p (t, long_double_type_node))
   12430              :             {
   12431        83782 :               max_arity = 1;
   12432        83782 :               *long_double_p = true;
   12433              :             }
   12434          100 :           else if (same_type_p (t, char_type_node))
   12435              :             max_arity = 1;
   12436           56 :           else if (same_type_p (t, wchar_type_node))
   12437              :             max_arity = 1;
   12438           45 :           else if (same_type_p (t, char8_type_node))
   12439              :             max_arity = 1;
   12440           40 :           else if (same_type_p (t, char16_type_node))
   12441              :             max_arity = 1;
   12442           29 :           else if (same_type_p (t, char32_type_node))
   12443              :             max_arity = 1;
   12444              :           else
   12445              :             return false;
   12446              :         }
   12447       247184 :       if (!argtype)
   12448              :         return false; /* Found ellipsis.  */
   12449              : 
   12450       247181 :       if (arity != max_arity)
   12451              :         return false;
   12452              : 
   12453              :       return true;
   12454              :     }
   12455              : }
   12456              : 
   12457              : /* Always returns false since unlike C90, C++ has no concept of implicit
   12458              :    function declarations.  */
   12459              : 
   12460              : bool
   12461          395 : c_decl_implicit (const_tree)
   12462              : {
   12463          395 :   return false;
   12464              : }
        

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.