LCOV - code coverage report
Current view: top level - gcc/cp - typeck.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 92.2 % 5521 5091
Test Date: 2026-02-28 14:20:25 Functions: 97.7 % 175 171
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Build expressions with type checking for C++ compiler.
       2              :    Copyright (C) 1987-2026 Free Software Foundation, Inc.
       3              :    Hacked by Michael Tiemann (tiemann@cygnus.com)
       4              : 
       5              : This file is part of GCC.
       6              : 
       7              : GCC is free software; you can redistribute it and/or modify
       8              : it under the terms of the GNU General Public License as published by
       9              : the Free Software Foundation; either version 3, or (at your option)
      10              : any later version.
      11              : 
      12              : GCC is distributed in the hope that it will be useful,
      13              : but WITHOUT ANY WARRANTY; without even the implied warranty of
      14              : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15              : GNU General Public License for more details.
      16              : 
      17              : You should have received a copy of the GNU General Public License
      18              : along with GCC; see the file COPYING3.  If not see
      19              : <http://www.gnu.org/licenses/>.  */
      20              : 
      21              : 
      22              : /* This file is part of the C++ front end.
      23              :    It contains routines to build C++ expressions given their operands,
      24              :    including computing the types of the result, C and C++ specific error
      25              :    checks, and some optimization.  */
      26              : 
      27              : #include "config.h"
      28              : #include "system.h"
      29              : #include "coretypes.h"
      30              : #include "target.h"
      31              : #include "cp-tree.h"
      32              : #include "stor-layout.h"
      33              : #include "varasm.h"
      34              : #include "intl.h"
      35              : #include "convert.h"
      36              : #include "c-family/c-objc.h"
      37              : #include "c-family/c-ubsan.h"
      38              : #include "c-family/c-type-mismatch.h"
      39              : #include "stringpool.h"
      40              : #include "attribs.h"
      41              : #include "asan.h"
      42              : #include "gimplify.h"
      43              : 
      44              : static tree cp_build_addr_expr_strict (tree, tsubst_flags_t);
      45              : static tree cp_build_function_call (tree, tree, tsubst_flags_t);
      46              : static tree pfn_from_ptrmemfunc (tree);
      47              : static tree delta_from_ptrmemfunc (tree);
      48              : static tree convert_for_assignment (tree, tree, impl_conv_rhs, tree, int,
      49              :                                     tsubst_flags_t, int);
      50              : static tree cp_pointer_int_sum (location_t, enum tree_code, tree, tree,
      51              :                                 tsubst_flags_t);
      52              : static tree rationalize_conditional_expr (enum tree_code, tree,
      53              :                                           tsubst_flags_t);
      54              : static bool comp_ptr_ttypes_real (tree, tree, int);
      55              : static bool comp_except_types (tree, tree, bool);
      56              : static bool comp_array_types (const_tree, const_tree, compare_bounds_t, bool);
      57              : static tree pointer_diff (location_t, tree, tree, tree, tsubst_flags_t, tree *);
      58              : static tree get_delta_difference (tree, tree, bool, bool, tsubst_flags_t);
      59              : static void casts_away_constness_r (tree *, tree *, tsubst_flags_t);
      60              : static bool casts_away_constness (tree, tree, tsubst_flags_t);
      61              : static bool maybe_warn_about_returning_address_of_local (tree, location_t = UNKNOWN_LOCATION);
      62              : static void error_args_num (location_t, tree, bool);
      63              : static int convert_arguments (tree, vec<tree, va_gc> **, tree, int,
      64              :                               tsubst_flags_t);
      65              : static bool is_std_move_p (tree);
      66              : static bool is_std_forward_p (tree);
      67              : 
      68              : /* Do `exp = require_complete_type (exp);' to make sure exp
      69              :    does not have an incomplete type.  (That includes void types.)
      70              :    Returns error_mark_node if the VALUE does not have
      71              :    complete type when this function returns.  */
      72              : 
      73              : tree
      74    193861195 : require_complete_type (tree value,
      75              :                        tsubst_flags_t complain /* = tf_warning_or_error */)
      76              : {
      77    193861195 :   tree type;
      78              : 
      79    193861195 :   if (processing_template_decl || value == error_mark_node)
      80              :     return value;
      81              : 
      82    183654536 :   if (TREE_CODE (value) == OVERLOAD)
      83            0 :     type = unknown_type_node;
      84              :   else
      85    183654536 :     type = TREE_TYPE (value);
      86              : 
      87    183654536 :   if (type == error_mark_node)
      88              :     return error_mark_node;
      89              : 
      90              :   /* First, detect a valid value with a complete type.  */
      91    183654524 :   if (COMPLETE_TYPE_P (type))
      92              :     return value;
      93              : 
      94       202048 :   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  16552254470 : complete_type (tree type)
     107              : {
     108  16552254470 :   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  16552254470 :   if (type == error_mark_node || COMPLETE_TYPE_P (type))
     114              :     ;
     115   4984967863 :   else if (TREE_CODE (type) == ARRAY_TYPE)
     116              :     {
     117       855708 :       tree t = complete_type (TREE_TYPE (type));
     118       855708 :       unsigned int needs_constructing, has_nontrivial_dtor;
     119       855708 :       if (COMPLETE_TYPE_P (t) && !dependent_type_p (type))
     120       836891 :         layout_type (type);
     121       855708 :       needs_constructing
     122       855708 :         = TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (t));
     123       855708 :       has_nontrivial_dtor
     124       855708 :         = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TYPE_MAIN_VARIANT (t));
     125      2880197 :       for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
     126              :         {
     127      2024489 :           TYPE_NEEDS_CONSTRUCTING (t) = needs_constructing;
     128      2024489 :           TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = has_nontrivial_dtor;
     129              :         }
     130              :     }
     131   4984112155 :   else if (CLASS_TYPE_P (type))
     132              :     {
     133   4883985268 :       if (modules_p ())
     134              :         /* TYPE could be a class member we've not loaded the definition of.  */
     135     14145133 :         lazy_load_pendings (TYPE_NAME (TYPE_MAIN_VARIANT (type)));
     136              : 
     137   4883985268 :       if (CLASSTYPE_TEMPLATE_INSTANTIATION (type))
     138   1039552140 :         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   2010387912 : complete_type_or_maybe_complain (tree type, tree value, tsubst_flags_t complain)
     150              : {
     151   2010387912 :   type = complete_type (type);
     152   2010387909 :   if (type == error_mark_node)
     153              :     /* We already issued an error.  */
     154              :     return NULL_TREE;
     155   2010387757 :   else if (!COMPLETE_TYPE_P (type))
     156              :     {
     157         3810 :       if (complain & tf_error)
     158          472 :         cxx_incomplete_type_diagnostic (value, type, diagnostics::kind::error);
     159         3810 :       note_failed_type_completion (type, complain);
     160         3810 :       return NULL_TREE;
     161              :     }
     162              :   else
     163              :     return type;
     164              : }
     165              : 
     166              : tree
     167    181544576 : complete_type_or_else (tree type, tree value)
     168              : {
     169    181544576 :   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      4083614 : commonparms (tree p1, tree p2)
     182              : {
     183      4083614 :   tree oldargs = p1, newargs, n;
     184      4083614 :   int i, len;
     185      4083614 :   int any_change = 0;
     186              : 
     187      4083614 :   len = list_length (p1);
     188      4083614 :   newargs = tree_last (p1);
     189              : 
     190      4083614 :   if (newargs == void_list_node)
     191              :     i = 1;
     192              :   else
     193              :     {
     194        38304 :       i = 0;
     195        38304 :       newargs = 0;
     196              :     }
     197              : 
     198     13520362 :   for (; i < len; i++)
     199      9436748 :     newargs = tree_cons (NULL_TREE, NULL_TREE, newargs);
     200              : 
     201              :   n = newargs;
     202              : 
     203     17565672 :   for (i = 0; p1;
     204     13482058 :        p1 = TREE_CHAIN (p1), p2 = TREE_CHAIN (p2), n = TREE_CHAIN (n), i++)
     205              :     {
     206     13482261 :       if (TREE_PURPOSE (p1) && !TREE_PURPOSE (p2))
     207              :         {
     208          170 :           TREE_PURPOSE (n) = TREE_PURPOSE (p1);
     209          170 :           any_change = 1;
     210              :         }
     211     13481888 :       else if (! TREE_PURPOSE (p1))
     212              :         {
     213     13481855 :           if (TREE_PURPOSE (p2))
     214              :             {
     215       411531 :               TREE_PURPOSE (n) = TREE_PURPOSE (p2);
     216       411531 :               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     13482058 :       if (TREE_VALUE (p1) != TREE_VALUE (p2))
     226              :         {
     227      3752386 :           any_change = 1;
     228      3752386 :           TREE_VALUE (n) = merge_types (TREE_VALUE (p1), TREE_VALUE (p2));
     229              :         }
     230              :       else
     231      9729672 :         TREE_VALUE (n) = TREE_VALUE (p1);
     232              :     }
     233      4083614 :   if (! any_change)
     234      1383827 :     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     31921496 : original_type (tree t)
     243              : {
     244     31921496 :   int quals = cp_type_quals (t);
     245     31921496 :   while (t != error_mark_node
     246     33035545 :          && TYPE_NAME (t) != NULL_TREE)
     247              :     {
     248     11146003 :       tree x = TYPE_NAME (t);
     249     11146003 :       if (TREE_CODE (x) != TYPE_DECL)
     250              :         break;
     251     11146003 :       x = DECL_ORIGINAL_TYPE (x);
     252     11146003 :       if (x == NULL_TREE)
     253              :         break;
     254              :       t = x;
     255              :     }
     256     31921496 :   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        59342 : merge_type_attributes_from (tree type, tree other_type)
     264              : {
     265        59342 :   tree attrs = targetm.merge_type_attributes (type, other_type);
     266        59342 :   attrs = restrict_type_identity_attributes_to (attrs, TYPE_ATTRIBUTES (type));
     267        59342 :   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      7023932 : cp_compare_floating_point_conversion_ranks (tree t1, tree t2)
     280              : {
     281      7023932 :   tree mv1 = TYPE_MAIN_VARIANT (t1);
     282      7023932 :   tree mv2 = TYPE_MAIN_VARIANT (t2);
     283      7023932 :   int extended1 = 0;
     284      7023932 :   int extended2 = 0;
     285              : 
     286      7023932 :   if (mv1 == mv2)
     287              :     return 0;
     288              : 
     289     56180136 :   for (int i = 0; i < NUM_FLOATN_NX_TYPES; ++i)
     290              :     {
     291     49157619 :       if (mv1 == FLOATN_NX_TYPE_NODE (i))
     292      3237402 :         extended1 = i + 1;
     293     49157619 :       if (mv2 == FLOATN_NX_TYPE_NODE (i))
     294      2683127 :         extended2 = i + 1;
     295              :     }
     296      7022517 :   if (mv1 == bfloat16_type_node)
     297       520398 :     extended1 = true;
     298      7022517 :   if (mv2 == bfloat16_type_node)
     299       415058 :     extended2 = true;
     300      7022517 :   if (extended2 && !extended1)
     301              :     {
     302      2943767 :       int ret = cp_compare_floating_point_conversion_ranks (t2, t1);
     303      2943767 :       return ret == 3 ? 3 : -ret;
     304              :     }
     305              : 
     306      4078750 :   const struct real_format *fmt1 = REAL_MODE_FORMAT (TYPE_MODE (t1));
     307      4078750 :   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      4078750 :   gcc_assert (fmt1->b == 2);
     313      4078750 :   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      4078717 :   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     32629736 :   int p1 = (MODE_COMPOSITE_P (TYPE_MODE (t1))
     338      8157434 :             ? fmt1->emax - fmt1->emin + fmt1->p - 1 : fmt1->p);
     339     32629736 :   int p2 = (MODE_COMPOSITE_P (TYPE_MODE (t2))
     340      8157434 :             ? 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      4078717 :   if ((p1 > p2 && fmt1->emax >= fmt2->emax)
     345      2987028 :        || (p1 == p2 && fmt1->emax > fmt2->emax))
     346              :     return 2;
     347      2987028 :   if ((p1 < p2 && fmt1->emax <= fmt2->emax)
     348      1316879 :        || (p1 == p2 && fmt1->emax < fmt2->emax))
     349              :     return -2;
     350      1316879 :   if ((p1 > p2 && fmt1->emax < fmt2->emax)
     351      1312391 :        || (p1 < p2 && fmt1->emax > fmt2->emax))
     352              :     return 3;
     353      1307903 :   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      1307903 :   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      5231596 :   for (p = &float_type_node; p <= &long_double_type_node; ++p)
     398              :     {
     399      3923697 :       const struct real_format *fmt3 = REAL_MODE_FORMAT (TYPE_MODE (*p));
     400      3923697 :       gcc_assert (fmt3->b == 2);
     401     31389576 :       int p3 = (MODE_COMPOSITE_P (TYPE_MODE (*p))
     402      7847394 :                 ? fmt3->emax - fmt3->emin + fmt3->p - 1 : fmt3->p);
     403      3923697 :       if (p1 == p3 && fmt1->emax == fmt3->emax)
     404       747482 :         ++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      1307899 :   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    120026455 : cp_common_type (tree t1, tree t2)
     436              : {
     437    120026455 :   enum tree_code code1 = TREE_CODE (t1);
     438    120026455 :   enum tree_code code2 = TREE_CODE (t2);
     439    120026455 :   tree attributes;
     440    120026455 :   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    120026455 :   attributes = (*targetm.merge_type_attributes) (t1, t2);
     447              : 
     448    120026455 :   if (SCOPED_ENUM_P (t1) || SCOPED_ENUM_P (t2))
     449              :     {
     450      4063323 :       if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
     451      4063323 :         return build_type_attribute_variant (t1, attributes);
     452              :       else
     453              :         return NULL_TREE;
     454              :     }
     455              : 
     456              :   /* FIXME: Attributes.  */
     457    115963132 :   gcc_assert (ARITHMETIC_TYPE_P (t1)
     458              :               || VECTOR_TYPE_P (t1)
     459              :               || UNSCOPED_ENUM_P (t1));
     460    115963132 :   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    115963132 :   if (code1 == COMPLEX_TYPE || code2 == COMPLEX_TYPE)
     468              :     {
     469       215758 :       tree subtype1 = code1 == COMPLEX_TYPE ? TREE_TYPE (t1) : t1;
     470       215758 :       tree subtype2 = code2 == COMPLEX_TYPE ? TREE_TYPE (t2) : t2;
     471       215758 :       tree subtype
     472       215758 :         = type_after_usual_arithmetic_conversions (subtype1, subtype2);
     473              : 
     474       215758 :       if (subtype == error_mark_node)
     475              :         return subtype;
     476       215758 :       if (code1 == COMPLEX_TYPE && TREE_TYPE (t1) == subtype)
     477       182350 :         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    115747374 :   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        59342 :       if (TYPE_UNSIGNED (t1))
     490        12804 :         return merge_type_attributes_from (t1, t2);
     491              :       else
     492        46538 :         return merge_type_attributes_from (t2, t1);
     493              :     }
     494              : 
     495              :   /* If only one is real, use it as the result.  */
     496    115688032 :   if (code1 == REAL_TYPE && code2 != REAL_TYPE)
     497      1134997 :     return build_type_attribute_variant (t1, attributes);
     498    114553035 :   if (code2 == REAL_TYPE && code1 != REAL_TYPE)
     499       997169 :     return build_type_attribute_variant (t2, attributes);
     500              : 
     501    113555866 :   if (code1 == REAL_TYPE
     502    113555866 :       && (extended_float_type_p (t1) || extended_float_type_p (t2)))
     503              :     {
     504        97746 :       tree mv1 = TYPE_MAIN_VARIANT (t1);
     505        97746 :       tree mv2 = TYPE_MAIN_VARIANT (t2);
     506        97746 :       if (mv1 == mv2)
     507        95612 :         return build_type_attribute_variant (t1, attributes);
     508              : 
     509         2134 :       int cmpret = cp_compare_floating_point_conversion_ranks (mv1, mv2);
     510         2134 :       if (cmpret == 3)
     511            6 :         return error_mark_node;
     512         2128 :       else if (cmpret >= 0)
     513         1860 :         return build_type_attribute_variant (t1, attributes);
     514              :       else
     515          268 :         return build_type_attribute_variant (t2, attributes);
     516              :     }
     517              : 
     518              :   /* Both real or both integers; use the one with greater precision.  */
     519    113458120 :   if (TYPE_PRECISION (t1) > TYPE_PRECISION (t2))
     520     18800317 :     return build_type_attribute_variant (t1, attributes);
     521     94657803 :   else if (TYPE_PRECISION (t2) > TYPE_PRECISION (t1))
     522      2065504 :     return build_type_attribute_variant (t2, attributes);
     523              : 
     524              :   /* The types are the same; no need to do anything fancy.  */
     525     92592299 :   if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
     526     85071959 :     return build_type_attribute_variant (t1, attributes);
     527              : 
     528      7520340 :   if (code1 != REAL_TYPE)
     529              :     {
     530              :       /* If one is unsigned long long, then convert the other to unsigned
     531              :          long long.  */
     532      7520337 :       if (same_type_p (TYPE_MAIN_VARIANT (t1), long_long_unsigned_type_node)
     533      7520337 :           || same_type_p (TYPE_MAIN_VARIANT (t2), long_long_unsigned_type_node))
     534       158808 :         return build_type_attribute_variant (long_long_unsigned_type_node,
     535       158808 :                                              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      7361529 :       if (same_type_p (TYPE_MAIN_VARIANT (t1), long_long_integer_type_node)
     547      7361529 :           || same_type_p (TYPE_MAIN_VARIANT (t2), long_long_integer_type_node))
     548              :         {
     549         1298 :           tree t = ((TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
     550          655 :                     ? long_long_unsigned_type_node
     551          655 :                     : long_long_integer_type_node);
     552          655 :           return build_type_attribute_variant (t, attributes);
     553              :         }
     554              : 
     555              :       /* Go through the same procedure, but for longs.  */
     556      7360874 :       if (same_type_p (TYPE_MAIN_VARIANT (t1), long_unsigned_type_node)
     557      7360874 :           || same_type_p (TYPE_MAIN_VARIANT (t2), long_unsigned_type_node))
     558       896386 :         return build_type_attribute_variant (long_unsigned_type_node,
     559       896386 :                                              attributes);
     560      6464488 :       if (same_type_p (TYPE_MAIN_VARIANT (t1), long_integer_type_node)
     561      6464488 :           || same_type_p (TYPE_MAIN_VARIANT (t2), long_integer_type_node))
     562              :         {
     563        75001 :           tree t = ((TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
     564        75001 :                     ? long_unsigned_type_node : long_integer_type_node);
     565        37945 :           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     12853054 :       for (i = 0; i < NUM_INT_N_ENTS; i ++)
     573              :         {
     574      6426543 :           if (int_n_enabled_p [i]
     575      6426543 :               && (same_type_p (TYPE_MAIN_VARIANT (t1), int_n_trees[i].signed_type)
     576      6341420 :                   || same_type_p (TYPE_MAIN_VARIANT (t2), int_n_trees[i].signed_type)
     577      6341416 :                   || same_type_p (TYPE_MAIN_VARIANT (t1), int_n_trees[i].unsigned_type)
     578      6341416 :                   || 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      6426511 :       if (TYPE_UNSIGNED (t1))
     589      5138806 :         return build_type_attribute_variant (t1, attributes);
     590              :       else
     591      1287705 :         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      1269760 : type_after_usual_arithmetic_conversions (tree t1, tree t2)
     623              : {
     624      1269760 :   gcc_assert (ARITHMETIC_TYPE_P (t1)
     625              :               || VECTOR_TYPE_P (t1)
     626              :               || UNSCOPED_ENUM_P (t1));
     627      1269760 :   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      1269760 :   if (INTEGRAL_OR_ENUMERATION_TYPE_P (t1)
     633      1053657 :       && INTEGRAL_OR_ENUMERATION_TYPE_P (t2))
     634              :     {
     635      1053426 :       t1 = type_promotes_to (t1);
     636      1053426 :       t2 = type_promotes_to (t2);
     637              :     }
     638              : 
     639      1269760 :   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      7878867 : 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      7878867 :   tree pointee1;
     683      7878867 :   tree pointee2;
     684      7878867 :   tree result_type;
     685      7878867 :   tree attributes;
     686              : 
     687              :   /* Determine the types pointed to by T1 and T2.  */
     688      7878867 :   if (TYPE_PTR_P (t1))
     689              :     {
     690      7878329 :       pointee1 = TREE_TYPE (t1);
     691      7878329 :       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      7878867 :   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      7878790 :   const int q1 = cp_type_quals (pointee1);
     723      7878790 :   const int q2 = cp_type_quals (pointee2);
     724      7878790 :   const int quals = q1 | q2;
     725      7878790 :   result_type = cp_build_qualified_type (result_type,
     726      7878790 :                                          (quals | (*add_const
     727      7878790 :                                                    ? 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      7878790 :   if (quals != q1 || quals != q2)
     733       722434 :     *add_const = true;
     734              :   /* If the original types were pointers to members, so is the
     735              :      result.  */
     736      7878790 :   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      7878266 :     result_type = build_pointer_type (result_type);
     752              : 
     753              :   /* Merge the attributes.  */
     754      7878790 :   attributes = (*targetm.merge_type_attributes) (t1, t2);
     755      7878790 :   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      8332477 : 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      8332477 :   tree class1;
     773      8332477 :   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      8332477 :   if (null_ptr_cst_p (arg1))
     780              :     return t2;
     781      8332314 :   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      8311423 :   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      8311423 :   if (TYPE_PTR_P (t1) && VOID_TYPE_P (TREE_TYPE (t1)))
     799              :     {
     800       432484 :       tree attributes;
     801       432484 :       tree result_type;
     802              : 
     803       432484 :       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       432482 :       result_type
     833       432482 :         = cp_build_qualified_type (void_type_node,
     834       432482 :                                    (cp_type_quals (TREE_TYPE (t1))
     835       432482 :                                     | cp_type_quals (TREE_TYPE (t2))));
     836       432482 :       result_type = build_pointer_type (result_type);
     837              :       /* Merge the attributes.  */
     838       432482 :       attributes = (*targetm.merge_type_attributes) (t1, t2);
     839       432482 :       return build_type_attribute_variant (result_type, attributes);
     840              :     }
     841              : 
     842      7878939 :   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      7878939 :   if (fnptr_conv_p (t1, t2))
     853              :     return t1;
     854      7878904 :   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      7878314 :   if (TYPE_PTR_P (t1) && TYPE_PTR_P (t2)
     860      7878314 :       && CLASS_TYPE_P (TREE_TYPE (t1))
     861      1285447 :       && CLASS_TYPE_P (TREE_TYPE (t2))
     862      9164317 :       && !same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (t1),
     863      1285444 :                                                      TREE_TYPE (t2)))
     864              :     {
     865        29159 :       class1 = TREE_TYPE (t1);
     866        29159 :       class2 = TREE_TYPE (t2);
     867              : 
     868        29159 :       if (DERIVED_FROM_P (class1, class2))
     869         3120 :         t2 = (build_pointer_type
     870         1560 :               (cp_build_qualified_type (class1, cp_type_quals (class2))));
     871        27599 :       else if (DERIVED_FROM_P (class2, class1))
     872        55162 :         t1 = (build_pointer_type
     873        27581 :               (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      7849294 :   else if (TYPE_PTRMEM_P (t1)
     885      7849853 :            && !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      7878834 :   bool add_const = false;
     923      7878834 :   return composite_pointer_type_r (location, t1, t2, &add_const, operation,
     924      7878834 :                                    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     29174227 : merge_types (tree t1, tree t2)
     936              : {
     937     29174227 :   enum tree_code code1;
     938     29174227 :   enum tree_code code2;
     939     29174227 :   tree attributes;
     940              : 
     941              :   /* Save time if the two types are the same.  */
     942     29174227 :   if (t1 == t2)
     943              :     return t1;
     944     15960748 :   if (original_type (t1) == original_type (t2))
     945              :     return t1;
     946              : 
     947              :   /* If one type is nonsense, use the other.  */
     948     15843070 :   if (t1 == error_mark_node)
     949              :     return t2;
     950     15843070 :   if (t2 == error_mark_node)
     951              :     return t1;
     952              : 
     953              :   /* Handle merging an auto redeclaration with a previous deduced
     954              :      return type.  */
     955     15843070 :   if (is_auto (t1))
     956              :     return t2;
     957              : 
     958              :   /* Merge the attributes.  */
     959     15834035 :   attributes = (*targetm.merge_type_attributes) (t1, t2);
     960              : 
     961     15834035 :   if (TYPE_PTRMEMFUNC_P (t1))
     962           15 :     t1 = TYPE_PTRMEMFUNC_FN_TYPE (t1);
     963     15834035 :   if (TYPE_PTRMEMFUNC_P (t2))
     964           15 :     t2 = TYPE_PTRMEMFUNC_FN_TYPE (t2);
     965              : 
     966     15834035 :   code1 = TREE_CODE (t1);
     967     15834035 :   code2 = TREE_CODE (t2);
     968     15834035 :   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     15834035 :   switch (code1)
     984              :     {
     985      2687567 :     case POINTER_TYPE:
     986      2687567 :     case REFERENCE_TYPE:
     987              :       /* For two pointers, do this recursively on the target type.  */
     988      2687567 :       {
     989      2687567 :         tree target = merge_types (TREE_TYPE (t1), TREE_TYPE (t2));
     990      2687567 :         int quals = cp_type_quals (t1);
     991              : 
     992      2687567 :         if (code1 == POINTER_TYPE)
     993              :           {
     994       710523 :             t1 = build_pointer_type (target);
     995       710523 :             if (TREE_CODE (target) == METHOD_TYPE)
     996           15 :               t1 = build_ptrmemfunc_type (t1);
     997              :           }
     998              :         else
     999      1977044 :           t1 = cp_build_reference_type (target, TYPE_REF_IS_RVALUE (t1));
    1000      2687567 :         t1 = build_type_attribute_variant (t1, attributes);
    1001      2687567 :         t1 = cp_build_qualified_type (t1, quals);
    1002              : 
    1003      2687567 :         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        10198 :     case ARRAY_TYPE:
    1020        10198 :       {
    1021        10198 :         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        20396 :         if (elt == TREE_TYPE (t1) && TYPE_DOMAIN (t1))
    1024        10173 :           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      4226393 :     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      4226393 :       {
    1037      4226393 :         tree valtype = merge_types (TREE_TYPE (t1), TREE_TYPE (t2));
    1038      4226393 :         tree p1 = TYPE_ARG_TYPES (t1);
    1039      4226393 :         tree p2 = TYPE_ARG_TYPES (t2);
    1040      4226393 :         tree parms;
    1041              : 
    1042              :         /* Save space: see if the result is identical to one of the args.  */
    1043      4226393 :         if (valtype == TREE_TYPE (t1) && ! p2)
    1044            0 :           return cp_build_type_attribute_variant (t1, attributes);
    1045      4226393 :         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      8452786 :         if (p1 == NULL_TREE || TREE_VALUE (p1) == void_type_node)
    1050              :           parms = p2;
    1051      8167228 :         else if (p2 == NULL_TREE || TREE_VALUE (p2) == void_type_node)
    1052              :           parms = p1;
    1053              :         else
    1054      4083614 :           parms = commonparms (p1, p2);
    1055              : 
    1056      4226393 :         cp_cv_quals quals = type_memfn_quals (t1);
    1057      4226393 :         cp_ref_qualifier rqual = type_memfn_rqual (t1);
    1058      4226393 :         gcc_assert (quals == type_memfn_quals (t2));
    1059      4226393 :         gcc_assert (rqual == type_memfn_rqual (t2));
    1060              : 
    1061      4226393 :         tree rval = cp_build_function_type (valtype, parms);
    1062      4226393 :         rval = apply_memfn_quals (rval, quals);
    1063      4226393 :         tree raises = merge_exception_specifiers (TYPE_RAISES_EXCEPTIONS (t1),
    1064      4226393 :                                                   TYPE_RAISES_EXCEPTIONS (t2));
    1065      4226393 :         bool late_return_type_p = TYPE_HAS_LATE_RETURN_TYPE (t1);
    1066      4226393 :         t1 = build_cp_fntype_variant (rval, rqual, raises, late_return_type_p);
    1067      4226393 :         break;
    1068              :       }
    1069              : 
    1070      3843101 :     case METHOD_TYPE:
    1071      3843101 :       {
    1072              :         /* Get this value the long way, since TYPE_METHOD_BASETYPE
    1073              :            is just the main variant of this.  */
    1074      3843101 :         tree basetype = class_of_this_parm (t2);
    1075      3843101 :         tree raises = merge_exception_specifiers (TYPE_RAISES_EXCEPTIONS (t1),
    1076      3843101 :                                                   TYPE_RAISES_EXCEPTIONS (t2));
    1077      3843101 :         cp_ref_qualifier rqual = type_memfn_rqual (t1);
    1078      3843101 :         tree t3;
    1079      3843101 :         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      3843101 :         t1 = cp_build_function_type (TREE_TYPE (t1),
    1085      3843101 :                                      TREE_CHAIN (TYPE_ARG_TYPES (t1)));
    1086      3843101 :         t2 = cp_build_function_type (TREE_TYPE (t2),
    1087      3843101 :                                      TREE_CHAIN (TYPE_ARG_TYPES (t2)));
    1088      3843101 :         t3 = merge_types (t1, t2);
    1089      3843101 :         t3 = build_method_type_directly (basetype, TREE_TYPE (t3),
    1090      3843101 :                                          TYPE_ARG_TYPES (t3));
    1091      3843101 :         t1 = build_cp_fntype_variant (t3, rqual, raises, late_return_type_1_p);
    1092      3843101 :         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      5057769 :     default:;
    1102      5057769 :       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      8069512 :   return cp_build_type_attribute_variant (t1, attributes);
    1110              : }
    1111              : 
    1112              : /* Return the ARRAY_TYPE type without its domain.  */
    1113              : 
    1114              : tree
    1115          377 : strip_array_domain (tree type)
    1116              : {
    1117          377 :   tree t2;
    1118          377 :   gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
    1119          377 :   if (TYPE_DOMAIN (type) == NULL_TREE)
    1120              :     return type;
    1121          216 :   t2 = build_cplus_array_type (TREE_TYPE (type), NULL_TREE);
    1122          216 :   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       792673 : common_type (tree t1, tree t2)
    1135              : {
    1136              :   /* If one type is nonsense, use the other  */
    1137       792673 :   if (t1 == error_mark_node)
    1138              :     return t2;
    1139       792673 :   if (t2 == error_mark_node)
    1140              :     return t1;
    1141              : 
    1142       792673 :   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      2076086 : common_pointer_type (tree t1, tree t2)
    1154              : {
    1155      2076086 :   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      2076086 :   return composite_pointer_type (input_location, t1, t2,
    1160              :                                  error_mark_node, error_mark_node,
    1161      2076086 :                                  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         1746 : comp_except_types (tree a, tree b, bool exact)
    1182              : {
    1183         1746 :   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   1666797165 : comp_except_specs (const_tree t1, const_tree t2, int exact)
    1218              : {
    1219   1666797165 :   const_tree probe;
    1220   1666797165 :   const_tree base;
    1221   1666797165 :   int  length = 0;
    1222              : 
    1223   1666797165 :   if (t1 == t2)
    1224              :     return true;
    1225              : 
    1226              :   /* First handle noexcept.  */
    1227    684757929 :   if (exact < ce_exact)
    1228              :     {
    1229      9096321 :       if (exact == ce_type
    1230     18150225 :           && (canonical_eh_spec (const_cast<tree> (t1))
    1231      9053904 :               == 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      9077033 :       if (t1 == noexcept_false_spec)
    1237          154 :         return t2 == NULL_TREE || exact == ce_derived;
    1238              :       /* Even a derived noexcept(false) is compatible with no
    1239              :          exception-specification.  */
    1240      9076879 :       if (t2 == noexcept_false_spec)
    1241          863 :         return t1 == NULL_TREE;
    1242              : 
    1243              :       /* Otherwise, if we aren't looking for an exact match, noexcept is
    1244              :          equivalent to throw().  */
    1245      9076016 :       if (t1 == noexcept_true_spec)
    1246       676132 :         t1 = empty_except_spec;
    1247      9076016 :       if (t2 == noexcept_true_spec)
    1248      8221791 :         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    655063750 :   if ((t1 && TREE_PURPOSE (t1))
    1255    717243951 :       || (t2 && TREE_PURPOSE (t2)))
    1256    673515273 :     return (t1 && t2
    1257    673515273 :             && (exact == ce_exact
    1258     84781861 :                 ? TREE_PURPOSE (t1) == TREE_PURPOSE (t2)
    1259       175140 :                 : cp_tree_equal (TREE_PURPOSE (t1), TREE_PURPOSE (t2))));
    1260              : 
    1261     11222351 :   if (t1 == NULL_TREE)                     /* T1 is ...  */
    1262      8450970 :     return t2 == NULL_TREE || exact == ce_derived;
    1263      2771381 :   if (!TREE_VALUE (t1))                    /* t1 is EMPTY */
    1264      2737657 :     return t2 != NULL_TREE && !TREE_VALUE (t2);
    1265        35032 :   if (t2 == NULL_TREE)                     /* T2 is ...  */
    1266              :     return false;
    1267         1624 :   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         2791 :   for (base = t1; t2 != NULL_TREE; t2 = TREE_CHAIN (t2))
    1275              :     {
    1276         2142 :       for (probe = base; probe != NULL_TREE; probe = TREE_CHAIN (probe))
    1277              :         {
    1278         1746 :           tree a = TREE_VALUE (probe);
    1279         1746 :           tree b = TREE_VALUE (t2);
    1280              : 
    1281         1746 :           if (comp_except_types (a, b, exact))
    1282              :             {
    1283         1243 :               if (probe == base && exact > ce_derived)
    1284         1208 :                 base = TREE_CHAIN (probe);
    1285         1243 :               length++;
    1286         1243 :               break;
    1287              :             }
    1288              :         }
    1289         1243 :       if (probe == NULL_TREE)
    1290              :         return false;
    1291              :     }
    1292         1152 :   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      2302121 : comp_array_types (const_tree t1, const_tree t2, compare_bounds_t cb,
    1303              :                   bool strict)
    1304              : {
    1305      2302121 :   tree d1;
    1306      2302121 :   tree d2;
    1307      2302121 :   tree max1, max2;
    1308              : 
    1309      2302121 :   if (t1 == t2)
    1310              :     return true;
    1311              : 
    1312              :   /* The type of the array elements must be the same.  */
    1313      2301638 :   if (strict
    1314      2301638 :       ? !same_type_p (TREE_TYPE (t1), TREE_TYPE (t2))
    1315         8175 :       : !similar_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
    1316              :     return false;
    1317              : 
    1318      1432067 :   d1 = TYPE_DOMAIN (t1);
    1319      1432067 :   d2 = TYPE_DOMAIN (t2);
    1320              : 
    1321      1432067 :   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       744317 :   if (!d1 && d2)
    1337         5020 :     return cb >= bounds_either;
    1338       739297 :   else if (d1 && !d2)
    1339        11151 :     return cb == bounds_either;
    1340              : 
    1341              :   /* Check that the dimensions are the same.  */
    1342              : 
    1343       728146 :   if (!cp_tree_equal (TYPE_MIN_VALUE (d1), TYPE_MIN_VALUE (d2)))
    1344              :     return false;
    1345       728125 :   max1 = TYPE_MAX_VALUE (d1);
    1346       728125 :   max2 = TYPE_MAX_VALUE (d2);
    1347              : 
    1348       728125 :   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   1747332194 : comp_template_parms_position (tree t1, tree t2)
    1361              : {
    1362   1747332194 :   tree index1, index2;
    1363   1747332194 :   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   1747332194 :   index1 = TEMPLATE_TYPE_PARM_INDEX (TYPE_MAIN_VARIANT (t1));
    1370   1747332194 :   index2 = TEMPLATE_TYPE_PARM_INDEX (TYPE_MAIN_VARIANT (t2));
    1371              : 
    1372              :   /* Then compare their relative position.  */
    1373   1747332194 :   if (TEMPLATE_PARM_IDX (index1) != TEMPLATE_PARM_IDX (index2)
    1374   1201859725 :       || TEMPLATE_PARM_LEVEL (index1) != TEMPLATE_PARM_LEVEL (index2)
    1375   2653571231 :       || (TEMPLATE_PARM_PARAMETER_PACK (index1)
    1376    906239037 :           != 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    816867635 :   if (cxx_dialect >= cxx14 && (is_auto (t1) || is_auto (t2)))
    1382    207576568 :     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        19616 : cxx_safe_function_type_cast_p (tree t1, tree t2)
    1414              : {
    1415        19616 :   if (TREE_TYPE (t1) == void_type_node &&
    1416        19543 :       TYPE_ARG_TYPES (t1) == void_list_node)
    1417              :     return true;
    1418              : 
    1419        18621 :   if (TREE_TYPE (t2) == void_type_node &&
    1420        18415 :       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  18888185380 : structural_comptypes (tree t1, tree t2, int strict)
    1439              : {
    1440              :   /* Both should be types that are not obviously the same.  */
    1441  18888185380 :   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  18888185380 :   if (!comparing_specializations)
    1446              :     {
    1447              :       /* TYPENAME_TYPEs should be resolved if the qualifying scope is the
    1448              :          current instantiation.  */
    1449  15547062399 :       if (TREE_CODE (t1) == TYPENAME_TYPE)
    1450    148166100 :         t1 = resolve_typename_type (t1, /*only_current_p=*/true);
    1451              : 
    1452  15547062399 :       if (TREE_CODE (t2) == TYPENAME_TYPE)
    1453    213653140 :         t2 = resolve_typename_type (t2, /*only_current_p=*/true);
    1454              :     }
    1455              : 
    1456  18888185380 :   if (TYPE_PTRMEMFUNC_P (t1))
    1457     25021114 :     t1 = TYPE_PTRMEMFUNC_FN_TYPE (t1);
    1458  18888185380 :   if (TYPE_PTRMEMFUNC_P (t2))
    1459     28149225 :     t2 = TYPE_PTRMEMFUNC_FN_TYPE (t2);
    1460              : 
    1461              :   /* Different classes of types can't be compatible.  */
    1462  18888185380 :   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  12146201756 :   if (TREE_CODE (t1) != ARRAY_TYPE
    1468  12146201756 :       && cp_type_quals (t1) != cp_type_quals (t2))
    1469              :     return false;
    1470  11355572481 :   if (TREE_CODE (t1) == FUNCTION_TYPE
    1471  11355572481 :       && 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  11355512887 :   if (FUNC_OR_METHOD_TYPE_P (t1))
    1476              :     {
    1477     36259012 :       if (type_memfn_rqual (t1) != type_memfn_rqual (t2))
    1478              :         return false;
    1479     21619239 :       if (flag_noexcept_type
    1480     43162425 :           && !comp_except_specs (TYPE_RAISES_EXCEPTIONS (t1),
    1481     21543186 :                                  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  11331974769 :   if (TREE_CODE (t1) != ARRAY_TYPE
    1490  11331974769 :       && TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
    1491    565779920 :     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  10766194849 :   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    854839735 :     case OPAQUE_TYPE:
    1504    854839735 :     case INTEGER_TYPE:
    1505    854839735 :     case FIXED_POINT_TYPE:
    1506    854839735 :     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    854839735 :       if (TYPE_CANONICAL (t1) != TYPE_CANONICAL (t2))
    1522              :         return false;
    1523              : 
    1524              :       /* We don't need or want the attribute comparison.  */
    1525         9119 :       goto check_alias;
    1526              : 
    1527      1836611 :     case TEMPLATE_TEMPLATE_PARM:
    1528      1836611 :     case BOUND_TEMPLATE_TEMPLATE_PARM:
    1529      1836611 :       if (!comp_template_parms_position (t1, t2))
    1530              :         return false;
    1531      1345460 :       if (!comp_template_parms
    1532      2690920 :           (DECL_TEMPLATE_PARMS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (t1)),
    1533      3701168 :            DECL_TEMPLATE_PARMS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (t2))))
    1534              :         return false;
    1535       901243 :       if (TREE_CODE (t1) == TEMPLATE_TEMPLATE_PARM)
    1536              :         break;
    1537              :       /* Don't check inheritance.  */
    1538              :       strict = COMPARE_STRICT;
    1539              :       /* Fall through.  */
    1540              : 
    1541   5130275859 :     case RECORD_TYPE:
    1542   5130275859 :     case UNION_TYPE:
    1543   9061399158 :       if (TYPE_TEMPLATE_INFO (t1) && TYPE_TEMPLATE_INFO (t2)
    1544   3299107584 :           && (TYPE_TI_TEMPLATE (t1) == TYPE_TI_TEMPLATE (t2)
    1545   2403373791 :               || TREE_CODE (t1) == BOUND_TEMPLATE_TEMPLATE_PARM)
    1546   6026127648 :           && comp_template_args (TYPE_TI_ARGS (t1), TYPE_TI_ARGS (t2)))
    1547              :         break;
    1548              : 
    1549   5030994596 :       if ((strict & COMPARE_BASE) && DERIVED_FROM_P (t1, t2))
    1550              :         break;
    1551   5030994563 :       else if ((strict & COMPARE_DERIVED) && DERIVED_FROM_P (t2, t1))
    1552              :         break;
    1553              : 
    1554              :       return false;
    1555              : 
    1556        52870 :     case OFFSET_TYPE:
    1557        52870 :       if (!comptypes (TYPE_OFFSET_BASETYPE (t1), TYPE_OFFSET_BASETYPE (t2),
    1558              :                       strict & ~COMPARE_REDECLARATION))
    1559              :         return false;
    1560        48173 :       if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
    1561              :         return false;
    1562              :       break;
    1563              : 
    1564   1748576853 :     case REFERENCE_TYPE:
    1565   1748576853 :       if (TYPE_REF_IS_RVALUE (t1) != TYPE_REF_IS_RVALUE (t2))
    1566              :         return false;
    1567              :       /* fall through to checks for pointer types */
    1568   2230656532 :       gcc_fallthrough ();
    1569              : 
    1570   2230656532 :     case POINTER_TYPE:
    1571   2230656532 :       if (TYPE_MODE (t1) != TYPE_MODE (t2)
    1572   2230656532 :           || !same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
    1573   2054113547 :         return false;
    1574              :       break;
    1575              : 
    1576      5388381 :     case FUNCTION_TYPE:
    1577      5388381 :       if (TYPE_NO_NAMED_ARGS_STDARG_P (t1) != TYPE_NO_NAMED_ARGS_STDARG_P (t2))
    1578              :         return false;
    1579              :       /* FALLTHRU */
    1580     12435535 :     case METHOD_TYPE:
    1581              :       /* Exception specs and memfn_rquals were checked above.  */
    1582     12435535 :       if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
    1583              :         return false;
    1584     11831397 :       if (!compparms (TYPE_ARG_TYPES (t1), TYPE_ARG_TYPES (t2)))
    1585              :         return false;
    1586              :       break;
    1587              : 
    1588      2293463 :     case ARRAY_TYPE:
    1589              :       /* Target types must match incl. qualifiers.  */
    1590      2293463 :       if (!comp_array_types (t1, t2, ((strict & COMPARE_REDECLARATION)
    1591      2293463 :                                       ? bounds_either : bounds_none),
    1592              :                              /*strict=*/true))
    1593              :         return false;
    1594              :       break;
    1595              : 
    1596   1745495583 :     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   1745495583 :       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   1328465476 :       if (!cp_tree_equal (CLASS_PLACEHOLDER_TEMPLATE (t1),
    1604    664232738 :                           CLASS_PLACEHOLDER_TEMPLATE (t2)))
    1605              :         return false;
    1606              :       /* Constrained 'auto's are distinct from parms that don't have the same
    1607              :          constraints.  */
    1608    644149707 :       if (!equivalent_placeholder_constraints (t1, t2))
    1609              :         return false;
    1610              :       break;
    1611              : 
    1612    299683351 :     case TYPENAME_TYPE:
    1613    599366702 :       if (!cp_tree_equal (TYPENAME_TYPE_FULLNAME (t1),
    1614    299683351 :                           TYPENAME_TYPE_FULLNAME (t2)))
    1615              :         return false;
    1616              :       /* Qualifiers don't matter on scopes.  */
    1617    262581935 :       if (!same_type_ignoring_top_level_qualifiers_p (TYPE_CONTEXT (t1),
    1618    262581935 :                                                       TYPE_CONTEXT (t2)))
    1619              :         return false;
    1620              :       break;
    1621              : 
    1622        26171 :     case UNBOUND_CLASS_TEMPLATE:
    1623        26171 :       if (!cp_tree_equal (TYPE_IDENTIFIER (t1), TYPE_IDENTIFIER (t2)))
    1624              :         return false;
    1625        26171 :       if (!same_type_p (TYPE_CONTEXT (t1), TYPE_CONTEXT (t2)))
    1626              :         return false;
    1627              :       break;
    1628              : 
    1629      2050445 :     case COMPLEX_TYPE:
    1630      2050445 :       if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
    1631              :         return false;
    1632              :       break;
    1633              : 
    1634     12644800 :     case VECTOR_TYPE:
    1635     12644800 :       if (gnu_vector_type_p (t1) != gnu_vector_type_p (t2)
    1636     23615081 :           || maybe_ne (TYPE_VECTOR_SUBPARTS (t1), TYPE_VECTOR_SUBPARTS (t2))
    1637     23669624 :           || !same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
    1638      1674519 :         return false;
    1639              :       break;
    1640              : 
    1641      7344850 :     case TYPE_PACK_EXPANSION:
    1642      7344850 :       return (same_type_p (PACK_EXPANSION_PATTERN (t1),
    1643              :                            PACK_EXPANSION_PATTERN (t2))
    1644     14535872 :               && comp_template_args (PACK_EXPANSION_EXTRA_ARGS (t1),
    1645      7191022 :                                      PACK_EXPANSION_EXTRA_ARGS (t2)));
    1646              : 
    1647           14 :     case PACK_INDEX_TYPE:
    1648           14 :       return (cp_tree_equal (PACK_INDEX_PACK (t1),
    1649           14 :                              PACK_INDEX_PACK (t2))
    1650           16 :               && cp_tree_equal (PACK_INDEX_INDEX (t1),
    1651            2 :                                 PACK_INDEX_INDEX (t2)));
    1652              : 
    1653     32814025 :     case DECLTYPE_TYPE:
    1654     65628050 :       if (DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t1)
    1655     32814025 :           != DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t2))
    1656              :         return false;
    1657     32797634 :       if (DECLTYPE_FOR_LAMBDA_CAPTURE (t1) != DECLTYPE_FOR_LAMBDA_CAPTURE (t2))
    1658              :         return false;
    1659     32797634 :       if (DECLTYPE_FOR_LAMBDA_PROXY (t1) != DECLTYPE_FOR_LAMBDA_PROXY (t2))
    1660              :         return false;
    1661     32797634 :       if (!cp_tree_equal (DECLTYPE_TYPE_EXPR (t1), DECLTYPE_TYPE_EXPR (t2)))
    1662              :         return false;
    1663              :       break;
    1664              : 
    1665       699768 :     case TRAIT_TYPE:
    1666       699768 :       if (TRAIT_TYPE_KIND (t1) != TRAIT_TYPE_KIND (t2))
    1667              :         return false;
    1668         1401 :       if (!cp_tree_equal (TRAIT_TYPE_TYPE1 (t1), TRAIT_TYPE_TYPE1 (t2))
    1669         2802 :           || !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    951788596 :   if (!comp_type_attributes (t1, t2))
    1686              :     return false;
    1687              : 
    1688    951787409 :  check_alias:
    1689   1517576448 :   if (comparing_dependent_aliases
    1690   1517576448 :       && (typedef_variant_p (t1) || typedef_variant_p (t2)))
    1691              :     {
    1692      4889057 :       tree dep1 = dependent_opaque_alias_p (t1) ? t1 : NULL_TREE;
    1693      4889057 :       tree dep2 = dependent_opaque_alias_p (t2) ? t2 : NULL_TREE;
    1694      4889057 :       if ((dep1 || dep2)
    1695      4889057 :           && (!(dep1 && dep2)
    1696            0 :               || !comp_type_attributes (DECL_ATTRIBUTES (TYPE_NAME (dep1)),
    1697            0 :                                         DECL_ATTRIBUTES (TYPE_NAME (dep2)))))
    1698           13 :         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      4889044 :       ++processing_template_decl;
    1707      4889044 :       dep1 = dependent_alias_template_spec_p (t1, nt_transparent);
    1708      4889044 :       dep2 = dependent_alias_template_spec_p (t2, nt_transparent);
    1709      4889044 :       --processing_template_decl;
    1710      4889044 :       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         1602 : compatible_types_for_indirection_note_p (tree type1, tree type2)
    1721              : {
    1722         1602 :   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  27871949443 : comptypes (tree t1, tree t2, int strict)
    1730              : {
    1731  27871949443 :   gcc_checking_assert (t1 && t2);
    1732              : 
    1733              :   /* TYPE_ARGUMENT_PACKS are not really types.  */
    1734  27871949443 :   gcc_checking_assert (TREE_CODE (t1) != TYPE_ARGUMENT_PACK
    1735              :                        && TREE_CODE (t2) != TYPE_ARGUMENT_PACK);
    1736              : 
    1737  27871949443 :   if (t1 == t2)
    1738              :     return true;
    1739              : 
    1740              :   /* Suppress errors caused by previously reported errors.  */
    1741  18888186544 :   if (t1 == error_mark_node || t2 == error_mark_node)
    1742              :     return false;
    1743              : 
    1744  18888186383 :   if (strict == COMPARE_STRICT)
    1745              :     {
    1746  17380397899 :       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   1990950798 :         return structural_comptypes (t1, t2, strict);
    1750              : 
    1751  15389447101 :       if (flag_checking && param_use_canonical_types)
    1752              :         {
    1753  15389446098 :           bool result = structural_comptypes (t1, t2, strict);
    1754              : 
    1755  15389446098 :           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  15389446098 :           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   1507788484 :   else if (strict == COMPARE_STRUCTURAL)
    1778   1425767537 :     return structural_comptypes (t1, t2, COMPARE_STRICT);
    1779              :   else
    1780     82020947 :     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   5271467687 : same_type_ignoring_top_level_qualifiers_p (tree type1, tree type2)
    1788              : {
    1789   5271467687 :   if (type1 == error_mark_node || type2 == error_mark_node)
    1790              :     return false;
    1791   5271466973 :   if (type1 == type2)
    1792              :     return true;
    1793              : 
    1794   3160377826 :   type1 = cp_build_qualified_type (type1, TYPE_UNQUALIFIED);
    1795   3160377826 :   type2 = cp_build_qualified_type (type2, TYPE_UNQUALIFIED);
    1796   3160377826 :   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    465986834 : similar_type_p (tree type1, tree type2)
    1803              : {
    1804    465986834 :   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    465986834 :   if (same_type_ignoring_top_level_qualifiers_p (type1, type2))
    1816              :     return true;
    1817              : 
    1818    201874849 :   if ((TYPE_PTR_P (type1) && TYPE_PTR_P (type2))
    1819    201571968 :       || (TYPE_PTRDATAMEM_P (type1) && TYPE_PTRDATAMEM_P (type2))
    1820    201571035 :       || (TREE_CODE (type1) == ARRAY_TYPE && TREE_CODE (type2) == ARRAY_TYPE))
    1821       305294 :     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    323299009 : at_least_as_qualified_p (const_tree type1, const_tree type2)
    2086              : {
    2087    323299009 :   int q1 = cp_type_quals (type1);
    2088    323299009 :   int q2 = cp_type_quals (type2);
    2089              : 
    2090              :   /* All qualifiers for TYPE2 must also appear in TYPE1.  */
    2091    323299009 :   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     21195636 : comp_cv_qualification (int q1, int q2)
    2099              : {
    2100     21195636 :   if (q1 == q2)
    2101              :     return 0;
    2102              : 
    2103      4123237 :   if ((q1 & q2) == q2)
    2104              :     return 1;
    2105       363170 :   else if ((q1 & q2) == q1)
    2106       362585 :     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   1326628853 : compparms (const_tree parms1, const_tree parms2)
    2143              : {
    2144   1326628853 :   const_tree t1, t2;
    2145              : 
    2146              :   /* An unspecified parmlist matches any specified parmlist
    2147              :      whose argument types don't need default promotions.  */
    2148              : 
    2149   1326628853 :   for (t1 = parms1, t2 = parms2;
    2150   2063480764 :        t1 || t2;
    2151    736851911 :        t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2))
    2152              :     {
    2153              :       /* If one parmlist is shorter than the other,
    2154              :          they fail to match.  */
    2155   1918606592 :       if (!t1 || !t2)
    2156              :         return false;
    2157   1918039558 :       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     32892224 : cxx_sizeof_or_alignof_type (location_t loc, tree type, enum tree_code op,
    2171              :                             bool std_alignof, bool complain)
    2172              : {
    2173     32892224 :   gcc_assert (op == SIZEOF_EXPR || op == ALIGNOF_EXPR);
    2174     32892224 :   if (type == error_mark_node)
    2175              :     return error_mark_node;
    2176              : 
    2177     32892222 :   type = non_reference (type);
    2178     32892222 :   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     32892222 :   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     32892210 :   bool dependent_p = dependent_type_p (type);
    2199     32892210 :   if (!dependent_p)
    2200              :     {
    2201     28160547 :       complete_type (type);
    2202     28160547 :       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          198 :         note_failed_type_completion (type, complain);
    2207              :     }
    2208     28160547 :   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     28160547 :       || (processing_template_decl
    2216      2023886 :           && COMPLETE_TYPE_P (type)
    2217      2023880 :           && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST))
    2218              :     {
    2219      4731663 :       tree value = build_min (op, size_type_node, type);
    2220      4731663 :       TREE_READONLY (value) = 1;
    2221      4731663 :       if (op == ALIGNOF_EXPR && std_alignof)
    2222       551044 :         ALIGNOF_EXPR_STD_P (value) = true;
    2223      4731663 :       SET_EXPR_LOCATION (value, loc);
    2224      4731663 :       return value;
    2225              :     }
    2226              : 
    2227     28160547 :   return c_sizeof_or_alignof_type (loc, complete_type (type),
    2228              :                                    op == SIZEOF_EXPR, std_alignof,
    2229     28160547 :                                    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      3804777 : cxx_sizeof_nowarn (tree type)
    2238              : {
    2239      3804777 :   if (TREE_CODE (type) == FUNCTION_TYPE
    2240      3804777 :       || VOID_TYPE_P (type)
    2241      3804695 :       || TREE_CODE (type) == ERROR_MARK)
    2242           82 :     return size_one_node;
    2243      3804695 :   else if (!COMPLETE_TYPE_P (type))
    2244           19 :     return size_zero_node;
    2245              :   else
    2246      3804676 :     return cxx_sizeof_or_alignof_type (input_location, type,
    2247      3804676 :                                        SIZEOF_EXPR, false, false);
    2248              : }
    2249              : 
    2250              : /* Process a sizeof expression where the operand is an expression.  */
    2251              : 
    2252              : static tree
    2253      2140060 : cxx_sizeof_expr (location_t loc, tree e, tsubst_flags_t complain)
    2254              : {
    2255      2140060 :   if (e == error_mark_node)
    2256              :     return error_mark_node;
    2257              : 
    2258      2139326 :   if (instantiation_dependent_uneval_expression_p (e))
    2259              :     {
    2260       332623 :       e = build_min (SIZEOF_EXPR, size_type_node, e);
    2261       332623 :       TREE_SIDE_EFFECTS (e) = 0;
    2262       332623 :       TREE_READONLY (e) = 1;
    2263       332623 :       SET_EXPR_LOCATION (e, loc);
    2264              : 
    2265       332623 :       return e;
    2266              :     }
    2267              : 
    2268      1806703 :   location_t e_loc = cp_expr_loc_or_loc (e, loc);
    2269      1806703 :   STRIP_ANY_LOCATION_WRAPPER (e);
    2270              : 
    2271      1806703 :   if (TREE_CODE (e) == PARM_DECL
    2272        32801 :       && DECL_ARRAY_PARAMETER_P (e)
    2273      1807080 :       && (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      1806703 :   e = mark_type_use (e);
    2283              : 
    2284      1806703 :   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      1806691 :   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      1806658 :   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      1806658 :     e = TREE_TYPE (e);
    2312              : 
    2313      1806676 :   return cxx_sizeof_or_alignof_type (loc, e, SIZEOF_EXPR, false,
    2314      1806676 :                                      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       100137 : cxx_alignof_expr (location_t loc, tree e, bool std_alignof,
    2325              :                   tsubst_flags_t complain)
    2326              : {
    2327       100137 :   tree t;
    2328              : 
    2329       100137 :   if (e == error_mark_node)
    2330              :     return error_mark_node;
    2331              : 
    2332       100129 :   if (processing_template_decl)
    2333              :     {
    2334        18424 :       e = build_min (ALIGNOF_EXPR, size_type_node, e);
    2335        18424 :       TREE_SIDE_EFFECTS (e) = 0;
    2336        18424 :       TREE_READONLY (e) = 1;
    2337        18424 :       SET_EXPR_LOCATION (e, loc);
    2338        18424 :       ALIGNOF_EXPR_STD_P (e) = std_alignof;
    2339              : 
    2340        18424 :       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      2240197 : cxx_sizeof_or_alignof_expr (location_t loc, tree e, enum tree_code op,
    2402              :                             bool std_alignof, bool complain)
    2403              : {
    2404      2240197 :   gcc_assert (op == SIZEOF_EXPR || op == ALIGNOF_EXPR);
    2405      2240197 :   if (op == SIZEOF_EXPR)
    2406      3317777 :     return cxx_sizeof_expr (loc, e, complain? tf_warning_or_error : tf_none);
    2407              :   else
    2408       100164 :     return cxx_alignof_expr (loc, e, std_alignof,
    2409       100137 :                              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       265289 : cxx_alignas_expr (tree e)
    2421              : {
    2422       265289 :   if (e == NULL_TREE || e == error_mark_node
    2423       530578 :       || (!TYPE_P (e) && !require_potential_rvalue_constant_expression (e)))
    2424            0 :     return e;
    2425              : 
    2426       265289 :   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       139416 :     return cxx_sizeof_or_alignof_type (input_location,
    2434              :                                        e, ALIGNOF_EXPR,
    2435              :                                        /*std_alignof=*/true,
    2436       139416 :                                        /*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       125873 :   if (value_dependent_expression_p (e))
    2443              :     /* Leave value-dependent expression alone for now. */
    2444              :     return e;
    2445              : 
    2446        65007 :   e = instantiate_non_dependent_expr (e);
    2447        65007 :   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        65007 :   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        64989 :   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   1811931685 : invalid_nonstatic_memfn_p (location_t loc, tree expr, tsubst_flags_t complain)
    2482              : {
    2483   1811931685 :   if (expr == NULL_TREE)
    2484              :     return false;
    2485              :   /* Don't enforce this in MS mode.  */
    2486   1811930248 :   if (flag_ms_extensions)
    2487              :     return false;
    2488   1811922187 :   if (is_overloaded_fn (expr) && !really_overloaded_fn (expr))
    2489    162032524 :     expr = get_first_fn (expr);
    2490   1811922187 :   if (TREE_TYPE (expr)
    2491   1811922187 :       && 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   4599038759 : is_bitfield_expr_with_lowered_type (const_tree exp)
    2517              : {
    2518   6302792670 :   switch (TREE_CODE (exp))
    2519              :     {
    2520      9341599 :     case COND_EXPR:
    2521     18683198 :       if (!is_bitfield_expr_with_lowered_type (TREE_OPERAND (exp, 1)
    2522      9341573 :                                                ? 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      1080140 :     case COMPOUND_EXPR:
    2528      1080140 :       return is_bitfield_expr_with_lowered_type (TREE_OPERAND (exp, 1));
    2529              : 
    2530    594697887 :     case MODIFY_EXPR:
    2531    594697887 :     case SAVE_EXPR:
    2532    594697887 :     case UNARY_PLUS_EXPR:
    2533    594697887 :     case PREDECREMENT_EXPR:
    2534    594697887 :     case PREINCREMENT_EXPR:
    2535    594697887 :     case POSTDECREMENT_EXPR:
    2536    594697887 :     case POSTINCREMENT_EXPR:
    2537    594697887 :     case NEGATE_EXPR:
    2538    594697887 :     case NON_LVALUE_EXPR:
    2539    594697887 :     case BIT_NOT_EXPR:
    2540    594697887 :     case CLEANUP_POINT_EXPR:
    2541    594697887 :       return is_bitfield_expr_with_lowered_type (TREE_OPERAND (exp, 0));
    2542              : 
    2543    448138799 :     case COMPONENT_REF:
    2544    448138799 :       {
    2545    448138799 :         tree field;
    2546              : 
    2547    448138799 :         field = TREE_OPERAND (exp, 1);
    2548    448138799 :         if (TREE_CODE (field) != FIELD_DECL || !DECL_BIT_FIELD_TYPE (field))
    2549              :           return NULL_TREE;
    2550    165664840 :         if (same_type_ignoring_top_level_qualifiers_p
    2551    165664840 :             (TREE_TYPE (exp), DECL_BIT_FIELD_TYPE (field)))
    2552              :           return NULL_TREE;
    2553    165497078 :         return DECL_BIT_FIELD_TYPE (field);
    2554              :       }
    2555              : 
    2556    832023507 :     case VAR_DECL:
    2557    832023507 :       if (DECL_HAS_VALUE_EXPR_P (exp))
    2558      4210332 :         return is_bitfield_expr_with_lowered_type (DECL_VALUE_EXPR
    2559      4210332 :                                                    (const_cast<tree> (exp)));
    2560              :       return NULL_TREE;
    2561              : 
    2562   1111239363 :     case VIEW_CONVERT_EXPR:
    2563   1111239363 :       if (location_wrapper_p (exp))
    2564   1103765411 :         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   2346887485 : unlowered_expr_type (const_tree exp)
    2579              : {
    2580   2346887485 :   tree type;
    2581   2346887485 :   tree etype = TREE_TYPE (exp);
    2582              : 
    2583   2346887485 :   type = is_bitfield_expr_with_lowered_type (exp);
    2584   2346887485 :   if (type)
    2585    143320783 :     type = cp_build_qualified_type (type, cp_type_quals (etype));
    2586              :   else
    2587              :     type = etype;
    2588              : 
    2589   2346887485 :   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   1398714334 : decay_conversion (tree exp,
    2606              :                   tsubst_flags_t complain,
    2607              :                   bool reject_builtin /* = true */)
    2608              : {
    2609   1398714334 :   tree type;
    2610   1398714334 :   enum tree_code code;
    2611   1398714334 :   location_t loc = cp_expr_loc_or_input_loc (exp);
    2612              : 
    2613   1398714334 :   type = TREE_TYPE (exp);
    2614   1398714334 :   if (type == error_mark_node)
    2615              :     return error_mark_node;
    2616              : 
    2617   1398714124 :   exp = resolve_nondeduced_context_or_error (exp, complain);
    2618              : 
    2619   1398714124 :   code = TREE_CODE (type);
    2620              : 
    2621   1398714124 :   if (error_operand_p (exp))
    2622           90 :     return error_mark_node;
    2623              : 
    2624   1398714034 :   if (NULLPTR_TYPE_P (type) && !TREE_SIDE_EFFECTS (exp))
    2625              :     {
    2626      1835948 :       mark_rvalue_use (exp, loc, reject_builtin);
    2627      1835948 :       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   1396878086 :   if (code == VOID_TYPE)
    2633              :     {
    2634         5760 :       if (complain & tf_error)
    2635            3 :         error_at (loc, "void value not ignored as it ought to be");
    2636         5760 :       return error_mark_node;
    2637              :     }
    2638   1396872326 :   if (invalid_nonstatic_memfn_p (loc, exp, complain))
    2639            6 :     return error_mark_node;
    2640   1396872320 :   if (code == FUNCTION_TYPE || is_overloaded_fn (exp))
    2641              :     {
    2642    168246777 :       exp = mark_lvalue_use (exp);
    2643    168246777 :       if (reject_builtin && reject_gcc_builtin (exp, loc))
    2644          109 :         return error_mark_node;
    2645    168246668 :       return cp_build_addr_expr (exp, complain);
    2646              :     }
    2647   1228625543 :   if (code == ARRAY_TYPE)
    2648              :     {
    2649      7616864 :       tree adr;
    2650      7616864 :       tree ptrtype;
    2651              : 
    2652      7616864 :       exp = mark_lvalue_use (exp);
    2653              : 
    2654      7616864 :       if (INDIRECT_REF_P (exp))
    2655       191427 :         return build_nop (build_pointer_type (TREE_TYPE (type)),
    2656       382854 :                           TREE_OPERAND (exp, 0));
    2657              : 
    2658      7425437 :       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      7425434 :       if (!obvalue_p (exp)
    2668      7425434 :           && ! (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      7425434 :       ptrtype = build_pointer_type (TREE_TYPE (type));
    2676              : 
    2677      7425434 :       if (VAR_P (exp))
    2678              :         {
    2679       630247 :           if (!cxx_mark_addressable (exp))
    2680            0 :             return error_mark_node;
    2681       630247 :           adr = build_nop (ptrtype, build_address (exp));
    2682       630247 :           return adr;
    2683              :         }
    2684              :       /* This way is better for a COMPONENT_REF since it can
    2685              :          simplify the offset for a component.  */
    2686      6795187 :       adr = cp_build_addr_expr (exp, complain);
    2687      6795187 :       return cp_convert (ptrtype, adr, complain);
    2688              :     }
    2689              : 
    2690              :   /* Otherwise, it's the lvalue-to-rvalue conversion.  */
    2691   1221008679 :   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   1221008679 :   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   1221008679 :   type = TREE_TYPE (exp);
    2709   1221008679 :   if (!CLASS_TYPE_P (type) && cv_qualified_p (type))
    2710    350319935 :     exp = build_nop (cv_unqualified (type), exp);
    2711              : 
    2712   1221008679 :   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    334685513 : cp_default_conversion (tree exp, tsubst_flags_t complain)
    2733              : {
    2734              :   /* Check for target-specific promotions.  */
    2735    334685513 :   tree promoted_type = targetm.promoted_type (TREE_TYPE (exp));
    2736    334685513 :   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    334685513 :   else if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (exp)))
    2742    230936539 :     exp = cp_perform_integral_promotions (exp, complain);
    2743              :   /* Perform the other conversions.  */
    2744    334685513 :   exp = decay_conversion (exp, complain);
    2745              : 
    2746    334685513 :   return exp;
    2747              : }
    2748              : 
    2749              : /* C version.  */
    2750              : 
    2751              : tree
    2752     40228600 : default_conversion (tree exp)
    2753              : {
    2754     40228600 :   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    240110698 : cp_perform_integral_promotions (tree expr, tsubst_flags_t complain)
    2763              : {
    2764    240110698 :   tree type;
    2765    240110698 :   tree promoted_type;
    2766              : 
    2767    240110698 :   expr = mark_rvalue_use (expr);
    2768    240110698 :   if (error_operand_p (expr))
    2769            6 :     return error_mark_node;
    2770              : 
    2771    240110692 :   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    240110692 :   tree bitfield_type = is_bitfield_expr_with_lowered_type (expr);
    2783    240110692 :   if (bitfield_type
    2784    240110692 :       && (TREE_CODE (bitfield_type) == ENUMERAL_TYPE
    2785      1095920 :           || TYPE_PRECISION (type) > TYPE_PRECISION (integer_type_node)))
    2786              :     type = bitfield_type;
    2787              : 
    2788    240110692 :   gcc_assert (INTEGRAL_OR_ENUMERATION_TYPE_P (type));
    2789              :   /* Scoped enums don't promote.  */
    2790    240110692 :   if (SCOPED_ENUM_P (type))
    2791              :     return expr;
    2792    236264628 :   promoted_type = type_promotes_to (type);
    2793    236264628 :   if (type != promoted_type)
    2794     77118577 :     expr = cp_convert (promoted_type, expr, complain);
    2795    159146051 :   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      4641984 : perform_integral_promotions (tree expr)
    2805              : {
    2806      4641984 :   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      4277649 : string_conv_p (const_tree totype, const_tree exp, int warn)
    2814              : {
    2815      4277649 :   tree t;
    2816              : 
    2817      4277649 :   if (!TYPE_PTR_P (totype))
    2818              :     return 0;
    2819              : 
    2820      4277178 :   t = TREE_TYPE (totype);
    2821      4277178 :   if (!same_type_p (t, char_type_node)
    2822      4116432 :       && !same_type_p (t, char8_type_node)
    2823      4048295 :       && !same_type_p (t, char16_type_node)
    2824      3990859 :       && !same_type_p (t, char32_type_node)
    2825      8210602 :       && !same_type_p (t, wchar_type_node))
    2826              :     return 0;
    2827              : 
    2828       417844 :   location_t loc = EXPR_LOC_OR_LOC (exp, input_location);
    2829              : 
    2830       417844 :   STRIP_ANY_LOCATION_WRAPPER (exp);
    2831              : 
    2832       417844 :   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       417736 :       t = build_pointer_type (cp_build_qualified_type (t, TYPE_QUAL_CONST));
    2842       417736 :       if (!same_type_p (TREE_TYPE (exp), t))
    2843              :         return 0;
    2844        13590 :       STRIP_NOPS (exp);
    2845        13590 :       if (TREE_CODE (exp) != ADDR_EXPR
    2846        13590 :           || 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       303379 : rationalize_conditional_expr (enum tree_code code, tree t,
    2874              :                               tsubst_flags_t complain)
    2875              : {
    2876       303379 :   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       303379 :   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       303379 :   tree op1 = TREE_OPERAND (t, 1);
    2905       303379 :   if (TREE_CODE (op1) != THROW_EXPR)
    2906       303376 :     op1 = cp_build_unary_op (code, op1, false, complain);
    2907       303379 :   tree op2 = TREE_OPERAND (t, 2);
    2908       303379 :   if (TREE_CODE (op2) != THROW_EXPR)
    2909       303373 :     op2 = cp_build_unary_op (code, op2, false, complain);
    2910              : 
    2911       303379 :   return
    2912       303379 :     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      2274163 : lookup_anon_field (tree, tree type)
    2922              : {
    2923      2274163 :   tree field;
    2924              : 
    2925      2274163 :   type = TYPE_MAIN_VARIANT (type);
    2926      2274163 :   field = ANON_AGGR_TYPE_FIELD (type);
    2927      2274163 :   gcc_assert (field);
    2928      2274163 :   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    147488340 : build_class_member_access_expr (cp_expr object, tree member,
    2945              :                                 tree access_path, bool preserve_reference,
    2946              :                                 tsubst_flags_t complain)
    2947              : {
    2948    147488340 :   tree object_type;
    2949    147488340 :   tree member_scope;
    2950    147488340 :   tree result = NULL_TREE;
    2951    147488340 :   tree using_decl = NULL_TREE;
    2952              : 
    2953    147488340 :   if (error_operand_p (object) || error_operand_p (member))
    2954           58 :     return error_mark_node;
    2955              : 
    2956    147488282 :   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    147488282 :   object_type = TREE_TYPE (object);
    2963    147488282 :   if (!currently_open_class (object_type)
    2964    147488282 :       && !complete_type_or_maybe_complain (object_type, object, complain))
    2965            0 :     return error_mark_node;
    2966    147488282 :   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    147488282 :   if (DECL_P (member))
    2986              :     {
    2987     67221853 :       member_scope = DECL_CLASS_CONTEXT (member);
    2988     67221853 :       if (!mark_used (member, complain) && !(complain & tf_error))
    2989            0 :         return error_mark_node;
    2990              : 
    2991     67221853 :       if (TREE_UNAVAILABLE (member))
    2992           30 :         error_unavailable_use (member, NULL_TREE);
    2993     67221823 :       else if (TREE_DEPRECATED (member))
    2994           30 :         warn_deprecated_use (member, NULL_TREE);
    2995              :     }
    2996              :   else
    2997     80266429 :     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    149766041 :   while ((ANON_AGGR_TYPE_P (member_scope) || UNSCOPED_ENUM_P (member_scope))
    3002    152044280 :          && !same_type_ignoring_top_level_qualifiers_p (member_scope,
    3003              :                                                         object_type))
    3004      2277759 :     member_scope = TYPE_CONTEXT (member_scope);
    3005    147488282 :   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    147488271 :   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    147488271 :   if (VAR_P (member))
    3032              :     {
    3033              :       /* A static data member.  */
    3034       342002 :       result = member;
    3035       342002 :       mark_exp_read (object);
    3036              : 
    3037       342002 :       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       342002 :       if (TREE_SIDE_EFFECTS (object))
    3044           58 :         result = build2 (COMPOUND_EXPR, TREE_TYPE (result), object, result);
    3045              :     }
    3046    147146269 :   else if (TREE_CODE (member) == FIELD_DECL)
    3047              :     {
    3048              :       /* A non-static data member.  */
    3049     66879636 :       bool null_object_p;
    3050     66879636 :       int type_quals;
    3051     66879636 :       tree member_type;
    3052              : 
    3053     66879636 :       if (INDIRECT_REF_P (object))
    3054     51005881 :         null_object_p =
    3055     51005881 :           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     66879636 :       if (!same_type_p (TYPE_MAIN_VARIANT (object_type),
    3061              :                         TYPE_MAIN_VARIANT (member_scope)))
    3062              :         {
    3063      2749485 :           tree binfo;
    3064      2749485 :           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      2749485 :           if (!cp_unevaluated_operand
    3070      2749020 :               && !dependent_type_p (object_type)
    3071      5222566 :               && !complete_type_or_maybe_complain (object_type, object,
    3072              :                                                    complain))
    3073           13 :             return error_mark_node;
    3074              : 
    3075      3588073 :           binfo = lookup_base (access_path ? access_path : object_type,
    3076              :                                member_scope, ba_unique, &kind, complain);
    3077      2749482 :           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      2749478 :           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      2749472 :           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      2749472 :           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    133759246 :       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     69154127 :           && (!same_type_ignoring_top_level_qualifiers_p
    3113      2274504 :               (TREE_TYPE (object), DECL_CONTEXT (member))))
    3114              :         {
    3115      2274030 :           tree anonymous_union;
    3116              : 
    3117      2274030 :           anonymous_union = lookup_anon_field (TREE_TYPE (object),
    3118      2274030 :                                                DECL_CONTEXT (member));
    3119      2274030 :           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     66879623 :       type_quals = TYPE_UNQUALIFIED;
    3128     66879623 :       member_type = TREE_TYPE (member);
    3129     66879623 :       if (!TYPE_REF_P (member_type))
    3130              :         {
    3131     63419023 :           type_quals = (cp_type_quals (member_type)
    3132     63419023 :                         | 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     63419023 :           if (DECL_MUTABLE_P (member))
    3138       312943 :             type_quals &= ~TYPE_QUAL_CONST;
    3139     63419023 :           member_type = cp_build_qualified_type (member_type, type_quals);
    3140              :         }
    3141              : 
    3142     66879623 :       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     66879623 :       if (type_quals & TYPE_QUAL_CONST)
    3149     21483167 :         TREE_READONLY (result) = 1;
    3150     66879623 :       if (type_quals & TYPE_QUAL_VOLATILE)
    3151       179513 :         TREE_THIS_VOLATILE (result) = 1;
    3152              :     }
    3153     80266633 :   else if (BASELINK_P (member))
    3154              :     {
    3155              :       /* The member is a (possibly overloaded) member function.  */
    3156     80266420 :       tree functions;
    3157     80266420 :       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     80266420 :       functions = BASELINK_FUNCTIONS (member);
    3163     80266420 :       if (TREE_CODE (functions) == OVERLOAD && OVL_SINGLE_P (functions))
    3164     80266420 :         functions = OVL_FIRST (functions);
    3165     80266420 :       if (TREE_CODE (functions) == FUNCTION_DECL
    3166     80266420 :           && DECL_STATIC_FUNCTION_P (functions))
    3167       644967 :         type = TREE_TYPE (functions);
    3168              :       else
    3169     79621453 :         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     80266420 :       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    147488246 :   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    139649680 :     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       296633 : lookup_destructor (tree object, tree scope, tree dtor_name,
    3211              :                    tsubst_flags_t complain)
    3212              : {
    3213       296633 :   tree object_type = TREE_TYPE (object);
    3214       296633 :   tree dtor_type = TREE_OPERAND (dtor_name, 0);
    3215       296633 :   tree expr;
    3216              : 
    3217              :   /* We've already complained about this destructor.  */
    3218       296633 :   if (dtor_type == error_mark_node)
    3219              :     return error_mark_node;
    3220              : 
    3221       296627 :   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       296624 :   if (is_auto (dtor_type))
    3229              :     dtor_type = object_type;
    3230       296621 :   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       296598 :   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       296614 :   expr = lookup_member (dtor_type, complete_dtor_identifier,
    3253              :                         /*protect=*/1, /*want_type=*/false,
    3254              :                         tf_warning_or_error);
    3255       296614 :   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       296608 :   expr = (adjust_result_of_qualified_name_lookup
    3262       296608 :           (expr, dtor_type, object_type));
    3263       296608 :   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       296465 :     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       245526 : 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       245526 :   if (TREE_CODE (decl) != TEMPLATE_DECL
    3296       245526 :       && TREE_CODE (decl) != TEMPLATE_ID_EXPR)
    3297              :     {
    3298        57143 :       if (VAR_P (decl))
    3299              :         {
    3300         9719 :           if (DECL_USE_TEMPLATE (decl)
    3301         9719 :               && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (decl)))
    3302              :             ;
    3303              :           else
    3304            0 :             permerror (input_location, "%qD is not a template", decl);
    3305              :         }
    3306        47424 :       else if (!is_overloaded_fn (decl))
    3307            0 :         permerror (input_location, "%qD is not a template", decl);
    3308              :       else
    3309              :         {
    3310        47424 :           bool found = false;
    3311              : 
    3312        94848 :           for (lkp_iterator iter (MAYBE_BASELINK_FUNCTIONS (decl));
    3313        94850 :                !found && iter; ++iter)
    3314              :             {
    3315        47426 :               tree fn = *iter;
    3316        47426 :               if (TREE_CODE (fn) == TEMPLATE_DECL
    3317        47030 :                   || TREE_CODE (fn) == TEMPLATE_ID_EXPR
    3318        47440 :                   || (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        47424 :           if (!found)
    3324           12 :             permerror (input_location, "%qD is not a template", decl);
    3325              :         }
    3326              :     }
    3327       245526 : }
    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    107035183 : access_failure_info::get_any_accessor (bool const_p) const
    3348              : {
    3349    107035183 :   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    107035113 : access_failure_info::maybe_suggest_accessor (bool const_p) const
    3384              : {
    3385    107035113 :   tree accessor = get_any_accessor (const_p);
    3386    107035113 :   if (accessor == NULL_TREE)
    3387    107035015 :     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    207053241 : 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    207053241 :   tree expr;
    3483    207053241 :   tree object_type;
    3484    207053241 :   tree member;
    3485    207053241 :   tree access_path = NULL_TREE;
    3486    207053241 :   tree orig_object = object;
    3487    207053241 :   tree orig_name = name;
    3488              : 
    3489    207053241 :   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    207052764 :   if (!objc_is_public (object, name))
    3494            0 :     return error_mark_node;
    3495              : 
    3496    207052764 :   object_type = TREE_TYPE (object);
    3497              : 
    3498    207052764 :   if (processing_template_decl)
    3499              :     {
    3500    154924758 :       if (/* If OBJECT is dependent, so is OBJECT.NAME.  */
    3501    154924758 :           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     73046643 :           || (TREE_CODE (name) == TEMPLATE_ID_EXPR
    3505       570342 :               && dependent_template_id_p (TREE_OPERAND (name, 0),
    3506       570342 :                                           TREE_OPERAND (name, 1)))
    3507              :           /* If NAME is "T::X" where "T" is dependent, then the
    3508              :              expression is dependent.  */
    3509     72767085 :           || (TREE_CODE (name) == SCOPE_REF
    3510       102957 :               && TYPE_P (TREE_OPERAND (name, 0))
    3511       102957 :               && 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     72664342 :           || (TREE_CODE (name) == IDENTIFIER_NODE
    3515     72037523 :               && IDENTIFIER_CONV_OP_P (name)
    3516           44 :               && dependent_type_p (TREE_TYPE (name)))
    3517              :           /* This is OBJECT.[:R:], which is dependent.  */
    3518     72664304 :           || dependent_splice_p (name)
    3519              :           /* This is OBJECT.[:T::R:], which is dependent.  */
    3520    227588862 :           || (TREE_CODE (name) == SCOPE_REF
    3521          214 :               && dependent_splice_p (TREE_OPERAND (name, 1))))
    3522              :         {
    3523     96577243 :         dependent:
    3524     96577243 :           expr = build_min_nt_loc (UNKNOWN_LOCATION, COMPONENT_REF,
    3525              :                                    orig_object, orig_name, NULL_TREE);
    3526     96577243 :           COMPONENT_REF_SPLICE_P (expr) = splice_p;
    3527     96577243 :           return expr;
    3528              :         }
    3529              :     }
    3530     52128006 :   else if (c_dialect_objc ()
    3531    124792110 :            && identifier_p (name)
    3532     52128006 :            && (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    124792110 :   if (!currently_open_class (object_type)
    3540    124792110 :       && !complete_type_or_maybe_complain (object_type, object, complain))
    3541           68 :     return error_mark_node;
    3542    124792042 :   if (!CLASS_TYPE_P (object_type))
    3543              :     {
    3544       275715 :       if (complain & tf_error)
    3545              :         {
    3546          125 :           if (INDIRECT_TYPE_P (object_type)
    3547          125 :               && 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          103 :             error ("request for member %qD in %qE, which is of non-class "
    3553              :                    "type %qT", name, object.get_value (), object_type);
    3554              :         }
    3555       275715 :       return error_mark_node;
    3556              :     }
    3557              : 
    3558    124516327 :   if (BASELINK_P (name))
    3559              :     /* A member function that has already been looked up.  */
    3560              :     member = name;
    3561    107378619 :   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    107378573 :       bool is_template_id = false;
    3574    107378573 :       tree template_args = NULL_TREE;
    3575    107378573 :       tree scope = NULL_TREE;
    3576              : 
    3577    107378573 :       access_path = object_type;
    3578              : 
    3579    107378573 :       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         1756 :           scope = TREE_OPERAND (name, 0);
    3585         1756 :           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         1756 :           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    107376817 :       else if (splice_p
    3598    107376817 :                && (TREE_CODE (name) == FIELD_DECL
    3599              :                    || VAR_P (name)
    3600          892 :                    || TREE_CODE (name) == CONST_DECL
    3601          776 :                    || TREE_CODE (name) == FUNCTION_DECL
    3602         1042 :                    || DECL_FUNCTION_TEMPLATE_P (OVL_FIRST (name))))
    3603          660 :         scope = context_for_name_lookup (OVL_FIRST (name));
    3604              : 
    3605    107378573 :       if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
    3606              :         {
    3607       556223 :           is_template_id = true;
    3608       556223 :           template_args = TREE_OPERAND (name, 1);
    3609       556223 :           name = TREE_OPERAND (name, 0);
    3610              : 
    3611       556223 :           if (splice_p
    3612       556919 :               && (DECL_FUNCTION_TEMPLATE_P (OVL_FIRST (name))
    3613           69 :                   || variable_template_p (name)))
    3614          232 :             scope = DECL_CONTEXT (OVL_FIRST (name));
    3615       961182 :           else if (!identifier_p (name))
    3616       405229 :             name = OVL_NAME (name);
    3617              :         }
    3618              : 
    3619    107378573 :       if (scope)
    3620              :         {
    3621         2648 :           if (TREE_CODE (scope) == ENUMERAL_TYPE)
    3622              :             {
    3623           12 :               gcc_assert (!is_template_id);
    3624              :               /* Looking up a member enumerator (c++/56793).  */
    3625           24 :               if (!TYPE_CLASS_SCOPE_P (scope)
    3626           21 :                   || !DERIVED_FROM_P (TYPE_CONTEXT (scope), object_type))
    3627              :                 {
    3628            3 :                   if (complain & tf_error)
    3629            3 :                     error ("%<%D::%D%> is not a member of %qT",
    3630              :                            scope, name, object_type);
    3631            3 :                   return error_mark_node;
    3632              :                 }
    3633            9 :               tree val;
    3634            9 :               if (splice_p && TREE_CODE (name) == CONST_DECL)
    3635              :                 val = name;
    3636              :               else
    3637            9 :                 val = lookup_enumerator (scope, name);
    3638            9 :               if (!val)
    3639              :                 {
    3640            6 :                   if (complain & tf_error)
    3641            6 :                     error ("%qD is not a member of %qD",
    3642              :                            name, scope);
    3643            6 :                   return error_mark_node;
    3644              :                 }
    3645              : 
    3646            3 :               if (TREE_SIDE_EFFECTS (object))
    3647            0 :                 val = build2 (COMPOUND_EXPR, TREE_TYPE (val), object, val);
    3648            3 :               return val;
    3649              :             }
    3650              : 
    3651         2636 :           gcc_assert (CLASS_TYPE_P (scope));
    3652         4142 :           gcc_assert (identifier_p (name)
    3653              :                       || TREE_CODE (name) == BIT_NOT_EXPR
    3654              :                       || (splice_p
    3655              :                           && (TREE_CODE (name) == FIELD_DECL
    3656              :                               || VAR_P (name)
    3657              :                               || TREE_CODE (name) == CONST_DECL
    3658              :                               || TREE_CODE (name) == FUNCTION_DECL
    3659              :                               || DECL_FUNCTION_TEMPLATE_P
    3660              :                                                 (OVL_FIRST (name))
    3661              :                               || variable_template_p (name))));
    3662              : 
    3663         2636 :           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         7899 :           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         2633 :               if (splice_p)
    3681              :                 return ba_unique;
    3682         1741 :               if (identifier_p (name))
    3683              :                 {
    3684         1604 :                   tree m = lookup_member (scope, name, /*protect=*/0,
    3685              :                                           /*want_type=*/false, tf_none);
    3686         1604 :                   if (!m || shared_member_p (m))
    3687           32 :                     return ba_any;
    3688              :                 }
    3689              :               return ba_check;
    3690         2633 :             } ();
    3691              : 
    3692              :           /* Find the base of OBJECT_TYPE corresponding to SCOPE.  */
    3693         2633 :           access_path = lookup_base (object_type, scope, ba, NULL, complain);
    3694         2633 :           if (access_path == error_mark_node)
    3695              :             return error_mark_node;
    3696         2612 :           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    107378513 :       if (TREE_CODE (name) == BIT_NOT_EXPR)
    3707              :         {
    3708       342529 :           if (dependent_type_p (object_type))
    3709              :             /* The destructor isn't declared yet.  */
    3710        45911 :             goto dependent;
    3711       296618 :           member = lookup_destructor (object, scope, name, complain);
    3712              :         }
    3713    107035984 :       else if (splice_p && (TREE_CODE (name) == FIELD_DECL
    3714              :                             || VAR_P (name)
    3715          871 :                             || TREE_CODE (name) == CONST_DECL
    3716          776 :                             || TREE_CODE (name) == FUNCTION_DECL
    3717         1506 :                             || DECL_FUNCTION_TEMPLATE_P (OVL_FIRST (name))
    3718           69 :                             || variable_template_p (name)))
    3719              :         {
    3720         1304 :           member = name;
    3721          871 :           name = OVL_FIRST (name);
    3722          871 :           if (any_dependent_type_attributes_p (DECL_ATTRIBUTES (name)))
    3723              :             /* Dependent type attributes on the decl mean that the TREE_TYPE is
    3724              :                wrong, so don't use it.  */
    3725            0 :             goto dependent;
    3726          871 :           if (is_overloaded_fn (name))
    3727          707 :             member
    3728          707 :               = build_baselink (access_path, TYPE_BINFO (object_type), member,
    3729          707 :                                 IDENTIFIER_CONV_OP_P (DECL_NAME (name))
    3730            0 :                                 ? TREE_TYPE (DECL_NAME (name)) : NULL_TREE);
    3731              :         }
    3732              :       else
    3733              :         {
    3734              :           /* Look up the member.  */
    3735    107035113 :           {
    3736    107035113 :             auto_diagnostic_group d;
    3737    107035113 :             access_failure_info afi;
    3738    107035113 :             if (processing_template_decl)
    3739              :               /* Even though this class member access expression is at this
    3740              :                  point not dependent, the member itself may be dependent, and
    3741              :                  we must not potentially push a access check for a dependent
    3742              :                  member onto TI_DEFERRED_ACCESS_CHECKS.  So don't check access
    3743              :                  ahead of time here; we're going to redo this member lookup at
    3744              :                  instantiation time anyway.  */
    3745     72328386 :               push_deferring_access_checks (dk_no_check);
    3746    107035113 :             member = lookup_member (access_path, name, /*protect=*/1,
    3747              :                                     /*want_type=*/false, complain,
    3748              :                                     &afi);
    3749    107035113 :             if (processing_template_decl)
    3750     72328386 :               pop_deferring_access_checks ();
    3751    107035113 :             afi.maybe_suggest_accessor (TYPE_READONLY (object_type));
    3752    107035113 :           }
    3753    107035113 :           if (member == NULL_TREE)
    3754              :             {
    3755      9006815 :               if (dependentish_scope_p (object_type))
    3756              :                 /* Try again at instantiation time.  */
    3757      8960164 :                 goto dependent;
    3758        46651 :               if (complain & tf_error)
    3759          315 :                 complain_about_unrecognized_member (access_path, name,
    3760              :                                                     object_type);
    3761        46651 :               return error_mark_node;
    3762              :             }
    3763     98028298 :           if (member == error_mark_node)
    3764              :             return error_mark_node;
    3765     98028253 :           if (DECL_P (member)
    3766     98028253 :               && any_dependent_type_attributes_p (DECL_ATTRIBUTES (member)))
    3767              :             /* Dependent type attributes on the decl mean that the TREE_TYPE is
    3768              :                wrong, so don't use it.  */
    3769            6 :             goto dependent;
    3770     98028247 :           if (TREE_CODE (member) == USING_DECL && DECL_DEPENDENT_P (member))
    3771      5310502 :             goto dependent;
    3772              :         }
    3773              : 
    3774     93015234 :       if (is_template_id)
    3775              :         {
    3776       556213 :           tree templ = member;
    3777              : 
    3778       556213 :           if (BASELINK_P (templ))
    3779       556092 :             member = lookup_template_function (templ, template_args);
    3780          121 :           else if (variable_template_p (templ))
    3781          121 :             member = (lookup_and_finish_template_variable
    3782          121 :                       (templ, template_args, complain));
    3783              :           else
    3784              :             {
    3785            0 :               if (complain & tf_error)
    3786            0 :                 error ("%qD is not a member template function", name);
    3787            0 :               return error_mark_node;
    3788              :             }
    3789              :         }
    3790              :     }
    3791              : 
    3792    110152942 :   if (TREE_UNAVAILABLE (member))
    3793           30 :     error_unavailable_use (member, NULL_TREE);
    3794    110152912 :   else if (TREE_DEPRECATED (member))
    3795           30 :     warn_deprecated_use (member, NULL_TREE);
    3796              : 
    3797    110152942 :   if (template_p)
    3798         9173 :     check_template_keyword (member);
    3799              : 
    3800    110152942 :   expr = build_class_member_access_expr (object, member, access_path,
    3801              :                                          /*preserve_reference=*/false,
    3802              :                                          complain);
    3803    110152942 :   if (processing_template_decl && expr != error_mark_node)
    3804              :     {
    3805     58347433 :       if (BASELINK_P (member))
    3806              :         {
    3807     43553027 :           if (TREE_CODE (orig_name) == SCOPE_REF)
    3808          169 :             BASELINK_QUALIFIED_P (member) = 1;
    3809              :           orig_name = member;
    3810              :         }
    3811     58347433 :       expr = build_min_non_dep (COMPONENT_REF, expr,
    3812              :                                 orig_object, orig_name,
    3813              :                                 NULL_TREE);
    3814    116694866 :       COMPONENT_REF_SPLICE_P (STRIP_REFERENCE_REF (expr)) = splice_p;
    3815              :     }
    3816              : 
    3817              :   return expr;
    3818              : }
    3819              : 
    3820              : /* Build a COMPONENT_REF of OBJECT and MEMBER with the appropriate
    3821              :    type.  */
    3822              : 
    3823              : tree
    3824       167063 : build_simple_component_ref (tree object, tree member)
    3825              : {
    3826       167063 :   tree type = cp_build_qualified_type (TREE_TYPE (member),
    3827       167063 :                                        cp_type_quals (TREE_TYPE (object)));
    3828       167063 :   return build3_loc (input_location,
    3829              :                      COMPONENT_REF, type,
    3830       167063 :                      object, member, NULL_TREE);
    3831              : }
    3832              : 
    3833              : /* Return an expression for the MEMBER_NAME field in the internal
    3834              :    representation of PTRMEM, a pointer-to-member function.  (Each
    3835              :    pointer-to-member function type gets its own RECORD_TYPE so it is
    3836              :    more convenient to access the fields by name than by FIELD_DECL.)
    3837              :    This routine converts the NAME to a FIELD_DECL and then creates the
    3838              :    node for the complete expression.  */
    3839              : 
    3840              : tree
    3841       166967 : build_ptrmemfunc_access_expr (tree ptrmem, tree member_name)
    3842              : {
    3843       166967 :   tree ptrmem_type;
    3844       166967 :   tree member;
    3845              : 
    3846       166967 :   if (TREE_CODE (ptrmem) == CONSTRUCTOR)
    3847              :     {
    3848          198 :       for (auto &e: CONSTRUCTOR_ELTS (ptrmem))
    3849           78 :         if (e.index && DECL_P (e.index) && DECL_NAME (e.index) == member_name)
    3850           60 :           return e.value;
    3851            0 :       gcc_unreachable ();
    3852              :     }
    3853              : 
    3854              :   /* This code is a stripped down version of
    3855              :      build_class_member_access_expr.  It does not work to use that
    3856              :      routine directly because it expects the object to be of class
    3857              :      type.  */
    3858       166907 :   ptrmem_type = TREE_TYPE (ptrmem);
    3859       166907 :   gcc_assert (TYPE_PTRMEMFUNC_P (ptrmem_type));
    3860       250259 :   for (member = TYPE_FIELDS (ptrmem_type); member;
    3861        83352 :        member = DECL_CHAIN (member))
    3862       250259 :     if (DECL_NAME (member) == member_name)
    3863              :       break;
    3864       166907 :   return build_simple_component_ref (ptrmem, member);
    3865              : }
    3866              : 
    3867              : /* Return a TREE_LIST of namespace-scope overloads for the given operator,
    3868              :    and for any other relevant operator.  */
    3869              : 
    3870              : static tree
    3871    134600655 : op_unqualified_lookup (tree_code code, bool is_assign)
    3872              : {
    3873    134600655 :   tree lookups = NULL_TREE;
    3874              : 
    3875    134600655 :   if (cxx_dialect >= cxx20 && !is_assign)
    3876              :     {
    3877    127336734 :       if (code == NE_EXPR)
    3878              :         {
    3879              :           /* != can get rewritten in terms of ==.  */
    3880      8194860 :           tree fnname = ovl_op_identifier (false, EQ_EXPR);
    3881      8194860 :           if (tree fns = lookup_name (fnname, LOOK_where::BLOCK_NAMESPACE))
    3882      8098254 :             lookups = tree_cons (fnname, fns, lookups);
    3883              :         }
    3884    119141874 :       else if (code == GT_EXPR || code == LE_EXPR
    3885    119141874 :                || code == LT_EXPR || code == GE_EXPR)
    3886              :         {
    3887              :           /* These can get rewritten in terms of <=>.  */
    3888     11095052 :           tree fnname = ovl_op_identifier (false, SPACESHIP_EXPR);
    3889     11095052 :           if (tree fns = lookup_name (fnname, LOOK_where::BLOCK_NAMESPACE))
    3890     10509177 :             lookups = tree_cons (fnname, fns, lookups);
    3891              :         }
    3892              :     }
    3893              : 
    3894    134600655 :   tree fnname = ovl_op_identifier (is_assign, code);
    3895    134600655 :   if (tree fns = lookup_name (fnname, LOOK_where::BLOCK_NAMESPACE))
    3896     73516440 :     lookups = tree_cons (fnname, fns, lookups);
    3897              : 
    3898    134600655 :   if (lookups)
    3899              :     return lookups;
    3900              :   else
    3901     60861774 :     return build_tree_list (NULL_TREE, NULL_TREE);
    3902              : }
    3903              : 
    3904              : /* Create a DEPENDENT_OPERATOR_TYPE for a dependent operator expression of
    3905              :    the given operator.  LOOKUPS, if non-NULL, is the result of phase 1
    3906              :    name lookup for the given operator.  */
    3907              : 
    3908              : tree
    3909    140818993 : build_dependent_operator_type (tree lookups, tree_code code, bool is_assign)
    3910              : {
    3911    140818993 :   if (lookups)
    3912              :     /* We're partially instantiating a dependent operator expression, and
    3913              :        LOOKUPS is the result of phase 1 name lookup that we performed
    3914              :        earlier at template definition time, so just reuse the corresponding
    3915              :        DEPENDENT_OPERATOR_TYPE.  */
    3916      6218338 :     return TREE_TYPE (lookups);
    3917              : 
    3918              :   /* Otherwise we're processing a dependent operator expression at template
    3919              :      definition time, so perform phase 1 name lookup now.  */
    3920    134600655 :   lookups = op_unqualified_lookup (code, is_assign);
    3921              : 
    3922    134600655 :   tree type = cxx_make_type (DEPENDENT_OPERATOR_TYPE);
    3923    134600655 :   DEPENDENT_OPERATOR_TYPE_SAVED_LOOKUPS (type) = lookups;
    3924    134600655 :   TREE_TYPE (lookups) = type;
    3925    134600655 :   return type;
    3926              : }
    3927              : 
    3928              : /* Given an expression PTR for a pointer, return an expression
    3929              :    for the value pointed to.
    3930              :    ERRORSTRING is the name of the operator to appear in error messages.
    3931              : 
    3932              :    This function may need to overload OPERATOR_FNNAME.
    3933              :    Must also handle REFERENCE_TYPEs for C++.  */
    3934              : 
    3935              : tree
    3936     62317439 : build_x_indirect_ref (location_t loc, tree expr, ref_operator errorstring,
    3937              :                       tree lookups, tsubst_flags_t complain)
    3938              : {
    3939     62317439 :   tree orig_expr = expr;
    3940     62317439 :   tree rval;
    3941     62317439 :   tree overload = NULL_TREE;
    3942              : 
    3943     62317439 :   if (processing_template_decl)
    3944              :     {
    3945              :       /* Retain the type if we know the operand is a pointer.  */
    3946     28472101 :       if (TREE_TYPE (expr) && INDIRECT_TYPE_P (TREE_TYPE (expr)))
    3947              :         {
    3948     13961020 :           if (expr == current_class_ptr
    3949     13961020 :               || (TREE_CODE (expr) == NOP_EXPR
    3950      9112482 :                   && TREE_OPERAND (expr, 0) == current_class_ptr
    3951      9103335 :                   && (same_type_ignoring_top_level_qualifiers_p
    3952      9103335 :                         (TREE_TYPE (expr), TREE_TYPE (current_class_ptr)))))
    3953      9103334 :             return current_class_ref;
    3954      4857686 :           return build_min (INDIRECT_REF, TREE_TYPE (TREE_TYPE (expr)), expr);
    3955              :         }
    3956     14511081 :       if (type_dependent_expression_p (expr))
    3957              :         {
    3958     14359516 :           expr = build_min_nt_loc (loc, INDIRECT_REF, expr);
    3959     14359516 :           TREE_TYPE (expr)
    3960     14359516 :             = build_dependent_operator_type (lookups, INDIRECT_REF, false);
    3961     14359516 :           return expr;
    3962              :         }
    3963              :     }
    3964              : 
    3965     33996903 :   rval = build_new_op (loc, INDIRECT_REF, LOOKUP_NORMAL, expr,
    3966              :                        NULL_TREE, NULL_TREE, lookups,
    3967              :                        &overload, complain);
    3968     33996903 :   if (!rval)
    3969            0 :     rval = cp_build_indirect_ref (loc, expr, errorstring, complain);
    3970              : 
    3971     33996903 :   if (processing_template_decl && rval != error_mark_node)
    3972              :     {
    3973       149732 :       if (overload != NULL_TREE)
    3974       149701 :         return (build_min_non_dep_op_overload
    3975       149701 :                 (INDIRECT_REF, rval, overload, orig_expr));
    3976              : 
    3977           31 :       return build_min_non_dep (INDIRECT_REF, rval, orig_expr);
    3978              :     }
    3979              :   else
    3980              :     return rval;
    3981              : }
    3982              : 
    3983              : /* Like c-family strict_aliasing_warning, but don't warn for dependent
    3984              :    types or expressions.  */
    3985              : 
    3986              : static bool
    3987       622502 : cp_strict_aliasing_warning (location_t loc, tree type, tree expr)
    3988              : {
    3989       622502 :   if (processing_template_decl)
    3990              :     {
    3991        41583 :       tree e = expr;
    3992        41583 :       STRIP_NOPS (e);
    3993        41583 :       if (dependent_type_p (type) || type_dependent_expression_p (e))
    3994         6786 :         return false;
    3995              :     }
    3996       615716 :   return strict_aliasing_warning (loc, type, expr);
    3997              : }
    3998              : 
    3999              : /* The implementation of the above, and of indirection implied by other
    4000              :    constructs.  If DO_FOLD is true, fold away INDIRECT_REF of ADDR_EXPR.  */
    4001              : 
    4002              : static tree
    4003    414956476 : cp_build_indirect_ref_1 (location_t loc, tree ptr, ref_operator errorstring,
    4004              :                          tsubst_flags_t complain, bool do_fold)
    4005              : {
    4006    414956476 :   tree pointer, type;
    4007              : 
    4008              :   /* RO_NULL should only be used with the folding entry points below, not
    4009              :      cp_build_indirect_ref.  */
    4010    414956476 :   gcc_checking_assert (errorstring != RO_NULL || do_fold);
    4011              : 
    4012    414956476 :   if (ptr == current_class_ptr
    4013    414956476 :       || (TREE_CODE (ptr) == NOP_EXPR
    4014     54705783 :           && TREE_OPERAND (ptr, 0) == current_class_ptr
    4015     31939933 :           && (same_type_ignoring_top_level_qualifiers_p
    4016     31939933 :               (TREE_TYPE (ptr), TREE_TYPE (current_class_ptr)))))
    4017     34061983 :     return current_class_ref;
    4018              : 
    4019    380894493 :   pointer = (TYPE_REF_P (TREE_TYPE (ptr))
    4020    380894493 :              ? ptr : decay_conversion (ptr, complain));
    4021    380894493 :   if (pointer == error_mark_node)
    4022              :     return error_mark_node;
    4023              : 
    4024    380888672 :   type = TREE_TYPE (pointer);
    4025              : 
    4026    380888672 :   if (INDIRECT_TYPE_P (type))
    4027              :     {
    4028              :       /* [expr.unary.op]
    4029              : 
    4030              :          If the type of the expression is "pointer to T," the type
    4031              :          of  the  result  is  "T."  */
    4032    380888150 :       tree t = TREE_TYPE (type);
    4033              : 
    4034    356691165 :       if ((CONVERT_EXPR_P (ptr)
    4035    238816768 :            || TREE_CODE (ptr) == VIEW_CONVERT_EXPR)
    4036    501993592 :           && (!CLASS_TYPE_P (t) || !CLASSTYPE_EMPTY_P (t)))
    4037              :         {
    4038              :           /* If a warning is issued, mark it to avoid duplicates from
    4039              :              the backend.  This only needs to be done at
    4040              :              warn_strict_aliasing > 2.  */
    4041    117576769 :           if (warn_strict_aliasing > 2
    4042    118101090 :               && cp_strict_aliasing_warning (EXPR_LOCATION (ptr),
    4043       524321 :                                              type, TREE_OPERAND (ptr, 0)))
    4044            6 :             suppress_warning (ptr, OPT_Wstrict_aliasing);
    4045              :         }
    4046              : 
    4047    380888150 :       if (VOID_TYPE_P (t))
    4048              :         {
    4049              :           /* A pointer to incomplete type (other than cv void) can be
    4050              :              dereferenced [expr.unary.op]/1  */
    4051           47 :           if (complain & tf_error)
    4052           19 :             error_at (loc, "%qT is not a pointer-to-object type", type);
    4053           47 :           return error_mark_node;
    4054              :         }
    4055    366838847 :       else if (do_fold && TREE_CODE (pointer) == ADDR_EXPR
    4056    391040178 :                && same_type_p (t, TREE_TYPE (TREE_OPERAND (pointer, 0))))
    4057              :         /* The POINTER was something like `&x'.  We simplify `*&x' to
    4058              :            `x'.  This can change the value category: '*&TARGET_EXPR'
    4059              :            is an lvalue and folding it into 'TARGET_EXPR' turns it into
    4060              :            a prvalue of class type.  */
    4061     10152032 :         return TREE_OPERAND (pointer, 0);
    4062              :       else
    4063              :         {
    4064    370736071 :           tree ref = build1 (INDIRECT_REF, t, pointer);
    4065              : 
    4066              :           /* We *must* set TREE_READONLY when dereferencing a pointer to const,
    4067              :              so that we get the proper error message if the result is used
    4068              :              to assign to.  Also, &* is supposed to be a no-op.  */
    4069    370736071 :           TREE_READONLY (ref) = CP_TYPE_CONST_P (t);
    4070    370736071 :           TREE_THIS_VOLATILE (ref) = CP_TYPE_VOLATILE_P (t);
    4071    370736071 :           TREE_SIDE_EFFECTS (ref)
    4072    370736071 :             = (TREE_THIS_VOLATILE (ref) || TREE_SIDE_EFFECTS (pointer));
    4073    370736071 :           return ref;
    4074              :         }
    4075              :     }
    4076          522 :   else if (!(complain & tf_error))
    4077              :     /* Don't emit any errors; we'll just return ERROR_MARK_NODE later.  */
    4078              :     ;
    4079              :   /* `pointer' won't be an error_mark_node if we were given a
    4080              :      pointer to member, so it's cool to check for this here.  */
    4081           40 :   else if (TYPE_PTRMEM_P (type))
    4082           15 :     switch (errorstring)
    4083              :       {
    4084            0 :          case RO_ARRAY_INDEXING:
    4085            0 :            error_at (loc,
    4086              :                      "invalid use of array indexing on pointer to member");
    4087            0 :            break;
    4088           12 :          case RO_UNARY_STAR:
    4089           12 :            error_at (loc, "invalid use of unary %<*%> on pointer to member");
    4090           12 :            break;
    4091            0 :          case RO_IMPLICIT_CONVERSION:
    4092            0 :            error_at (loc, "invalid use of implicit conversion on pointer "
    4093              :                      "to member");
    4094            0 :            break;
    4095            3 :          case RO_ARROW_STAR:
    4096            3 :            error_at (loc, "left hand operand of %<->*%> must be a pointer to "
    4097              :                      "class, but is a pointer to member of type %qT", type);
    4098            3 :            break;
    4099            0 :          default:
    4100            0 :            gcc_unreachable ();
    4101              :       }
    4102           25 :   else if (pointer != error_mark_node)
    4103           25 :     invalid_indirection_error (loc, type, errorstring);
    4104              : 
    4105          522 :   return error_mark_node;
    4106              : }
    4107              : 
    4108              : /* Entry point used by c-common, which expects folding.  */
    4109              : 
    4110              : tree
    4111        67360 : build_indirect_ref (location_t loc, tree ptr, ref_operator errorstring)
    4112              : {
    4113        67360 :   return cp_build_indirect_ref_1 (loc, ptr, errorstring,
    4114        67360 :                                   tf_warning_or_error, true);
    4115              : }
    4116              : 
    4117              : /* Entry point used by internal indirection needs that don't correspond to any
    4118              :    syntactic construct.  */
    4119              : 
    4120              : tree
    4121    371256536 : cp_build_fold_indirect_ref (tree pointer)
    4122              : {
    4123    371256536 :   return cp_build_indirect_ref_1 (input_location, pointer, RO_NULL,
    4124    371256536 :                                   tf_warning_or_error, true);
    4125              : }
    4126              : 
    4127              : /* Entry point used by indirection needs that correspond to some syntactic
    4128              :    construct.  */
    4129              : 
    4130              : tree
    4131     43632580 : cp_build_indirect_ref (location_t loc, tree ptr, ref_operator errorstring,
    4132              :                        tsubst_flags_t complain)
    4133              : {
    4134     43632580 :   return cp_build_indirect_ref_1 (loc, ptr, errorstring, complain, false);
    4135              : }
    4136              : 
    4137              : /* This handles expressions of the form "a[i]", which denotes
    4138              :    an array reference.
    4139              : 
    4140              :    This is logically equivalent in C to *(a+i), but we may do it differently.
    4141              :    If A is a variable or a member, we generate a primitive ARRAY_REF.
    4142              :    This avoids forcing the array out of registers, and can work on
    4143              :    arrays that are not lvalues (for example, members of structures returned
    4144              :    by functions).
    4145              : 
    4146              :    If INDEX is of some user-defined type, it must be converted to
    4147              :    integer type.  Otherwise, to make a compatible PLUS_EXPR, it
    4148              :    will inherit the type of the array, which will be some pointer type.
    4149              : 
    4150              :    LOC is the location to use in building the array reference.  */
    4151              : 
    4152              : tree
    4153      6536108 : cp_build_array_ref (location_t loc, tree array, tree idx,
    4154              :                     tsubst_flags_t complain)
    4155              : {
    4156      6536108 :   tree ret;
    4157              : 
    4158      6536108 :   if (idx == 0)
    4159              :     {
    4160            0 :       if (complain & tf_error)
    4161            0 :         error_at (loc, "subscript missing in array reference");
    4162            0 :       return error_mark_node;
    4163              :     }
    4164              : 
    4165      6536108 :   if (TREE_TYPE (array) == error_mark_node
    4166      6536108 :       || TREE_TYPE (idx) == error_mark_node)
    4167              :     return error_mark_node;
    4168              : 
    4169              :   /* 0[array] */
    4170      6536108 :   if (TREE_CODE (TREE_TYPE (idx)) == ARRAY_TYPE)
    4171              :     {
    4172           10 :       std::swap (array, idx);
    4173              : 
    4174           10 :       tree first = NULL_TREE;
    4175           10 :       if (flag_strong_eval_order == 2 && TREE_SIDE_EFFECTS (array))
    4176            9 :         idx = first = save_expr (idx);
    4177           10 :       ret = cp_build_array_ref (loc, array, idx, complain);
    4178              : 
    4179           10 :       if (first)
    4180            9 :         ret = build2 (COMPOUND_EXPR, TREE_TYPE (ret), first, ret);
    4181           10 :       return ret;
    4182              :     }
    4183              : 
    4184              :   /* If ARRAY is a COMPOUND_EXPR or COND_EXPR, move our reference
    4185              :      inside it.  */
    4186      6536098 :   switch (TREE_CODE (array))
    4187              :     {
    4188           28 :     case COMPOUND_EXPR:
    4189           28 :       {
    4190           28 :         tree value = cp_build_array_ref (loc, TREE_OPERAND (array, 1), idx,
    4191              :                                          complain);
    4192           28 :         ret = build2 (COMPOUND_EXPR, TREE_TYPE (value),
    4193           28 :                       TREE_OPERAND (array, 0), value);
    4194           28 :         SET_EXPR_LOCATION (ret, loc);
    4195           28 :         return ret;
    4196              :       }
    4197              : 
    4198           73 :     case COND_EXPR:
    4199           73 :       tree op0, op1, op2;
    4200           73 :       op0 = TREE_OPERAND (array, 0);
    4201           73 :       op1 = TREE_OPERAND (array, 1);
    4202           73 :       op2 = TREE_OPERAND (array, 2);
    4203           73 :       if (TREE_SIDE_EFFECTS (idx) || !tree_invariant_p (idx))
    4204              :         {
    4205              :           /* If idx could possibly have some SAVE_EXPRs, turning
    4206              :              (op0 ? op1 : op2)[idx] into
    4207              :              op0 ? op1[idx] : op2[idx] can lead into temporaries
    4208              :              initialized in one conditional path and uninitialized
    4209              :              uses of them in the other path.
    4210              :              And if idx is a really large expression, evaluating it
    4211              :              twice is also not optimal.
    4212              :              On the other side, op0 must be sequenced before evaluation
    4213              :              of op1 and op2 and for C++17 op0, op1 and op2 must be
    4214              :              sequenced before idx.
    4215              :              If idx is INTEGER_CST, we can just do the optimization
    4216              :              without any SAVE_EXPRs, if op1 and op2 are both ARRAY_TYPE
    4217              :              VAR_DECLs or COMPONENT_REFs thereof (so their address
    4218              :              is constant or relative to frame), optimize into
    4219              :              (SAVE_EXPR <op0>, SAVE_EXPR <idx>, SAVE_EXPR <op0>)
    4220              :              ? op1[SAVE_EXPR <idx>] : op2[SAVE_EXPR <idx>]
    4221              :              Otherwise avoid this optimization.  */
    4222           58 :           if (flag_strong_eval_order == 2)
    4223              :             {
    4224           39 :               if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE)
    4225              :                 {
    4226           30 :                   if (!address_invariant_p (op1) || !address_invariant_p (op2))
    4227              :                     {
    4228              :                       /* Force default conversion on array if
    4229              :                          we can't optimize this and array is ARRAY_TYPE
    4230              :                          COND_EXPR, we can't leave COND_EXPRs with
    4231              :                          ARRAY_TYPE in the IL.  */
    4232            8 :                       array = cp_default_conversion (array, complain);
    4233            8 :                       if (error_operand_p (array))
    4234            0 :                         return error_mark_node;
    4235              :                       break;
    4236              :                     }
    4237              :                 }
    4238           16 :               else if (!POINTER_TYPE_P (TREE_TYPE (array))
    4239            2 :                        || !tree_invariant_p (op1)
    4240           11 :                        || !tree_invariant_p (op2))
    4241              :                 break;
    4242              :             }
    4243           43 :           if (TREE_SIDE_EFFECTS (idx))
    4244              :             {
    4245           18 :               idx = save_expr (idx);
    4246           18 :               op0 = save_expr (op0);
    4247           18 :               warning_sentinel w (warn_unused_value);
    4248           18 :               tree tem = build_compound_expr (loc, op0, idx);
    4249           18 :               op0 = build_compound_expr (loc, tem, op0);
    4250           18 :             }
    4251              :         }
    4252           58 :       op1 = cp_build_array_ref (loc, op1, idx, complain);
    4253           58 :       op2 = cp_build_array_ref (loc, op2, idx, complain);
    4254           58 :       ret = build_conditional_expr (loc, op0, op1, op2, complain);
    4255           58 :       protected_set_expr_location (ret, loc);
    4256           58 :       return ret;
    4257              : 
    4258              :     default:
    4259              :       break;
    4260              :     }
    4261              : 
    4262      6536012 :   bool non_lvalue = convert_vector_to_array_for_subscript (loc, &array, idx);
    4263              : 
    4264      6536012 :   if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE)
    4265              :     {
    4266      1909216 :       tree rval, type;
    4267              : 
    4268      1909216 :       warn_array_subscript_with_type_char (loc, idx);
    4269              : 
    4270      1909216 :       if (!INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (idx)))
    4271              :         {
    4272            3 :           if (complain & tf_error)
    4273            3 :             error_at (loc, "array subscript is not an integer");
    4274            3 :           return error_mark_node;
    4275              :         }
    4276              : 
    4277              :       /* Apply integral promotions *after* noticing character types.
    4278              :          (It is unclear why we do these promotions -- the standard
    4279              :          does not say that we should.  In fact, the natural thing would
    4280              :          seem to be to convert IDX to ptrdiff_t; we're performing
    4281              :          pointer arithmetic.)  */
    4282      1909213 :       idx = cp_perform_integral_promotions (idx, complain);
    4283              : 
    4284      1909213 :       idx = maybe_fold_non_dependent_expr (idx, complain);
    4285              : 
    4286              :       /* An array that is indexed by a non-constant
    4287              :          cannot be stored in a register; we must be able to do
    4288              :          address arithmetic on its address.
    4289              :          Likewise an array of elements of variable size.  */
    4290      1909213 :       if (TREE_CODE (idx) != INTEGER_CST
    4291      1909213 :           || (COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (array)))
    4292       917669 :               && (TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))))
    4293              :                   != INTEGER_CST)))
    4294              :         {
    4295       992804 :           if (!cxx_mark_addressable (array, true))
    4296            0 :             return error_mark_node;
    4297              :         }
    4298              : 
    4299              :       /* An array that is indexed by a constant value which is not within
    4300              :          the array bounds cannot be stored in a register either; because we
    4301              :          would get a crash in store_bit_field/extract_bit_field when trying
    4302              :          to access a non-existent part of the register.  */
    4303      1909213 :       if (TREE_CODE (idx) == INTEGER_CST
    4304       917672 :           && TYPE_DOMAIN (TREE_TYPE (array))
    4305      2825496 :           && ! int_fits_type_p (idx, TYPE_DOMAIN (TREE_TYPE (array))))
    4306              :         {
    4307         3007 :           if (!cxx_mark_addressable (array))
    4308            0 :             return error_mark_node;
    4309              :         }
    4310              : 
    4311              :       /* Note in C++ it is valid to subscript a `register' array, since
    4312              :          it is valid to take the address of something with that
    4313              :          storage specification.  */
    4314      1909213 :       if (extra_warnings)
    4315              :         {
    4316        38397 :           tree foo = array;
    4317        58947 :           while (TREE_CODE (foo) == COMPONENT_REF)
    4318        20550 :             foo = TREE_OPERAND (foo, 0);
    4319            8 :           if (VAR_P (foo) && DECL_REGISTER (foo)
    4320        38397 :               && (complain & tf_warning))
    4321            0 :             warning_at (loc, OPT_Wextra,
    4322              :                         "subscripting array declared %<register%>");
    4323              :         }
    4324              : 
    4325      1909213 :       type = TREE_TYPE (TREE_TYPE (array));
    4326      1909213 :       rval = build4 (ARRAY_REF, type, array, idx, NULL_TREE, NULL_TREE);
    4327              :       /* Array ref is const/volatile if the array elements are
    4328              :          or if the array is..  */
    4329      5727639 :       TREE_READONLY (rval)
    4330      1909213 :         |= (CP_TYPE_CONST_P (type) | TREE_READONLY (array));
    4331      5727639 :       TREE_SIDE_EFFECTS (rval)
    4332      1909213 :         |= (CP_TYPE_VOLATILE_P (type) | TREE_SIDE_EFFECTS (array));
    4333      3818426 :       TREE_THIS_VOLATILE (rval)
    4334      1909213 :         |= (CP_TYPE_VOLATILE_P (type) | TREE_THIS_VOLATILE (array));
    4335      1909213 :       ret = require_complete_type (rval, complain);
    4336      1909213 :       protected_set_expr_location (ret, loc);
    4337      1909213 :       if (non_lvalue)
    4338         6640 :         ret = non_lvalue_loc (loc, ret);
    4339      1909213 :       return ret;
    4340              :     }
    4341              : 
    4342      4626796 :   {
    4343      4626796 :     tree ar = cp_default_conversion (array, complain);
    4344      4626796 :     tree ind = cp_default_conversion (idx, complain);
    4345      4626796 :     tree first = NULL_TREE;
    4346              : 
    4347      3177178 :     if (!processing_template_decl && flag_strong_eval_order == 2
    4348      7762991 :         && TREE_SIDE_EFFECTS (ind))
    4349       163025 :       ar = first = save_expr (ar);
    4350              : 
    4351              :     /* Put the integer in IND to simplify error checking.  */
    4352      4626796 :     if (TREE_CODE (TREE_TYPE (ar)) == INTEGER_TYPE)
    4353           57 :       std::swap (ar, ind);
    4354              : 
    4355      4626796 :     if (ar == error_mark_node || ind == error_mark_node)
    4356              :       return error_mark_node;
    4357              : 
    4358      4626796 :     if (!TYPE_PTR_P (TREE_TYPE (ar)))
    4359              :       {
    4360           22 :         if (complain & tf_error)
    4361            3 :           error_at (loc, "subscripted value is neither array nor pointer");
    4362           22 :         return error_mark_node;
    4363              :       }
    4364      4626774 :     if (TREE_CODE (TREE_TYPE (ind)) != INTEGER_TYPE)
    4365              :       {
    4366            0 :         if (complain & tf_error)
    4367            0 :           error_at (loc, "array subscript is not an integer");
    4368            0 :         return error_mark_node;
    4369              :       }
    4370              : 
    4371      4626774 :     warn_array_subscript_with_type_char (loc, idx);
    4372              : 
    4373      4626774 :     ret = cp_build_binary_op (input_location, PLUS_EXPR, ar, ind, complain);
    4374      4626774 :     if (first)
    4375       163025 :       ret = build2_loc (loc, COMPOUND_EXPR, TREE_TYPE (ret), first, ret);
    4376      4626774 :     ret = cp_build_indirect_ref (loc, ret, RO_ARRAY_INDEXING, complain);
    4377      4626774 :     protected_set_expr_location (ret, loc);
    4378      4626774 :     if (non_lvalue)
    4379            0 :       ret = non_lvalue_loc (loc, ret);
    4380              :     return ret;
    4381              :   }
    4382              : }
    4383              : 
    4384              : /* Entry point for Obj-C++.  */
    4385              : 
    4386              : tree
    4387      3855860 : build_array_ref (location_t loc, tree array, tree idx)
    4388              : {
    4389      3855860 :   return cp_build_array_ref (loc, array, idx, tf_warning_or_error);
    4390              : }
    4391              : 
    4392              : /* Resolve a pointer to member function.  INSTANCE is the object
    4393              :    instance to use, if the member points to a virtual member.
    4394              : 
    4395              :    This used to avoid checking for virtual functions if basetype
    4396              :    has no virtual functions, according to an earlier ANSI draft.
    4397              :    With the final ISO C++ rules, such an optimization is
    4398              :    incorrect: A pointer to a derived member can be static_cast
    4399              :    to pointer-to-base-member, as long as the dynamic object
    4400              :    later has the right member.  So now we only do this optimization
    4401              :    when we know the dynamic type of the object.  */
    4402              : 
    4403              : tree
    4404        83217 : get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function,
    4405              :                                   tsubst_flags_t complain)
    4406              : {
    4407        83217 :   if (TREE_CODE (function) == OFFSET_REF)
    4408            0 :     function = TREE_OPERAND (function, 1);
    4409              : 
    4410        83217 :   if (TYPE_PTRMEMFUNC_P (TREE_TYPE (function)))
    4411              :     {
    4412        83217 :       tree idx, delta, e1, e2, e3, vtbl;
    4413        83217 :       bool nonvirtual;
    4414        83217 :       tree fntype = TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (function));
    4415        83217 :       tree basetype = TYPE_METHOD_BASETYPE (TREE_TYPE (fntype));
    4416              : 
    4417        83217 :       tree instance_ptr = *instance_ptrptr;
    4418        83217 :       tree instance_save_expr = 0;
    4419        83217 :       if (instance_ptr == error_mark_node)
    4420              :         {
    4421            0 :           if (TREE_CODE (function) == PTRMEM_CST)
    4422              :             {
    4423              :               /* Extracting the function address from a pmf is only
    4424              :                  allowed with -Wno-pmf-conversions. It only works for
    4425              :                  pmf constants.  */
    4426            0 :               e1 = build_addr_func (PTRMEM_CST_MEMBER (function), complain);
    4427            0 :               e1 = convert (fntype, e1);
    4428            0 :               return e1;
    4429              :             }
    4430              :           else
    4431              :             {
    4432            0 :               if (complain & tf_error)
    4433            0 :                 error ("object missing in use of %qE", function);
    4434            0 :               return error_mark_node;
    4435              :             }
    4436              :         }
    4437              : 
    4438              :       /* True if we know that the dynamic type of the object doesn't have
    4439              :          virtual functions, so we can assume the PFN field is a pointer.  */
    4440        83217 :       nonvirtual = (COMPLETE_TYPE_P (basetype)
    4441        83181 :                     && !TYPE_POLYMORPHIC_P (basetype)
    4442       111829 :                     && resolves_to_fixed_type_p (instance_ptr, 0));
    4443              : 
    4444              :       /* If we don't really have an object (i.e. in an ill-formed
    4445              :          conversion from PMF to pointer), we can't resolve virtual
    4446              :          functions anyway.  */
    4447        82965 :       if (!nonvirtual && is_dummy_object (instance_ptr))
    4448              :         nonvirtual = true;
    4449              : 
    4450              :       /* Use force_target_expr even when instance_ptr doesn't have
    4451              :          side-effects, unless it is a simple decl or constant, so
    4452              :          that we don't ubsan instrument the expression multiple times.
    4453              :          Don't use save_expr, as save_expr can avoid building a SAVE_EXPR
    4454              :          and building a SAVE_EXPR manually can be optimized away during
    4455              :          cp_fold.  See PR116449 and PR117259.  */
    4456        83217 :       if (TREE_SIDE_EFFECTS (instance_ptr)
    4457        83217 :           || (!nonvirtual
    4458        46433 :               && !DECL_P (instance_ptr)
    4459        46433 :               && !TREE_CONSTANT (instance_ptr)))
    4460        82701 :         instance_ptr = instance_save_expr
    4461        82701 :           = get_internal_target_expr (instance_ptr);
    4462              : 
    4463              :       /* See above comment.  */
    4464        83217 :       if (TREE_SIDE_EFFECTS (function)
    4465        83217 :           || (!nonvirtual
    4466        64532 :               && !DECL_P (function)
    4467        64520 :               && !TREE_CONSTANT (function)))
    4468        82768 :         function = get_internal_target_expr (function);
    4469              : 
    4470              :       /* Start by extracting all the information from the PMF itself.  */
    4471        83217 :       e3 = pfn_from_ptrmemfunc (function);
    4472        83217 :       delta = delta_from_ptrmemfunc (function);
    4473        83217 :       idx = build1 (NOP_EXPR, vtable_index_type, e3);
    4474        83217 :       switch (TARGET_PTRMEMFUNC_VBIT_LOCATION)
    4475              :         {
    4476        83217 :           sanitize_code_type flag_sanitize_save;
    4477        83217 :         case ptrmemfunc_vbit_in_pfn:
    4478        83217 :           e1 = cp_build_binary_op (input_location,
    4479              :                                    BIT_AND_EXPR, idx, integer_one_node,
    4480              :                                    complain);
    4481        83217 :           idx = cp_build_binary_op (input_location,
    4482              :                                     MINUS_EXPR, idx, integer_one_node,
    4483              :                                     complain);
    4484        83217 :           if (idx == error_mark_node)
    4485              :             return error_mark_node;
    4486        83217 :           break;
    4487              : 
    4488              :         case ptrmemfunc_vbit_in_delta:
    4489              :           e1 = cp_build_binary_op (input_location,
    4490              :                                    BIT_AND_EXPR, delta, integer_one_node,
    4491              :                                    complain);
    4492              :           /* Don't instrument the RSHIFT_EXPR we're about to create because
    4493              :              we're going to use DELTA number of times, and that wouldn't play
    4494              :              well with SAVE_EXPRs therein.  */
    4495              :           flag_sanitize_save = flag_sanitize;
    4496              :           flag_sanitize = 0;
    4497              :           delta = cp_build_binary_op (input_location,
    4498              :                                       RSHIFT_EXPR, delta, integer_one_node,
    4499              :                                       complain);
    4500              :           flag_sanitize = flag_sanitize_save;
    4501              :           if (delta == error_mark_node)
    4502              :             return error_mark_node;
    4503              :           break;
    4504              : 
    4505              :         default:
    4506              :           gcc_unreachable ();
    4507              :         }
    4508              : 
    4509        83217 :       if (e1 == error_mark_node)
    4510              :         return error_mark_node;
    4511              : 
    4512              :       /* Convert down to the right base before using the instance.  A
    4513              :          special case is that in a pointer to member of class C, C may
    4514              :          be incomplete.  In that case, the function will of course be
    4515              :          a member of C, and no conversion is required.  In fact,
    4516              :          lookup_base will fail in that case, because incomplete
    4517              :          classes do not have BINFOs.  */
    4518        83217 :       if (!same_type_ignoring_top_level_qualifiers_p
    4519        83217 :           (basetype, TREE_TYPE (TREE_TYPE (instance_ptr))))
    4520              :         {
    4521           81 :           basetype = lookup_base (TREE_TYPE (TREE_TYPE (instance_ptr)),
    4522              :                                   basetype, ba_check, NULL, complain);
    4523           81 :           instance_ptr = build_base_path (PLUS_EXPR, instance_ptr, basetype,
    4524              :                                           1, complain);
    4525           81 :           if (instance_ptr == error_mark_node)
    4526              :             return error_mark_node;
    4527              :         }
    4528              :       /* ...and then the delta in the PMF.  */
    4529        83217 :       instance_ptr = fold_build_pointer_plus (instance_ptr, delta);
    4530              : 
    4531              :       /* Hand back the adjusted 'this' argument to our caller.  */
    4532        83217 :       *instance_ptrptr = instance_ptr;
    4533              : 
    4534        83217 :       if (nonvirtual)
    4535              :         /* Now just return the pointer.  */
    4536              :         return e3;
    4537              : 
    4538              :       /* Next extract the vtable pointer from the object.  */
    4539        82947 :       vtbl = build1 (NOP_EXPR, build_pointer_type (vtbl_ptr_type_node),
    4540              :                      instance_ptr);
    4541        82947 :       vtbl = cp_build_fold_indirect_ref (vtbl);
    4542        82947 :       if (vtbl == error_mark_node)
    4543              :         return error_mark_node;
    4544              : 
    4545              :       /* Finally, extract the function pointer from the vtable.  */
    4546        82947 :       e2 = fold_build_pointer_plus_loc (input_location, vtbl, idx);
    4547        82947 :       e2 = cp_build_fold_indirect_ref (e2);
    4548        82947 :       if (e2 == error_mark_node)
    4549              :         return error_mark_node;
    4550        82947 :       TREE_CONSTANT (e2) = 1;
    4551              : 
    4552              :       /* When using function descriptors, the address of the
    4553              :          vtable entry is treated as a function pointer.  */
    4554        82947 :       if (TARGET_VTABLE_USES_DESCRIPTORS)
    4555              :         e2 = build1 (NOP_EXPR, TREE_TYPE (e2),
    4556              :                      cp_build_addr_expr (e2, complain));
    4557              : 
    4558        82947 :       e2 = fold_convert (TREE_TYPE (e3), e2);
    4559        82947 :       e1 = build_conditional_expr (input_location, e1, e2, e3, complain);
    4560        82947 :       if (e1 == error_mark_node)
    4561              :         return error_mark_node;
    4562              : 
    4563              :       /* Make sure this doesn't get evaluated first inside one of the
    4564              :          branches of the COND_EXPR.  */
    4565        82947 :       if (instance_save_expr)
    4566        82653 :         e1 = build2 (COMPOUND_EXPR, TREE_TYPE (e1),
    4567              :                      instance_save_expr, e1);
    4568              : 
    4569              :       function = e1;
    4570              :     }
    4571              :   return function;
    4572              : }
    4573              : 
    4574              : /* Used by the C-common bits.  */
    4575              : tree
    4576            0 : build_function_call (location_t /*loc*/,
    4577              :                      tree function, tree params)
    4578              : {
    4579            0 :   return cp_build_function_call (function, params, tf_warning_or_error);
    4580              : }
    4581              : 
    4582              : /* Used by the C-common bits.  */
    4583              : tree
    4584       328236 : build_function_call_vec (location_t /*loc*/, vec<location_t> /*arg_loc*/,
    4585              :                          tree function, vec<tree, va_gc> *params,
    4586              :                          vec<tree, va_gc> * /*origtypes*/, tree orig_function)
    4587              : {
    4588       328236 :   vec<tree, va_gc> *orig_params = params;
    4589       328236 :   tree ret = cp_build_function_call_vec (function, &params,
    4590              :                                          tf_warning_or_error, orig_function);
    4591              : 
    4592              :   /* cp_build_function_call_vec can reallocate PARAMS by adding
    4593              :      default arguments.  That should never happen here.  Verify
    4594              :      that.  */
    4595       328236 :   gcc_assert (params == orig_params);
    4596              : 
    4597       328236 :   return ret;
    4598              : }
    4599              : 
    4600              : /* Build a function call using a tree list of arguments.  */
    4601              : 
    4602              : static tree
    4603            0 : cp_build_function_call (tree function, tree params, tsubst_flags_t complain)
    4604              : {
    4605            0 :   tree ret;
    4606              : 
    4607            0 :   releasing_vec vec;
    4608            0 :   for (; params != NULL_TREE; params = TREE_CHAIN (params))
    4609            0 :     vec_safe_push (vec, TREE_VALUE (params));
    4610            0 :   ret = cp_build_function_call_vec (function, &vec, complain);
    4611            0 :   return ret;
    4612            0 : }
    4613              : 
    4614              : /* Build a function call using varargs.  */
    4615              : 
    4616              : tree
    4617       547273 : cp_build_function_call_nary (tree function, tsubst_flags_t complain, ...)
    4618              : {
    4619       547273 :   va_list args;
    4620       547273 :   tree ret, t;
    4621              : 
    4622       547273 :   releasing_vec vec;
    4623       547273 :   va_start (args, complain);
    4624      1362943 :   for (t = va_arg (args, tree); t != NULL_TREE; t = va_arg (args, tree))
    4625       815670 :     vec_safe_push (vec, t);
    4626       547273 :   va_end (args);
    4627       547273 :   ret = cp_build_function_call_vec (function, &vec, complain);
    4628       547273 :   return ret;
    4629       547273 : }
    4630              : 
    4631              : /* C++ implementation of callback for use when checking param types.  */
    4632              : 
    4633              : bool
    4634           18 : cp_comp_parm_types (tree wanted_type, tree actual_type)
    4635              : {
    4636           18 :   if (TREE_CODE (wanted_type) == POINTER_TYPE
    4637           18 :       && TREE_CODE (actual_type) == POINTER_TYPE)
    4638           15 :     return same_or_base_type_p (TREE_TYPE (wanted_type),
    4639              :                                 TREE_TYPE (actual_type));
    4640              :   return false;
    4641              : }
    4642              : 
    4643              : /* Build a function call using a vector of arguments.
    4644              :    If FUNCTION is the result of resolving an overloaded target built-in,
    4645              :    ORIG_FNDECL is the original function decl, otherwise it is null.
    4646              :    PARAMS may be NULL if there are no parameters.  This changes the
    4647              :    contents of PARAMS.  */
    4648              : 
    4649              : tree
    4650      8286916 : cp_build_function_call_vec (tree function, vec<tree, va_gc> **params,
    4651              :                             tsubst_flags_t complain, tree orig_fndecl)
    4652              : {
    4653      8286916 :   tree fntype, fndecl;
    4654      8286916 :   int is_method;
    4655      8286916 :   tree original = function;
    4656      8286916 :   int nargs;
    4657      8286916 :   tree *argarray;
    4658      8286916 :   tree parm_types;
    4659      8286916 :   vec<tree, va_gc> *allocated = NULL;
    4660      8286916 :   tree ret;
    4661              : 
    4662              :   /* For Objective-C, convert any calls via a cast to OBJC_TYPE_REF
    4663              :      expressions, like those used for ObjC messenger dispatches.  */
    4664      8286916 :   if (params != NULL && !vec_safe_is_empty (*params))
    4665      2114534 :     function = objc_rewrite_function_call (function, (**params)[0]);
    4666              : 
    4667              :   /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
    4668              :      Strip such NOP_EXPRs, since FUNCTION is used in non-lvalue context.  */
    4669      8286916 :   if (TREE_CODE (function) == NOP_EXPR
    4670      8286916 :       && TREE_TYPE (function) == TREE_TYPE (TREE_OPERAND (function, 0)))
    4671           15 :     function = TREE_OPERAND (function, 0);
    4672              : 
    4673      8286916 :   if (TREE_CODE (function) == FUNCTION_DECL)
    4674              :     {
    4675      1581073 :       if (!mark_used (function, complain))
    4676           24 :         return error_mark_node;
    4677      1581049 :       fndecl = function;
    4678              : 
    4679              :       /* For target_version semantics, the function set cannot be called
    4680              :          if there is no default version in scope.  */
    4681      1581049 :       if (!TARGET_HAS_FMV_TARGET_ATTRIBUTE
    4682              :            && !is_function_default_version (fndecl))
    4683              :          {
    4684              :            if (complain & tf_error)
    4685              :             error ("no default version in scope");
    4686              :            return error_mark_node;
    4687              :          }
    4688              : 
    4689              :       /* Convert anything with function type to a pointer-to-function.  */
    4690      1581049 :       if (DECL_MAIN_P (function))
    4691              :         {
    4692            0 :           if (complain & tf_error)
    4693            0 :             pedwarn (input_location, OPT_Wpedantic,
    4694              :                      "ISO C++ forbids calling %<::main%> from within program");
    4695              :           else
    4696            0 :             return error_mark_node;
    4697              :         }
    4698      1581049 :       function = build_addr_func (function, complain);
    4699              :     }
    4700              :   else
    4701              :     {
    4702      6705843 :       fndecl = NULL_TREE;
    4703              : 
    4704      6705843 :       function = build_addr_func (function, complain);
    4705              :     }
    4706              : 
    4707      8286892 :   if (function == error_mark_node)
    4708              :     return error_mark_node;
    4709              : 
    4710      8286790 :   fntype = TREE_TYPE (function);
    4711              : 
    4712      8286790 :   if (TYPE_PTRMEMFUNC_P (fntype))
    4713              :     {
    4714           15 :       if (complain & tf_error)
    4715           15 :         error ("must use %<.*%> or %<->*%> to call pointer-to-member "
    4716              :                "function in %<%E (...)%>, e.g. %<(... ->* %E) (...)%>",
    4717              :                original, original);
    4718           15 :       return error_mark_node;
    4719              :     }
    4720              : 
    4721     16573550 :   is_method = (TYPE_PTR_P (fntype)
    4722      8286775 :                && TREE_CODE (TREE_TYPE (fntype)) == METHOD_TYPE);
    4723              : 
    4724      8286775 :   if (!(TYPE_PTRFN_P (fntype)
    4725        84548 :         || is_method
    4726         1387 :         || TREE_CODE (function) == TEMPLATE_ID_EXPR))
    4727              :     {
    4728         1387 :       if (complain & tf_error)
    4729              :         {
    4730          176 :           if (is_stub_object (original))
    4731            3 :             error_at (input_location,
    4732              :                       "%qT cannot be used as a function",
    4733            3 :                       TREE_TYPE (original));
    4734          173 :           else if (!flag_diagnostics_show_caret)
    4735          173 :             error_at (input_location,
    4736              :                       "%qE cannot be used as a function", original);
    4737            0 :           else if (DECL_P (original))
    4738            0 :             error_at (input_location,
    4739              :                       "%qD cannot be used as a function", original);
    4740              :           else
    4741            0 :             error_at (input_location,
    4742              :                       "expression cannot be used as a function");
    4743              :         }
    4744              : 
    4745         1387 :       return error_mark_node;
    4746              :     }
    4747              : 
    4748              :   /* fntype now gets the type of function pointed to.  */
    4749      8285388 :   fntype = TREE_TYPE (fntype);
    4750      8285388 :   parm_types = TYPE_ARG_TYPES (fntype);
    4751              : 
    4752      8285388 :   if (params == NULL)
    4753              :     {
    4754       149627 :       allocated = make_tree_vector ();
    4755       149627 :       params = &allocated;
    4756              :     }
    4757              : 
    4758      8285388 :     nargs = convert_arguments (parm_types, params, fndecl, LOOKUP_NORMAL,
    4759              :                                complain);
    4760      8285388 :   if (nargs < 0)
    4761         1872 :     return error_mark_node;
    4762              : 
    4763      8283516 :   argarray = (*params)->address ();
    4764              : 
    4765              :   /* Check for errors in format strings and inappropriately
    4766              :      null parameters.  */
    4767      8283516 :   bool warned_p
    4768      8283516 :     = ((complain & tf_warning)
    4769      8283516 :        && check_function_arguments (input_location, fndecl, fntype,
    4770              :                                     nargs, argarray, NULL,
    4771      8283516 :                                     cp_comp_parm_types));
    4772              : 
    4773      8283516 :   ret = build_cxx_call (function, nargs, argarray, complain, orig_fndecl);
    4774              : 
    4775      8283516 :   if (warned_p)
    4776              :     {
    4777           27 :       tree c = extract_call_expr (ret);
    4778           27 :       if (TREE_CODE (c) == CALL_EXPR)
    4779           27 :         suppress_warning (c, OPT_Wnonnull);
    4780              :     }
    4781              : 
    4782      8283516 :   if (allocated != NULL)
    4783       149627 :     release_tree_vector (allocated);
    4784              : 
    4785              :   return ret;
    4786              : }
    4787              : 
    4788              : /* Subroutine of convert_arguments.
    4789              :    Print an error message about a wrong number of arguments.  */
    4790              : 
    4791              : static void
    4792          162 : error_args_num (location_t loc, tree fndecl, bool too_many_p)
    4793              : {
    4794          162 :   if (fndecl)
    4795              :     {
    4796          126 :       auto_diagnostic_group d;
    4797          126 :       if (TREE_CODE (TREE_TYPE (fndecl)) == METHOD_TYPE)
    4798              :         {
    4799            0 :           if (DECL_NAME (fndecl) == NULL_TREE
    4800            0 :               || (DECL_NAME (fndecl)
    4801            0 :                   == DECL_NAME (TYPE_NAME (DECL_CONTEXT (fndecl)))))
    4802            0 :             error_at (loc,
    4803              :                       too_many_p
    4804              :                       ? G_("too many arguments to constructor %q#D")
    4805              :                       : G_("too few arguments to constructor %q#D"),
    4806              :                       fndecl);
    4807              :           else
    4808            0 :             error_at (loc,
    4809              :                       too_many_p
    4810              :                       ? G_("too many arguments to member function %q#D")
    4811              :                       : G_("too few arguments to member function %q#D"),
    4812              :                       fndecl);
    4813              :         }
    4814              :       else
    4815          189 :         error_at (loc,
    4816              :                   too_many_p
    4817              :                   ? G_("too many arguments to function %q#D")
    4818              :                   : G_("too few arguments to function %q#D"),
    4819              :                   fndecl);
    4820          126 :       if (!DECL_IS_UNDECLARED_BUILTIN (fndecl))
    4821           87 :         inform (DECL_SOURCE_LOCATION (fndecl), "declared here");
    4822          126 :     }
    4823              :   else
    4824              :     {
    4825           36 :       if (c_dialect_objc ()  &&  objc_message_selector ())
    4826            0 :         error_at (loc,
    4827              :                   too_many_p
    4828              :                   ? G_("too many arguments to method %q#D")
    4829              :                   : G_("too few arguments to method %q#D"),
    4830              :                   objc_message_selector ());
    4831              :       else
    4832           57 :         error_at (loc, too_many_p ? G_("too many arguments to function")
    4833              :                                   : G_("too few arguments to function"));
    4834              :     }
    4835          162 : }
    4836              : 
    4837              : /* Convert the actual parameter expressions in the list VALUES to the
    4838              :    types in the list TYPELIST.  The converted expressions are stored
    4839              :    back in the VALUES vector.
    4840              :    If parmdecls is exhausted, or when an element has NULL as its type,
    4841              :    perform the default conversions.
    4842              : 
    4843              :    NAME is an IDENTIFIER_NODE or 0.  It is used only for error messages.
    4844              : 
    4845              :    This is also where warnings about wrong number of args are generated.
    4846              : 
    4847              :    Returns the actual number of arguments processed (which might be less
    4848              :    than the length of the vector), or -1 on error.
    4849              : 
    4850              :    In C++, unspecified trailing parameters can be filled in with their
    4851              :    default arguments, if such were specified.  Do so here.  */
    4852              : 
    4853              : static int
    4854      8285388 : convert_arguments (tree typelist, vec<tree, va_gc> **values, tree fndecl,
    4855              :                    int flags, tsubst_flags_t complain)
    4856              : {
    4857      8285388 :   tree typetail;
    4858      8285388 :   unsigned int i;
    4859              : 
    4860              :   /* Argument passing is always copy-initialization.  */
    4861      8285388 :   flags |= LOOKUP_ONLYCONVERTING;
    4862              : 
    4863     12909345 :   for (i = 0, typetail = typelist;
    4864     12909345 :        i < vec_safe_length (*values);
    4865              :        i++)
    4866              :     {
    4867      9250888 :       tree type = typetail ? TREE_VALUE (typetail) : 0;
    4868      4625667 :       tree val = (**values)[i];
    4869              : 
    4870      4625667 :       if (val == error_mark_node || type == error_mark_node)
    4871              :         return -1;
    4872              : 
    4873      4625661 :       if (type == void_type_node)
    4874              :         {
    4875          205 :           if (complain & tf_error)
    4876           78 :             error_args_num (input_location, fndecl, /*too_many_p=*/true);
    4877          205 :           return -1;
    4878              :         }
    4879              : 
    4880              :       /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
    4881              :          Strip such NOP_EXPRs, since VAL is used in non-lvalue context.  */
    4882      4625456 :       if (TREE_CODE (val) == NOP_EXPR
    4883      1209657 :           && TREE_TYPE (val) == TREE_TYPE (TREE_OPERAND (val, 0))
    4884      4625474 :           && (type == 0 || !TYPE_REF_P (type)))
    4885           18 :         val = TREE_OPERAND (val, 0);
    4886              : 
    4887      4625456 :       if (type == 0 || !TYPE_REF_P (type))
    4888              :         {
    4889      4397374 :           if (TREE_CODE (TREE_TYPE (val)) == ARRAY_TYPE
    4890      4397374 :               || FUNC_OR_METHOD_TYPE_P (TREE_TYPE (val)))
    4891        11183 :             val = decay_conversion (val, complain);
    4892              :         }
    4893              : 
    4894      4625456 :       if (val == error_mark_node)
    4895              :         return -1;
    4896              : 
    4897      4625456 :       if (type != 0)
    4898              :         {
    4899              :           /* Formal parm type is specified by a function prototype.  */
    4900      4625010 :           tree parmval;
    4901              : 
    4902      4625010 :           if (!COMPLETE_TYPE_P (complete_type (type)))
    4903              :             {
    4904           18 :               if (complain & tf_error)
    4905              :                 {
    4906           12 :                   location_t loc = EXPR_LOC_OR_LOC (val, input_location);
    4907           12 :                   if (fndecl)
    4908              :                     {
    4909           12 :                       auto_diagnostic_group d;
    4910           12 :                       error_at (loc,
    4911              :                                 "parameter %P of %qD has incomplete type %qT",
    4912              :                                 i, fndecl, type);
    4913           12 :                       inform (get_fndecl_argument_location (fndecl, i),
    4914              :                               "  declared here");
    4915           12 :                     }
    4916              :                   else
    4917            0 :                     error_at (loc, "parameter %P has incomplete type %qT", i,
    4918              :                               type);
    4919              :                 }
    4920           18 :               parmval = error_mark_node;
    4921              :             }
    4922              :           else
    4923              :             {
    4924      4624992 :               parmval = convert_for_initialization
    4925      4624992 :                 (NULL_TREE, type, val, flags,
    4926              :                  ICR_ARGPASS, fndecl, i, complain);
    4927      4624992 :               parmval = convert_for_arg_passing (type, parmval, complain);
    4928              :             }
    4929              : 
    4930      4625010 :           if (parmval == error_mark_node)
    4931              :             return -1;
    4932              : 
    4933      4623511 :           (**values)[i] = parmval;
    4934              :         }
    4935              :       else
    4936              :         {
    4937          446 :           int magic = fndecl ? magic_varargs_p (fndecl) : 0;
    4938           21 :           if (magic)
    4939              :             {
    4940              :               /* Don't truncate excess precision to the semantic type.  */
    4941            0 :               if (magic == 1 && TREE_CODE (val) == EXCESS_PRECISION_EXPR)
    4942            0 :                 val = TREE_OPERAND (val, 0);
    4943              :               /* Don't do ellipsis conversion for __built_in_constant_p
    4944              :                  as this will result in spurious errors for non-trivial
    4945              :                  types.  */
    4946            0 :               val = require_complete_type (val, complain);
    4947              :             }
    4948              :           else
    4949          446 :             val = convert_arg_to_ellipsis (val, complain);
    4950              : 
    4951          446 :           (**values)[i] = val;
    4952              :         }
    4953              : 
    4954      4623957 :       if (typetail)
    4955      4623511 :         typetail = TREE_CHAIN (typetail);
    4956              :     }
    4957              : 
    4958      8283678 :   if (typetail != 0 && typetail != void_list_node)
    4959              :     {
    4960              :       /* See if there are default arguments that can be used.  Because
    4961              :          we hold default arguments in the FUNCTION_TYPE (which is so
    4962              :          wrong), we can see default parameters here from deduced
    4963              :          contexts (and via typeof) for indirect function calls.
    4964              :          Fortunately we know whether we have a function decl to
    4965              :          provide default arguments in a language conformant
    4966              :          manner.  */
    4967           63 :       if (fndecl && TREE_PURPOSE (typetail)
    4968          165 :           && TREE_CODE (TREE_PURPOSE (typetail)) != DEFERRED_PARSE)
    4969              :         {
    4970            6 :           for (; typetail != void_list_node; ++i)
    4971              :             {
    4972              :               /* After DR777, with explicit template args we can end up with a
    4973              :                  default argument followed by no default argument.  */
    4974            6 :               if (!TREE_PURPOSE (typetail))
    4975              :                 break;
    4976            3 :               tree parmval
    4977            3 :                 = convert_default_arg (TREE_VALUE (typetail),
    4978            3 :                                        TREE_PURPOSE (typetail),
    4979            3 :                                        fndecl, i, complain);
    4980              : 
    4981            3 :               if (parmval == error_mark_node)
    4982            0 :                 return -1;
    4983              : 
    4984            3 :               vec_safe_push (*values, parmval);
    4985            3 :               typetail = TREE_CHAIN (typetail);
    4986              :               /* ends with `...'.  */
    4987            3 :               if (typetail == NULL_TREE)
    4988              :                 break;
    4989              :             }
    4990              :         }
    4991              : 
    4992          162 :       if (typetail && typetail != void_list_node)
    4993              :         {
    4994          162 :           if (complain & tf_error)
    4995           84 :             error_args_num (input_location, fndecl, /*too_many_p=*/false);
    4996          162 :           return -1;
    4997              :         }
    4998              :     }
    4999              : 
    5000      8283516 :   return (int) i;
    5001              : }
    5002              : 
    5003              : /* Build a binary-operation expression, after performing default
    5004              :    conversions on the operands.  CODE is the kind of expression to
    5005              :    build.  ARG1 and ARG2 are the arguments.  ARG1_CODE and ARG2_CODE
    5006              :    are the tree codes which correspond to ARG1 and ARG2 when issuing
    5007              :    warnings about possibly misplaced parentheses.  They may differ
    5008              :    from the TREE_CODE of ARG1 and ARG2 if the parser has done constant
    5009              :    folding (e.g., if the parser sees "a | 1 + 1", it may call this
    5010              :    routine with ARG2 being an INTEGER_CST and ARG2_CODE == PLUS_EXPR).
    5011              :    To avoid issuing any parentheses warnings, pass ARG1_CODE and/or
    5012              :    ARG2_CODE as ERROR_MARK.  */
    5013              : 
    5014              : tree
    5015    239638238 : build_x_binary_op (const op_location_t &loc, enum tree_code code, tree arg1,
    5016              :                    enum tree_code arg1_code, tree arg2,
    5017              :                    enum tree_code arg2_code, tree lookups,
    5018              :                    tree *overload_p, tsubst_flags_t complain)
    5019              : {
    5020    239638238 :   tree orig_arg1;
    5021    239638238 :   tree orig_arg2;
    5022    239638238 :   tree expr;
    5023    239638238 :   tree overload = NULL_TREE;
    5024              : 
    5025    239638238 :   orig_arg1 = arg1;
    5026    239638238 :   orig_arg2 = arg2;
    5027              : 
    5028    239638238 :   if (processing_template_decl)
    5029              :     {
    5030    130146292 :       if (type_dependent_expression_p (arg1)
    5031    130146292 :           || type_dependent_expression_p (arg2))
    5032              :         {
    5033     89754271 :           expr = build_min_nt_loc (loc, code, arg1, arg2);
    5034     89754271 :           TREE_TYPE (expr)
    5035     89754271 :             = build_dependent_operator_type (lookups, code, false);
    5036     89754271 :           return expr;
    5037              :         }
    5038              :     }
    5039              : 
    5040    149883967 :   if (code == DOTSTAR_EXPR)
    5041        83360 :     expr = build_m_component_ref (arg1, arg2, complain);
    5042              :   else
    5043    149800607 :     expr = build_new_op (loc, code, LOOKUP_NORMAL, arg1, arg2, NULL_TREE,
    5044              :                          lookups, &overload, complain);
    5045              : 
    5046    149883934 :   if (overload_p != NULL)
    5047     58487025 :     *overload_p = overload;
    5048              : 
    5049              :   /* Check for cases such as x+y<<z which users are likely to
    5050              :      misinterpret.  But don't warn about obj << x + y, since that is a
    5051              :      common idiom for I/O.  */
    5052    149883934 :   if (warn_parentheses
    5053      1197284 :       && (complain & tf_warning)
    5054      1143904 :       && !processing_template_decl
    5055       792773 :       && !error_operand_p (arg1)
    5056       792767 :       && !error_operand_p (arg2)
    5057    150676689 :       && (code != LSHIFT_EXPR
    5058        70226 :           || !CLASS_TYPE_P (TREE_TYPE (arg1))))
    5059       791732 :     warn_about_parentheses (loc, code, arg1_code, orig_arg1,
    5060              :                             arg2_code, orig_arg2);
    5061              : 
    5062    149883934 :   if (processing_template_decl && expr != error_mark_node)
    5063              :     {
    5064     40391832 :       if (overload != NULL_TREE)
    5065      3811635 :         return (build_min_non_dep_op_overload
    5066      3811635 :                 (code, expr, overload, orig_arg1, orig_arg2));
    5067              : 
    5068     36580197 :       return build_min_non_dep (code, expr, orig_arg1, orig_arg2);
    5069              :     }
    5070              : 
    5071              :   return expr;
    5072              : }
    5073              : 
    5074              : /* Build and return an ARRAY_REF expression.  */
    5075              : 
    5076              : tree
    5077      3479317 : build_x_array_ref (location_t loc, tree arg1, tree arg2,
    5078              :                    tsubst_flags_t complain)
    5079              : {
    5080      3479317 :   tree orig_arg1 = arg1;
    5081      3479317 :   tree orig_arg2 = arg2;
    5082      3479317 :   tree expr;
    5083      3479317 :   tree overload = NULL_TREE;
    5084              : 
    5085      3479317 :   if (processing_template_decl)
    5086              :     {
    5087         4092 :       if (type_dependent_expression_p (arg1)
    5088         4092 :           || type_dependent_expression_p (arg2))
    5089         2308 :         return build_min_nt_loc (loc, ARRAY_REF, arg1, arg2,
    5090         2308 :                                  NULL_TREE, NULL_TREE);
    5091              :     }
    5092              : 
    5093      3477009 :   expr = build_new_op (loc, ARRAY_REF, LOOKUP_NORMAL, arg1, arg2,
    5094              :                        NULL_TREE, NULL_TREE, &overload, complain);
    5095              : 
    5096      3477009 :   if (processing_template_decl && expr != error_mark_node)
    5097              :     {
    5098         1781 :       if (overload != NULL_TREE)
    5099         1773 :         return (build_min_non_dep_op_overload
    5100         1773 :                 (ARRAY_REF, expr, overload, orig_arg1, orig_arg2));
    5101              : 
    5102            8 :       return build_min_non_dep (ARRAY_REF, expr, orig_arg1, orig_arg2,
    5103            8 :                                 NULL_TREE, NULL_TREE);
    5104              :     }
    5105              :   return expr;
    5106              : }
    5107              : 
    5108              : /* Build an OpenMP array section reference, creating an exact type for the
    5109              :    resulting expression based on the element type and bounds if possible.  If
    5110              :    we have variable bounds, create an incomplete array type for the result
    5111              :    instead.  */
    5112              : 
    5113              : tree
    5114        10476 : build_omp_array_section (location_t loc, tree array_expr, tree index,
    5115              :                          tree length)
    5116              : {
    5117        10476 :   if (TREE_CODE (array_expr) == TYPE_DECL
    5118        10476 :       || type_dependent_expression_p (array_expr))
    5119          258 :     return build3_loc (loc, OMP_ARRAY_SECTION, NULL_TREE, array_expr, index,
    5120          258 :                        length);
    5121              : 
    5122        10218 :   tree type = TREE_TYPE (array_expr);
    5123        10218 :   gcc_assert (type);
    5124        10218 :   type = non_reference (type);
    5125              : 
    5126        10218 :   tree sectype, eltype = TREE_TYPE (type);
    5127              : 
    5128              :   /* It's not an array or pointer type.  Just reuse the type of the
    5129              :      original expression as the type of the array section (an error will be
    5130              :      raised anyway, later).  */
    5131        10218 :   if (eltype == NULL_TREE)
    5132           39 :     sectype = TREE_TYPE (array_expr);
    5133              :   else
    5134              :     {
    5135        10179 :       tree idxtype = NULL_TREE;
    5136              : 
    5137              :       /* If we know the integer bounds, create an index type with exact
    5138              :          low/high (or zero/length) bounds.  Otherwise, create an incomplete
    5139              :          array type.  (This mostly only affects diagnostics.)  */
    5140        10179 :       if (index != NULL_TREE
    5141        10179 :           && length != NULL_TREE
    5142         7379 :           && TREE_CODE (index) == INTEGER_CST
    5143         6585 :           && TREE_CODE (length) == INTEGER_CST)
    5144              :         {
    5145         5090 :           tree low = fold_convert (sizetype, index);
    5146         5090 :           tree high = fold_convert (sizetype, length);
    5147         5090 :           high = size_binop (PLUS_EXPR, low, high);
    5148         5090 :           high = size_binop (MINUS_EXPR, high, size_one_node);
    5149         5090 :           idxtype = build_range_type (sizetype, low, high);
    5150         5090 :         }
    5151         2897 :       else if ((index == NULL_TREE || integer_zerop (index))
    5152         3503 :                && length != NULL_TREE
    5153         7187 :                && TREE_CODE (length) == INTEGER_CST)
    5154         1387 :         idxtype = build_index_type (length);
    5155              : 
    5156        10179 :       sectype = build_array_type (eltype, idxtype);
    5157              :     }
    5158              : 
    5159        10218 :   return build3_loc (loc, OMP_ARRAY_SECTION, sectype, array_expr, index,
    5160        10218 :                      length);
    5161              : }
    5162              : 
    5163              : /* Return whether OP is an expression of enum type cast to integer
    5164              :    type.  In C++ even unsigned enum types are cast to signed integer
    5165              :    types.  We do not want to issue warnings about comparisons between
    5166              :    signed and unsigned types when one of the types is an enum type.
    5167              :    Those warnings are always false positives in practice.  */
    5168              : 
    5169              : static bool
    5170       623456 : enum_cast_to_int (tree op)
    5171              : {
    5172       610851 :   if (CONVERT_EXPR_P (op)
    5173        13616 :       && TREE_TYPE (op) == integer_type_node
    5174          895 :       && TREE_CODE (TREE_TYPE (TREE_OPERAND (op, 0))) == ENUMERAL_TYPE
    5175       623471 :       && TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op, 0))))
    5176              :     return true;
    5177              : 
    5178              :   /* The cast may have been pushed into a COND_EXPR.  */
    5179       623449 :   if (TREE_CODE (op) == COND_EXPR)
    5180          761 :     return (enum_cast_to_int (TREE_OPERAND (op, 1))
    5181          761 :             || enum_cast_to_int (TREE_OPERAND (op, 2)));
    5182              : 
    5183              :   return false;
    5184              : }
    5185              : 
    5186              : /* For the c-common bits.  */
    5187              : tree
    5188      6368757 : build_binary_op (location_t location, enum tree_code code, tree op0, tree op1,
    5189              :                  bool /*convert_p*/)
    5190              : {
    5191      6368757 :   return cp_build_binary_op (location, code, op0, op1, tf_warning_or_error);
    5192              : }
    5193              : 
    5194              : /* Build a vector comparison of ARG0 and ARG1 using CODE opcode
    5195              :    into a value of TYPE type.  Comparison is done via VEC_COND_EXPR.  */
    5196              : 
    5197              : static tree
    5198         7181 : build_vec_cmp (tree_code code, tree type,
    5199              :                tree arg0, tree arg1)
    5200              : {
    5201         7181 :   tree zero_vec = build_zero_cst (type);
    5202         7181 :   tree minus_one_vec = build_minus_one_cst (type);
    5203         7181 :   tree cmp_type = truth_type_for (TREE_TYPE (arg0));
    5204         7181 :   tree cmp = build2 (code, cmp_type, arg0, arg1);
    5205         7181 :   return build3 (VEC_COND_EXPR, type, cmp, minus_one_vec, zero_vec);
    5206              : }
    5207              : 
    5208              : /* Possibly warn about an address never being NULL.  */
    5209              : 
    5210              : static void
    5211      1892988 : warn_for_null_address (location_t location, tree op, tsubst_flags_t complain)
    5212              : {
    5213              :   /* Prevent warnings issued for macro expansion.  */
    5214      1892988 :   if (!warn_address
    5215        41234 :       || (complain & tf_warning) == 0
    5216        24641 :       || c_inhibit_evaluation_warnings != 0
    5217        24625 :       || from_macro_expansion_at (location)
    5218      1910884 :       || warning_suppressed_p (op, OPT_Waddress))
    5219      1875415 :     return;
    5220              : 
    5221        17863 :   tree cop = fold_for_warn (op);
    5222              : 
    5223        17863 :   if (TREE_CODE (cop) == NON_LVALUE_EXPR)
    5224              :     /* Unwrap the expression for C++ 98.  */
    5225            1 :     cop = TREE_OPERAND (cop, 0);
    5226              : 
    5227        17863 :   if (TREE_CODE (cop) == PTRMEM_CST)
    5228              :     {
    5229              :       /* The address of a nonstatic data member is never null.  */
    5230           30 :       warning_at (location, OPT_Waddress,
    5231              :                   "the address %qE will never be NULL",
    5232              :                   cop);
    5233           30 :       return;
    5234              :     }
    5235              : 
    5236        17833 :   if (TREE_CODE (cop) == NOP_EXPR)
    5237              :     {
    5238              :       /* Allow casts to intptr_t to suppress the warning.  */
    5239         1215 :       tree type = TREE_TYPE (cop);
    5240         1215 :       if (TREE_CODE (type) == INTEGER_TYPE)
    5241              :         return;
    5242              : 
    5243         1215 :       STRIP_NOPS (cop);
    5244              :     }
    5245              : 
    5246        17833 :   auto_diagnostic_group d;
    5247        17833 :   bool warned = false;
    5248        17833 :   if (TREE_CODE (cop) == ADDR_EXPR)
    5249              :     {
    5250          789 :       cop = TREE_OPERAND (cop, 0);
    5251              : 
    5252              :       /* Set to true in the loop below if OP dereferences its operand.
    5253              :          In such a case the ultimate target need not be a decl for
    5254              :          the null [in]equality test to be necessarily constant.  */
    5255          789 :       bool deref = false;
    5256              : 
    5257              :       /* Get the outermost array or object, or member.  */
    5258          960 :       while (handled_component_p (cop))
    5259              :         {
    5260          270 :           if (TREE_CODE (cop) == COMPONENT_REF)
    5261              :             {
    5262              :               /* Get the member (its address is never null).  */
    5263           99 :               cop = TREE_OPERAND (cop, 1);
    5264           99 :               break;
    5265              :             }
    5266              : 
    5267              :           /* Get the outer array/object to refer to in the warning.  */
    5268          171 :           cop = TREE_OPERAND (cop, 0);
    5269          171 :           deref = true;
    5270              :         }
    5271              : 
    5272          639 :       if ((!deref && !decl_with_nonnull_addr_p (cop))
    5273          631 :           || from_macro_expansion_at (location)
    5274         1420 :           || warning_suppressed_p (cop, OPT_Waddress))
    5275          158 :         return;
    5276              : 
    5277          631 :       warned = warning_at (location, OPT_Waddress,
    5278              :                            "the address of %qD will never be NULL", cop);
    5279          631 :       op = cop;
    5280              :     }
    5281        17044 :   else if (TREE_CODE (cop) == POINTER_PLUS_EXPR)
    5282              :     {
    5283              :       /* Adding zero to the null pointer is well-defined in C++.  When
    5284              :          the offset is unknown (i.e., not a constant) warn anyway since
    5285              :          it's less likely that the pointer operand is null than not.  */
    5286          102 :       tree off = TREE_OPERAND (cop, 1);
    5287          102 :       if (!integer_zerop (off)
    5288          102 :           && !warning_suppressed_p (cop, OPT_Waddress))
    5289              :         {
    5290          102 :           tree base = TREE_OPERAND (cop, 0);
    5291          102 :           STRIP_NOPS (base);
    5292          102 :           if (TYPE_REF_P (TREE_TYPE (base)))
    5293           12 :             warning_at (location, OPT_Waddress, "the compiler can assume that "
    5294              :                         "the address of %qE will never be NULL", base);
    5295              :           else
    5296           90 :             warning_at (location, OPT_Waddress, "comparing the result of "
    5297              :                         "pointer addition %qE and NULL", cop);
    5298              :         }
    5299          102 :       return;
    5300              :     }
    5301        16008 :   else if (CONVERT_EXPR_P (op)
    5302        17004 :            && TYPE_REF_P (TREE_TYPE (TREE_OPERAND (op, 0))))
    5303              :     {
    5304           62 :       STRIP_NOPS (op);
    5305              : 
    5306           62 :       if (TREE_CODE (op) == COMPONENT_REF)
    5307           24 :         op = TREE_OPERAND (op, 1);
    5308              : 
    5309           62 :       if (DECL_P (op))
    5310           62 :         warned = warning_at (location, OPT_Waddress,
    5311              :                              "the compiler can assume that the address of "
    5312              :                              "%qD will never be NULL", op);
    5313              :     }
    5314              : 
    5315          693 :   if (warned && DECL_P (op))
    5316          657 :     inform (DECL_SOURCE_LOCATION (op), "%qD declared here", op);
    5317        17833 : }
    5318              : 
    5319              : /* Warn about [expr.arith.conv]/2: If one operand is of enumeration type and
    5320              :    the other operand is of a different enumeration type or a floating-point
    5321              :    type, this behavior is deprecated ([depr.arith.conv.enum]).  CODE is the
    5322              :    code of the binary operation, TYPE0 and TYPE1 are the types of the operands,
    5323              :    and LOC is the location for the whole binary expression.
    5324              :    For C++26 this is ill-formed rather than deprecated.
    5325              :    Return true for SFINAE errors.
    5326              :    TODO: Consider combining this with -Wenum-compare in build_new_op_1.  */
    5327              : 
    5328              : static bool
    5329    117933386 : do_warn_enum_conversions (location_t loc, enum tree_code code, tree type0,
    5330              :                           tree type1, tsubst_flags_t complain)
    5331              : {
    5332    117933386 :   if (TREE_CODE (type0) == ENUMERAL_TYPE
    5333      4437329 :       && TREE_CODE (type1) == ENUMERAL_TYPE
    5334    121855412 :       && TYPE_MAIN_VARIANT (type0) != TYPE_MAIN_VARIANT (type1))
    5335              :     {
    5336          198 :       if (cxx_dialect >= cxx26)
    5337              :         {
    5338           60 :           if ((complain & tf_warning_or_error) == 0)
    5339              :             return true;
    5340              :         }
    5341          138 :       else if ((complain & tf_warning) == 0)
    5342              :         return false;
    5343              :       /* In C++20, -Wdeprecated-enum-enum-conversion is on by default.
    5344              :          Otherwise, warn if -Wenum-conversion is on.  */
    5345          190 :       enum opt_code opt;
    5346          190 :       if (warn_deprecated_enum_enum_conv)
    5347              :         opt = OPT_Wdeprecated_enum_enum_conversion;
    5348           93 :       else if (warn_enum_conversion)
    5349              :         opt = OPT_Wenum_conversion;
    5350              :       else
    5351              :         return false;
    5352              : 
    5353          119 :       switch (code)
    5354              :         {
    5355              :         case GT_EXPR:
    5356              :         case LT_EXPR:
    5357              :         case GE_EXPR:
    5358              :         case LE_EXPR:
    5359              :         case EQ_EXPR:
    5360              :         case NE_EXPR:
    5361              :           /* Comparisons are handled by -Wenum-compare.  */
    5362              :           return false;
    5363              :         case SPACESHIP_EXPR:
    5364              :           /* This is invalid, don't warn.  */
    5365              :           return false;
    5366           17 :         case BIT_AND_EXPR:
    5367           17 :         case BIT_IOR_EXPR:
    5368           17 :         case BIT_XOR_EXPR:
    5369           17 :           if (cxx_dialect >= cxx26)
    5370            5 :             pedwarn (loc, opt, "bitwise operation between different "
    5371              :                      "enumeration types %qT and %qT", type0, type1);
    5372              :           else
    5373           12 :             warning_at (loc, opt, "bitwise operation between different "
    5374              :                         "enumeration types %qT and %qT is deprecated",
    5375              :                         type0, type1);
    5376           17 :           return false;
    5377           41 :         default:
    5378           41 :           if (cxx_dialect >= cxx26)
    5379           12 :             pedwarn (loc, opt, "arithmetic between different enumeration "
    5380              :                      "types %qT and %qT", type0, type1);
    5381              :           else
    5382           29 :             warning_at (loc, opt, "arithmetic between different enumeration "
    5383              :                         "types %qT and %qT is deprecated", type0, type1);
    5384           41 :           return false;
    5385              :         }
    5386              :     }
    5387    117933188 :   else if ((TREE_CODE (type0) == ENUMERAL_TYPE
    5388      4437131 :             && SCALAR_FLOAT_TYPE_P (type1))
    5389    117933118 :            || (SCALAR_FLOAT_TYPE_P (type0)
    5390     30542192 :                && TREE_CODE (type1) == ENUMERAL_TYPE))
    5391              :     {
    5392          147 :       if (cxx_dialect >= cxx26)
    5393              :         {
    5394           46 :           if ((complain & tf_warning_or_error) == 0)
    5395              :             return true;
    5396              :         }
    5397          101 :       else if ((complain & tf_warning) == 0)
    5398              :         return false;
    5399          135 :       const bool enum_first_p = TREE_CODE (type0) == ENUMERAL_TYPE;
    5400              :       /* In C++20, -Wdeprecated-enum-float-conversion is on by default.
    5401              :          Otherwise, warn if -Wenum-conversion is on.  */
    5402          135 :       enum opt_code opt;
    5403          135 :       if (warn_deprecated_enum_float_conv)
    5404              :         opt = OPT_Wdeprecated_enum_float_conversion;
    5405           68 :       else if (warn_enum_conversion)
    5406              :         opt = OPT_Wenum_conversion;
    5407              :       else
    5408              :         return false;
    5409              : 
    5410           84 :       switch (code)
    5411              :         {
    5412           34 :         case GT_EXPR:
    5413           34 :         case LT_EXPR:
    5414           34 :         case GE_EXPR:
    5415           34 :         case LE_EXPR:
    5416           34 :         case EQ_EXPR:
    5417           34 :         case NE_EXPR:
    5418           34 :           if (enum_first_p && cxx_dialect >= cxx26)
    5419            5 :             pedwarn (loc, opt, "comparison of enumeration type %qT with "
    5420              :                      "floating-point type %qT", type0, type1);
    5421           29 :           else if (cxx_dialect >= cxx26)
    5422            5 :             pedwarn (loc, opt, "comparison of floating-point type %qT "
    5423              :                       "with enumeration type %qT", type0, type1);
    5424           24 :           else if (enum_first_p)
    5425           12 :             warning_at (loc, opt, "comparison of enumeration type %qT with "
    5426              :                         "floating-point type %qT is deprecated",
    5427              :                         type0, type1);
    5428              :           else
    5429           12 :             warning_at (loc, opt, "comparison of floating-point type %qT "
    5430              :                         "with enumeration type %qT is deprecated",
    5431              :                         type0, type1);
    5432           34 :           return false;
    5433              :         case SPACESHIP_EXPR:
    5434              :           /* This is invalid, don't warn.  */
    5435              :           return false;
    5436           38 :         default:
    5437           38 :           if (enum_first_p && cxx_dialect >= cxx26)
    5438            5 :             pedwarn (loc, opt, "arithmetic between enumeration type %qT "
    5439              :                      "and floating-point type %qT", type0, type1);
    5440           33 :           else if (cxx_dialect >= cxx26)
    5441            6 :             pedwarn (loc, opt, "arithmetic between floating-point type %qT "
    5442              :                      "and enumeration type %qT", type0, type1);
    5443           27 :           else if (enum_first_p)
    5444           12 :             warning_at (loc, opt, "arithmetic between enumeration type %qT "
    5445              :                         "and floating-point type %qT is deprecated",
    5446              :                         type0, type1);
    5447              :           else
    5448           15 :             warning_at (loc, opt, "arithmetic between floating-point type %qT "
    5449              :                         "and enumeration type %qT is deprecated",
    5450              :                         type0, type1);
    5451           38 :           return false;
    5452              :         }
    5453              :     }
    5454              :   return false;
    5455              : }
    5456              : 
    5457              : /* Build a binary-operation expression without default conversions.
    5458              :    CODE is the kind of expression to build.
    5459              :    LOCATION is the location_t of the operator in the source code.
    5460              :    This function differs from `build' in several ways:
    5461              :    the data type of the result is computed and recorded in it,
    5462              :    warnings are generated if arg data types are invalid,
    5463              :    special handling for addition and subtraction of pointers is known,
    5464              :    and some optimization is done (operations on narrow ints
    5465              :    are done in the narrower type when that gives the same result).
    5466              :    Constant folding is also done before the result is returned.
    5467              : 
    5468              :    Note that the operands will never have enumeral types
    5469              :    because either they have just had the default conversions performed
    5470              :    or they have both just been converted to some other type in which
    5471              :    the arithmetic is to be done.
    5472              : 
    5473              :    C++: must do special pointer arithmetic when implementing
    5474              :    multiple inheritance, and deal with pointer to member functions.  */
    5475              : 
    5476              : tree
    5477    160560458 : cp_build_binary_op (const op_location_t &location,
    5478              :                     enum tree_code code, tree orig_op0, tree orig_op1,
    5479              :                     tsubst_flags_t complain)
    5480              : {
    5481    160560458 :   tree op0, op1;
    5482    160560458 :   enum tree_code code0, code1;
    5483    160560458 :   tree type0, type1, orig_type0, orig_type1;
    5484    160560458 :   const char *invalid_op_diag;
    5485              : 
    5486              :   /* Expression code to give to the expression when it is built.
    5487              :      Normally this is CODE, which is what the caller asked for,
    5488              :      but in some special cases we change it.  */
    5489    160560458 :   enum tree_code resultcode = code;
    5490              : 
    5491              :   /* Data type in which the computation is to be performed.
    5492              :      In the simplest cases this is the common type of the arguments.  */
    5493    160560458 :   tree result_type = NULL_TREE;
    5494              : 
    5495              :   /* When the computation is in excess precision, the type of the
    5496              :      final EXCESS_PRECISION_EXPR.  */
    5497    160560458 :   tree semantic_result_type = NULL;
    5498              : 
    5499              :   /* Nonzero means operands have already been type-converted
    5500              :      in whatever way is necessary.
    5501              :      Zero means they need to be converted to RESULT_TYPE.  */
    5502    160560458 :   int converted = 0;
    5503              : 
    5504              :   /* Nonzero means create the expression with this type, rather than
    5505              :      RESULT_TYPE.  */
    5506    160560458 :   tree build_type = 0;
    5507              : 
    5508              :   /* Nonzero means after finally constructing the expression
    5509              :      convert it to this type.  */
    5510    160560458 :   tree final_type = 0;
    5511              : 
    5512    160560458 :   tree result;
    5513              : 
    5514              :   /* Nonzero if this is an operation like MIN or MAX which can
    5515              :      safely be computed in short if both args are promoted shorts.
    5516              :      Also implies COMMON.
    5517              :      -1 indicates a bitwise operation; this makes a difference
    5518              :      in the exact conditions for when it is safe to do the operation
    5519              :      in a narrower mode.  */
    5520    160560458 :   int shorten = 0;
    5521              : 
    5522              :   /* Nonzero if this is a comparison operation;
    5523              :      if both args are promoted shorts, compare the original shorts.
    5524              :      Also implies COMMON.  */
    5525    160560458 :   int short_compare = 0;
    5526              : 
    5527              :   /* Nonzero if this is a right-shift operation, which can be computed on the
    5528              :      original short and then promoted if the operand is a promoted short.  */
    5529    160560458 :   int short_shift = 0;
    5530              : 
    5531              :   /* Nonzero means set RESULT_TYPE to the common type of the args.  */
    5532    160560458 :   int common = 0;
    5533              : 
    5534              :   /* True if both operands have arithmetic type.  */
    5535    160560458 :   bool arithmetic_types_p;
    5536              : 
    5537              :   /* Remember whether we're doing / or %.  */
    5538    160560458 :   bool doing_div_or_mod = false;
    5539              : 
    5540              :   /* Remember whether we're doing << or >>.  */
    5541    160560458 :   bool doing_shift = false;
    5542              : 
    5543              :   /* Tree holding instrumentation expression.  */
    5544    160560458 :   tree instrument_expr = NULL_TREE;
    5545              : 
    5546              :   /* True means this is an arithmetic operation that may need excess
    5547              :      precision.  */
    5548    160560458 :   bool may_need_excess_precision;
    5549              : 
    5550              :   /* Apply default conversions.  */
    5551    160560458 :   op0 = resolve_nondeduced_context (orig_op0, complain);
    5552    160560458 :   op1 = resolve_nondeduced_context (orig_op1, complain);
    5553              : 
    5554    160560458 :   if (code == TRUTH_AND_EXPR || code == TRUTH_ANDIF_EXPR
    5555    146524152 :       || code == TRUTH_OR_EXPR || code == TRUTH_ORIF_EXPR
    5556    142601680 :       || code == TRUTH_XOR_EXPR)
    5557              :     {
    5558     17958778 :       if (!really_overloaded_fn (op0) && !VOID_TYPE_P (TREE_TYPE (op0)))
    5559     17958760 :         op0 = decay_conversion (op0, complain);
    5560     17958778 :       if (!really_overloaded_fn (op1) && !VOID_TYPE_P (TREE_TYPE (op1)))
    5561     17958778 :         op1 = decay_conversion (op1, complain);
    5562              :     }
    5563              :   else
    5564              :     {
    5565    142601680 :       if (!really_overloaded_fn (op0) && !VOID_TYPE_P (TREE_TYPE (op0)))
    5566    142601637 :         op0 = cp_default_conversion (op0, complain);
    5567    142601680 :       if (!really_overloaded_fn (op1) && !VOID_TYPE_P (TREE_TYPE (op1)))
    5568    142601661 :         op1 = cp_default_conversion (op1, complain);
    5569              :     }
    5570              : 
    5571              :   /* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue.  */
    5572    169017705 :   STRIP_TYPE_NOPS (op0);
    5573    198507438 :   STRIP_TYPE_NOPS (op1);
    5574              : 
    5575              :   /* DTRT if one side is an overloaded function, but complain about it.  */
    5576    160560458 :   if (type_unknown_p (op0))
    5577              :     {
    5578            9 :       tree t = instantiate_type (TREE_TYPE (op1), op0, tf_none);
    5579            9 :       if (t != error_mark_node)
    5580              :         {
    5581            0 :           if (complain & tf_error)
    5582            0 :             permerror (location,
    5583              :                        "assuming cast to type %qT from overloaded function",
    5584            0 :                        TREE_TYPE (t));
    5585              :           op0 = t;
    5586              :         }
    5587              :     }
    5588    160560458 :   if (type_unknown_p (op1))
    5589              :     {
    5590            3 :       tree t = instantiate_type (TREE_TYPE (op0), op1, tf_none);
    5591            3 :       if (t != error_mark_node)
    5592              :         {
    5593            3 :           if (complain & tf_error)
    5594            3 :             permerror (location,
    5595              :                        "assuming cast to type %qT from overloaded function",
    5596            3 :                        TREE_TYPE (t));
    5597              :           op1 = t;
    5598              :         }
    5599              :     }
    5600              : 
    5601    160560458 :   orig_type0 = type0 = TREE_TYPE (op0);
    5602    160560458 :   orig_type1 = type1 = TREE_TYPE (op1);
    5603    160560458 :   tree non_ep_op0 = op0;
    5604    160560458 :   tree non_ep_op1 = op1;
    5605              : 
    5606              :   /* The expression codes of the data types of the arguments tell us
    5607              :      whether the arguments are integers, floating, pointers, etc.  */
    5608    160560458 :   code0 = TREE_CODE (type0);
    5609    160560458 :   code1 = TREE_CODE (type1);
    5610              : 
    5611              :   /* If an error was already reported for one of the arguments,
    5612              :      avoid reporting another error.  */
    5613    160560458 :   if (code0 == ERROR_MARK || code1 == ERROR_MARK)
    5614           99 :     return error_mark_node;
    5615              : 
    5616    321120718 :   if ((invalid_op_diag
    5617    160560359 :        = targetm.invalid_binary_op (code, type0, type1)))
    5618              :     {
    5619            0 :       if (complain & tf_error)
    5620              :         {
    5621            0 :           if (code0 == REAL_TYPE
    5622            0 :               && code1 == REAL_TYPE
    5623            0 :               && (extended_float_type_p (type0)
    5624            0 :                   || extended_float_type_p (type1))
    5625            0 :               && cp_compare_floating_point_conversion_ranks (type0,
    5626              :                                                              type1) == 3)
    5627              :             {
    5628            0 :               rich_location richloc (line_table, location);
    5629            0 :               binary_op_error (&richloc, code, type0, type1);
    5630            0 :             }
    5631              :           else
    5632            0 :             error (invalid_op_diag);
    5633              :         }
    5634            0 :       return error_mark_node;
    5635              :     }
    5636              : 
    5637    160560359 :   switch (code)
    5638              :     {
    5639              :     case PLUS_EXPR:
    5640              :     case MINUS_EXPR:
    5641              :     case MULT_EXPR:
    5642              :     case TRUNC_DIV_EXPR:
    5643              :     case CEIL_DIV_EXPR:
    5644              :     case FLOOR_DIV_EXPR:
    5645              :     case ROUND_DIV_EXPR:
    5646              :     case EXACT_DIV_EXPR:
    5647              :       may_need_excess_precision = true;
    5648              :       break;
    5649     60342951 :     case EQ_EXPR:
    5650     60342951 :     case NE_EXPR:
    5651     60342951 :     case LE_EXPR:
    5652     60342951 :     case GE_EXPR:
    5653     60342951 :     case LT_EXPR:
    5654     60342951 :     case GT_EXPR:
    5655     60342951 :     case SPACESHIP_EXPR:
    5656              :       /* Excess precision for implicit conversions of integers to
    5657              :          floating point.  */
    5658     12542969 :       may_need_excess_precision = (ANY_INTEGRAL_TYPE_P (type0)
    5659     72879309 :                                    || ANY_INTEGRAL_TYPE_P (type1));
    5660              :       break;
    5661              :     default:
    5662    160560359 :       may_need_excess_precision = false;
    5663              :       break;
    5664              :     }
    5665    160560359 :   if (TREE_CODE (op0) == EXCESS_PRECISION_EXPR)
    5666              :     {
    5667        10584 :       op0 = TREE_OPERAND (op0, 0);
    5668        10584 :       type0 = TREE_TYPE (op0);
    5669              :     }
    5670    160549775 :   else if (may_need_excess_precision
    5671    121725142 :            && (code0 == REAL_TYPE || code0 == COMPLEX_TYPE))
    5672     26654230 :     if (tree eptype = excess_precision_type (type0))
    5673              :       {
    5674        28017 :         type0 = eptype;
    5675        28017 :         op0 = convert (eptype, op0);
    5676              :       }
    5677    160560359 :   if (TREE_CODE (op1) == EXCESS_PRECISION_EXPR)
    5678              :     {
    5679        13202 :       op1 = TREE_OPERAND (op1, 0);
    5680        13202 :       type1 = TREE_TYPE (op1);
    5681              :     }
    5682    160547157 :   else if (may_need_excess_precision
    5683    121724059 :            && (code1 == REAL_TYPE || code1 == COMPLEX_TYPE))
    5684     26514492 :     if (tree eptype = excess_precision_type (type1))
    5685              :       {
    5686        19031 :         type1 = eptype;
    5687        19031 :         op1 = convert (eptype, op1);
    5688              :       }
    5689              : 
    5690              :   /* Issue warnings about peculiar, but valid, uses of NULL.  */
    5691    321120633 :   if ((null_node_p (orig_op0) || null_node_p (orig_op1))
    5692              :       /* It's reasonable to use pointer values as operands of &&
    5693              :          and ||, so NULL is no exception.  */
    5694        11878 :       && code != TRUTH_ANDIF_EXPR && code != TRUTH_ORIF_EXPR
    5695        11863 :       && ( /* Both are NULL (or 0) and the operation was not a
    5696              :               comparison or a pointer subtraction.  */
    5697        11936 :           (null_ptr_cst_p (orig_op0) && null_ptr_cst_p (orig_op1)
    5698           27 :            && code != EQ_EXPR && code != NE_EXPR && code != MINUS_EXPR)
    5699              :           /* Or if one of OP0 or OP1 is neither a pointer nor NULL.  */
    5700        11851 :           || (!null_ptr_cst_p (orig_op0)
    5701        11790 :               && !TYPE_PTR_OR_PTRMEM_P (type0))
    5702        11839 :           || (!null_ptr_cst_p (orig_op1)
    5703           46 :               && !TYPE_PTR_OR_PTRMEM_P (type1)))
    5704    160560398 :       && (complain & tf_warning))
    5705              :     {
    5706           39 :       location_t loc =
    5707           39 :         expansion_point_location_if_in_system_header (input_location);
    5708              : 
    5709           39 :       warning_at (loc, OPT_Wpointer_arith, "NULL used in arithmetic");
    5710              :     }
    5711              : 
    5712              :   /* In case when one of the operands of the binary operation is
    5713              :      a vector and another is a scalar -- convert scalar to vector.  */
    5714    160627240 :   if ((gnu_vector_type_p (type0) && code1 != VECTOR_TYPE)
    5715    160626389 :       || (gnu_vector_type_p (type1) && code0 != VECTOR_TYPE))
    5716              :     {
    5717          936 :       enum stv_conv convert_flag
    5718          936 :         = scalar_to_vector (location, code, non_ep_op0, non_ep_op1,
    5719              :                             complain & tf_error);
    5720              : 
    5721          936 :       switch (convert_flag)
    5722              :         {
    5723           21 :           case stv_error:
    5724           21 :             return error_mark_node;
    5725           55 :           case stv_firstarg:
    5726           55 :             {
    5727           55 :               op0 = convert (TREE_TYPE (type1), op0);
    5728           55 :               op0 = cp_save_expr (op0);
    5729           55 :               op0 = build_vector_from_val (type1, op0);
    5730           55 :               orig_type0 = type0 = TREE_TYPE (op0);
    5731           55 :               code0 = TREE_CODE (type0);
    5732           55 :               converted = 1;
    5733           55 :               break;
    5734              :             }
    5735          755 :           case stv_secondarg:
    5736          755 :             {
    5737          755 :               op1 = convert (TREE_TYPE (type0), op1);
    5738          755 :               op1 = cp_save_expr (op1);
    5739          755 :               op1 = build_vector_from_val (type0, op1);
    5740          755 :               orig_type1 = type1 = TREE_TYPE (op1);
    5741          755 :               code1 = TREE_CODE (type1);
    5742          755 :               converted = 1;
    5743          755 :               break;
    5744              :             }
    5745              :           default:
    5746              :             break;
    5747              :         }
    5748              :     }
    5749              : 
    5750    160560338 :   switch (code)
    5751              :     {
    5752     17660978 :     case MINUS_EXPR:
    5753              :       /* Subtraction of two similar pointers.
    5754              :          We must subtract them as integers, then divide by object size.  */
    5755     17660978 :       if (code0 == POINTER_TYPE && code1 == POINTER_TYPE
    5756     19737066 :           && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (type0),
    5757      2076088 :                                                         TREE_TYPE (type1)))
    5758              :         {
    5759      2076086 :           result = pointer_diff (location, op0, op1,
    5760              :                                  common_pointer_type (type0, type1), complain,
    5761              :                                  &instrument_expr);
    5762      2076086 :           if (instrument_expr != NULL)
    5763           84 :             result = build2 (COMPOUND_EXPR, TREE_TYPE (result),
    5764              :                              instrument_expr, result);
    5765              : 
    5766      2076086 :           return result;
    5767              :         }
    5768              :       /* In all other cases except pointer - int, the usual arithmetic
    5769              :          rules apply.  */
    5770     15584892 :       else if (!(code0 == POINTER_TYPE && code1 == INTEGER_TYPE))
    5771              :         {
    5772              :           common = 1;
    5773              :           break;
    5774              :         }
    5775              :       /* The pointer - int case is just like pointer + int; fall
    5776              :          through.  */
    5777     24395856 :       gcc_fallthrough ();
    5778     24395856 :     case PLUS_EXPR:
    5779     24395856 :       if ((code0 == POINTER_TYPE || code1 == POINTER_TYPE)
    5780     10139275 :           && (code0 == INTEGER_TYPE || code1 == INTEGER_TYPE))
    5781              :         {
    5782     10139266 :           tree ptr_operand;
    5783     10139266 :           tree int_operand;
    5784     10139266 :           ptr_operand = ((code0 == POINTER_TYPE) ? op0 : op1);
    5785       138910 :           int_operand = ((code0 == INTEGER_TYPE) ? op0 : op1);
    5786     10139266 :           if (processing_template_decl)
    5787              :             {
    5788      2164856 :               result_type = TREE_TYPE (ptr_operand);
    5789      2164856 :               break;
    5790              :             }
    5791      7974410 :           return cp_pointer_int_sum (location, code,
    5792              :                                      ptr_operand,
    5793              :                                      int_operand,
    5794      7974410 :                                      complain);
    5795              :         }
    5796              :       common = 1;
    5797              :       break;
    5798              : 
    5799              :     case MULT_EXPR:
    5800    150415839 :       common = 1;
    5801              :       break;
    5802              : 
    5803     12011903 :     case TRUNC_DIV_EXPR:
    5804     12011903 :     case CEIL_DIV_EXPR:
    5805     12011903 :     case FLOOR_DIV_EXPR:
    5806     12011903 :     case ROUND_DIV_EXPR:
    5807     12011903 :     case EXACT_DIV_EXPR:
    5808     12011903 :       if (TREE_CODE (op0) == SIZEOF_EXPR && TREE_CODE (op1) == SIZEOF_EXPR)
    5809              :         {
    5810       116100 :           tree type0 = TREE_OPERAND (op0, 0);
    5811       116100 :           tree type1 = TREE_OPERAND (op1, 0);
    5812       116100 :           tree first_arg = tree_strip_any_location_wrapper (type0);
    5813       116100 :           if (!TYPE_P (type0))
    5814        76138 :             type0 = TREE_TYPE (type0);
    5815       116100 :           if (!TYPE_P (type1))
    5816        42201 :             type1 = TREE_TYPE (type1);
    5817       116100 :           if (type0
    5818       116100 :               && type1
    5819        97161 :               && INDIRECT_TYPE_P (type0)
    5820       116175 :               && same_type_p (TREE_TYPE (type0), type1))
    5821              :             {
    5822           27 :               if (!(TREE_CODE (first_arg) == PARM_DECL
    5823           21 :                     && DECL_ARRAY_PARAMETER_P (first_arg)
    5824            3 :                     && warn_sizeof_array_argument)
    5825           42 :                   && (complain & tf_warning))
    5826              :                 {
    5827           21 :                   auto_diagnostic_group d;
    5828           21 :                   if (warning_at (location, OPT_Wsizeof_pointer_div,
    5829              :                                   "division %<sizeof (%T) / sizeof (%T)%> does "
    5830              :                                   "not compute the number of array elements",
    5831              :                                   type0, type1))
    5832           18 :                     if (DECL_P (first_arg))
    5833           18 :                       inform (DECL_SOURCE_LOCATION (first_arg),
    5834              :                               "first %<sizeof%> operand was declared here");
    5835           21 :                 }
    5836              :             }
    5837       116076 :           else if (!dependent_type_p (type0)
    5838        23363 :                    && !dependent_type_p (type1)
    5839        23265 :                    && TREE_CODE (type0) == ARRAY_TYPE
    5840        20863 :                    && !char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type0)))
    5841              :                    /* Set by finish_parenthesized_expr.  */
    5842        20215 :                    && !warning_suppressed_p (op1, OPT_Wsizeof_array_div)
    5843       136273 :                    && (complain & tf_warning))
    5844        20197 :             maybe_warn_sizeof_array_div (location, first_arg, type0,
    5845              :                                          op1, non_reference (type1));
    5846              :         }
    5847              : 
    5848     12011903 :       if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
    5849              :            || code0 == COMPLEX_TYPE || code0 == VECTOR_TYPE)
    5850     12011885 :           && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
    5851              :               || code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE))
    5852              :         {
    5853     12011876 :           enum tree_code tcode0 = code0, tcode1 = code1;
    5854     12011876 :           doing_div_or_mod = true;
    5855     12011876 :           warn_for_div_by_zero (location, fold_for_warn (op1));
    5856              : 
    5857     12011876 :           if (tcode0 == COMPLEX_TYPE || tcode0 == VECTOR_TYPE)
    5858        56647 :             tcode0 = TREE_CODE (TREE_TYPE (TREE_TYPE (op0)));
    5859     12011876 :           if (tcode1 == COMPLEX_TYPE || tcode1 == VECTOR_TYPE)
    5860        29178 :             tcode1 = TREE_CODE (TREE_TYPE (TREE_TYPE (op1)));
    5861              : 
    5862     12011879 :           if (!((tcode0 == INTEGER_TYPE
    5863      5222734 :                  || (tcode0 == ENUMERAL_TYPE && code0 == VECTOR_TYPE))
    5864              :                 && (tcode1 == INTEGER_TYPE
    5865        93458 :                     || (tcode1 == ENUMERAL_TYPE && code1 == VECTOR_TYPE))))
    5866              :             resultcode = RDIV_EXPR;
    5867              :           else
    5868              :             {
    5869              :               /* When dividing two signed integers, we have to promote to int.
    5870              :                  unless we divide by a constant != -1.  Note that default
    5871              :                  conversion will have been performed on the operands at this
    5872              :                  point, so we have to dig out the original type to find out if
    5873              :                  it was unsigned.  */
    5874      6695690 :               tree stripped_op1 = tree_strip_any_location_wrapper (op1);
    5875      6695690 :               shorten = may_shorten_divmod (op0, stripped_op1);
    5876              :             }
    5877              : 
    5878              :           common = 1;
    5879              :         }
    5880              :       break;
    5881              : 
    5882      3062049 :     case BIT_AND_EXPR:
    5883      3062049 :     case BIT_IOR_EXPR:
    5884      3062049 :     case BIT_XOR_EXPR:
    5885      3062049 :       if ((code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
    5886      3062049 :           || (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE
    5887        20780 :               && !VECTOR_FLOAT_TYPE_P (type0)
    5888        20762 :               && !VECTOR_FLOAT_TYPE_P (type1)))
    5889              :         shorten = -1;
    5890              :       break;
    5891              : 
    5892      1499629 :     case TRUNC_MOD_EXPR:
    5893      1499629 :     case FLOOR_MOD_EXPR:
    5894      1499629 :       doing_div_or_mod = true;
    5895      1499629 :       warn_for_div_by_zero (location, fold_for_warn (op1));
    5896              : 
    5897      1499629 :       if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE
    5898           20 :           && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE
    5899      1499649 :           && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE)
    5900              :         common = 1;
    5901      1499609 :       else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
    5902              :         {
    5903              :           /* Although it would be tempting to shorten always here, that loses
    5904              :              on some targets, since the modulo instruction is undefined if the
    5905              :              quotient can't be represented in the computation mode.  We shorten
    5906              :              only if unsigned or if dividing by something we know != -1.  */
    5907      1499585 :           tree stripped_op1 = tree_strip_any_location_wrapper (op1);
    5908      1499585 :           shorten = may_shorten_divmod (op0, stripped_op1);
    5909      1499585 :           common = 1;
    5910              :         }
    5911              :       break;
    5912              : 
    5913     17958763 :     case TRUTH_ANDIF_EXPR:
    5914     17958763 :     case TRUTH_ORIF_EXPR:
    5915     17958763 :     case TRUTH_AND_EXPR:
    5916     17958763 :     case TRUTH_OR_EXPR:
    5917     17958763 :       if (!VECTOR_TYPE_P (type0) && gnu_vector_type_p (type1))
    5918              :         {
    5919            3 :           if (!COMPARISON_CLASS_P (op1))
    5920            3 :             op1 = cp_build_binary_op (EXPR_LOCATION (op1), NE_EXPR, op1,
    5921              :                                       build_zero_cst (type1), complain);
    5922            3 :           if (code == TRUTH_ANDIF_EXPR)
    5923              :             {
    5924            0 :               tree z = build_zero_cst (TREE_TYPE (op1));
    5925            0 :               return build_conditional_expr (location, op0, op1, z, complain);
    5926              :             }
    5927            3 :           else if (code == TRUTH_ORIF_EXPR)
    5928              :             {
    5929            3 :               tree m1 = build_all_ones_cst (TREE_TYPE (op1));
    5930            3 :               return build_conditional_expr (location, op0, m1, op1, complain);
    5931              :             }
    5932              :           else
    5933            0 :             gcc_unreachable ();
    5934              :         }
    5935     17958760 :       if (gnu_vector_type_p (type0)
    5936     17958760 :           && (!VECTOR_TYPE_P (type1) || gnu_vector_type_p (type1)))
    5937              :         {
    5938           24 :           if (!COMPARISON_CLASS_P (op0))
    5939           24 :             op0 = cp_build_binary_op (EXPR_LOCATION (op0), NE_EXPR, op0,
    5940              :                                       build_zero_cst (type0), complain);
    5941           24 :           if (!VECTOR_TYPE_P (type1))
    5942              :             {
    5943            9 :               tree m1 = build_all_ones_cst (TREE_TYPE (op0));
    5944            9 :               tree z = build_zero_cst (TREE_TYPE (op0));
    5945            9 :               op1 = build_conditional_expr (location, op1, m1, z, complain);
    5946              :             }
    5947           15 :           else if (!COMPARISON_CLASS_P (op1))
    5948           15 :             op1 = cp_build_binary_op (EXPR_LOCATION (op1), NE_EXPR, op1,
    5949              :                                       build_zero_cst (type1), complain);
    5950              : 
    5951           24 :           if (code == TRUTH_ANDIF_EXPR)
    5952              :             code = BIT_AND_EXPR;
    5953            9 :           else if (code == TRUTH_ORIF_EXPR)
    5954              :             code = BIT_IOR_EXPR;
    5955              :           else
    5956            0 :             gcc_unreachable ();
    5957              : 
    5958           24 :           return cp_build_binary_op (location, code, op0, op1, complain);
    5959              :         }
    5960              : 
    5961     17958736 :       result_type = boolean_type_node;
    5962     17958736 :       break;
    5963              : 
    5964              :       /* Shift operations: result has same type as first operand;
    5965              :          always convert second operand to int.
    5966              :          Also set SHORT_SHIFT if shifting rightward.  */
    5967              : 
    5968      1135374 :     case RSHIFT_EXPR:
    5969      1135374 :       if (gnu_vector_type_p (type0)
    5970          170 :           && code1 == INTEGER_TYPE
    5971      1135421 :           && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE)
    5972              :         {
    5973              :           result_type = type0;
    5974              :           converted = 1;
    5975              :         }
    5976      1135327 :       else if (gnu_vector_type_p (type0)
    5977          123 :                && gnu_vector_type_p (type1)
    5978          123 :                && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE
    5979          120 :                && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE
    5980      1135447 :                && known_eq (TYPE_VECTOR_SUBPARTS (type0),
    5981              :                             TYPE_VECTOR_SUBPARTS (type1)))
    5982              :         {
    5983              :           result_type = type0;
    5984              :           converted = 1;
    5985              :         }
    5986      1135207 :       else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
    5987              :         {
    5988      1135180 :           tree const_op1 = fold_for_warn (op1);
    5989      1135180 :           if (TREE_CODE (const_op1) != INTEGER_CST)
    5990       115254 :             const_op1 = op1;
    5991      1135180 :           result_type = type0;
    5992      1135180 :           doing_shift = true;
    5993      1135180 :           if (TREE_CODE (const_op1) == INTEGER_CST)
    5994              :             {
    5995      1019926 :               if (tree_int_cst_lt (const_op1, integer_zero_node))
    5996              :                 {
    5997           48 :                   if ((complain & tf_warning)
    5998           48 :                       && c_inhibit_evaluation_warnings == 0)
    5999           36 :                     warning_at (location, OPT_Wshift_count_negative,
    6000              :                                 "right shift count is negative");
    6001              :                 }
    6002              :               else
    6003              :                 {
    6004      1019878 :                   if (!integer_zerop (const_op1))
    6005      1019679 :                     short_shift = 1;
    6006              : 
    6007      1019878 :                   if (compare_tree_int (const_op1, TYPE_PRECISION (type0)) >= 0
    6008           46 :                       && (complain & tf_warning)
    6009      1019924 :                       && c_inhibit_evaluation_warnings == 0)
    6010           34 :                     warning_at (location, OPT_Wshift_count_overflow,
    6011              :                                 "right shift count >= width of type");
    6012              :                 }
    6013              :             }
    6014              :           /* Avoid converting op1 to result_type later.  */
    6015              :           converted = 1;
    6016              :         }
    6017              :       break;
    6018              : 
    6019      3112192 :     case LSHIFT_EXPR:
    6020      3112192 :       if (gnu_vector_type_p (type0)
    6021          183 :           && code1 == INTEGER_TYPE
    6022      3112229 :           && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE)
    6023              :         {
    6024              :           result_type = type0;
    6025              :           converted = 1;
    6026              :         }
    6027      3112155 :       else if (gnu_vector_type_p (type0)
    6028          146 :                && gnu_vector_type_p (type1)
    6029          146 :                && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE
    6030          143 :                && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE
    6031      3112295 :                && known_eq (TYPE_VECTOR_SUBPARTS (type0),
    6032              :                             TYPE_VECTOR_SUBPARTS (type1)))
    6033              :         {
    6034              :           result_type = type0;
    6035              :           converted = 1;
    6036              :         }
    6037      3112015 :       else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
    6038              :         {
    6039      3111984 :           tree const_op0 = fold_for_warn (op0);
    6040      3111984 :           if (TREE_CODE (const_op0) != INTEGER_CST)
    6041       308214 :             const_op0 = op0;
    6042      3111984 :           tree const_op1 = fold_for_warn (op1);
    6043      3111984 :           if (TREE_CODE (const_op1) != INTEGER_CST)
    6044       213954 :             const_op1 = op1;
    6045      3111984 :           result_type = type0;
    6046      3111984 :           doing_shift = true;
    6047      3111984 :           if (TREE_CODE (const_op0) == INTEGER_CST
    6048      2803770 :               && tree_int_cst_sgn (const_op0) < 0
    6049          280 :               && !TYPE_OVERFLOW_WRAPS (type0)
    6050          196 :               && (complain & tf_warning)
    6051      3112180 :               && c_inhibit_evaluation_warnings == 0)
    6052          196 :             warning_at (location, OPT_Wshift_negative_value,
    6053              :                         "left shift of negative value");
    6054      3111984 :           if (TREE_CODE (const_op1) == INTEGER_CST)
    6055              :             {
    6056      2898030 :               if (tree_int_cst_lt (const_op1, integer_zero_node))
    6057              :                 {
    6058           57 :                   if ((complain & tf_warning)
    6059           57 :                       && c_inhibit_evaluation_warnings == 0)
    6060           39 :                     warning_at (location, OPT_Wshift_count_negative,
    6061              :                                 "left shift count is negative");
    6062              :                 }
    6063      2897973 :               else if (compare_tree_int (const_op1,
    6064      2897973 :                                          TYPE_PRECISION (type0)) >= 0)
    6065              :                 {
    6066           83 :                   if ((complain & tf_warning)
    6067           61 :                       && c_inhibit_evaluation_warnings == 0)
    6068           45 :                     warning_at (location, OPT_Wshift_count_overflow,
    6069              :                                 "left shift count >= width of type");
    6070              :                 }
    6071      2897890 :               else if (TREE_CODE (const_op0) == INTEGER_CST
    6072      2626731 :                        && (complain & tf_warning))
    6073      2505669 :                 maybe_warn_shift_overflow (location, const_op0, const_op1);
    6074              :             }
    6075              :           /* Avoid converting op1 to result_type later.  */
    6076              :           converted = 1;
    6077              :         }
    6078              :       break;
    6079              : 
    6080     32756158 :     case EQ_EXPR:
    6081     32756158 :     case NE_EXPR:
    6082     32756158 :       if (gnu_vector_type_p (type0) && gnu_vector_type_p (type1))
    6083         2655 :         goto vector_compare;
    6084     32753503 :       if ((complain & tf_warning)
    6085     29248283 :           && c_inhibit_evaluation_warnings == 0
    6086     60730042 :           && (FLOAT_TYPE_P (type0) || FLOAT_TYPE_P (type1)))
    6087       785759 :         warning_at (location, OPT_Wfloat_equal,
    6088              :                     "comparing floating-point with %<==%> "
    6089              :                     "or %<!=%> is unsafe");
    6090     32753503 :       {
    6091     32753503 :         tree stripped_orig_op0 = tree_strip_any_location_wrapper (orig_op0);
    6092     32753503 :         tree stripped_orig_op1 = tree_strip_any_location_wrapper (orig_op1);
    6093     32753503 :         if ((complain & tf_warning_or_error)
    6094     32753503 :             && ((TREE_CODE (stripped_orig_op0) == STRING_CST
    6095           39 :                  && !integer_zerop (cp_fully_fold (op1)))
    6096     29912377 :                 || (TREE_CODE (stripped_orig_op1) == STRING_CST
    6097           68 :                     && !integer_zerop (cp_fully_fold (op0)))))
    6098           47 :           warning_at (location, OPT_Waddress,
    6099              :                       "comparison with string literal results in "
    6100              :                       "unspecified behavior");
    6101     32753456 :         else if (TREE_CODE (TREE_TYPE (orig_op0)) == ARRAY_TYPE
    6102     32753456 :                  && TREE_CODE (TREE_TYPE (orig_op1)) == ARRAY_TYPE)
    6103              :           {
    6104              :             /* P2865R5 made array comparisons ill-formed in C++26.  */
    6105           68 :             if (complain & tf_warning_or_error)
    6106           45 :               do_warn_array_compare (location, code, stripped_orig_op0,
    6107              :                                      stripped_orig_op1);
    6108           23 :             else if (cxx_dialect >= cxx26)
    6109            1 :               return error_mark_node;
    6110              :           }
    6111              :       }
    6112              : 
    6113     32753502 :       build_type = boolean_type_node;
    6114     32753502 :       if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
    6115              :            || code0 == COMPLEX_TYPE || code0 == ENUMERAL_TYPE)
    6116     27715259 :           && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
    6117              :               || code1 == COMPLEX_TYPE || code1 == ENUMERAL_TYPE))
    6118              :         short_compare = 1;
    6119        90678 :       else if (((code0 == POINTER_TYPE || TYPE_PTRDATAMEM_P (type0))
    6120      5035792 :                 && null_ptr_cst_p (orig_op1))
    6121              :                /* Handle, eg, (void*)0 (c++/43906), and more.  */
    6122      8377874 :                || (code0 == POINTER_TYPE
    6123      3162033 :                    && TYPE_PTR_P (type1) && integer_zerop (op1)))
    6124              :         {
    6125      1891815 :           if (TYPE_PTR_P (type1))
    6126        18441 :             result_type = composite_pointer_type (location,
    6127              :                                                   type0, type1, op0, op1,
    6128              :                                                   CPO_COMPARISON, complain);
    6129              :           else
    6130              :             result_type = type0;
    6131              : 
    6132      1891815 :           if (char_type_p (TREE_TYPE (orig_op1)))
    6133              :             {
    6134           10 :               auto_diagnostic_group d;
    6135           10 :               if (warning_at (location, OPT_Wpointer_compare,
    6136              :                               "comparison between pointer and zero character "
    6137              :                               "constant"))
    6138           10 :                 inform (location,
    6139              :                         "did you mean to dereference the pointer?");
    6140           10 :             }
    6141      1891815 :           warn_for_null_address (location, op0, complain);
    6142              :         }
    6143         2906 :       else if (((code1 == POINTER_TYPE || TYPE_PTRDATAMEM_P (type1))
    6144      3231312 :                 && null_ptr_cst_p (orig_op0))
    6145              :                /* Handle, eg, (void*)0 (c++/43906), and more.  */
    6146      6466725 :                || (code1 == POINTER_TYPE
    6147      3230034 :                    && TYPE_PTR_P (type0) && integer_zerop (op0)))
    6148              :         {
    6149          961 :           if (TYPE_PTR_P (type0))
    6150           68 :             result_type = composite_pointer_type (location,
    6151              :                                                   type0, type1, op0, op1,
    6152              :                                                   CPO_COMPARISON, complain);
    6153              :           else
    6154              :             result_type = type1;
    6155              : 
    6156          961 :           if (char_type_p (TREE_TYPE (orig_op0)))
    6157              :             {
    6158           10 :               auto_diagnostic_group d;
    6159           10 :               if (warning_at (location, OPT_Wpointer_compare,
    6160              :                              "comparison between pointer and zero character "
    6161              :                              "constant"))
    6162           10 :                 inform (location,
    6163              :                         "did you mean to dereference the pointer?");
    6164           10 :             }
    6165          961 :           warn_for_null_address (location, op1, complain);
    6166              :         }
    6167      3232848 :       else if ((code0 == POINTER_TYPE && code1 == POINTER_TYPE)
    6168        89382 :                || (TYPE_PTRDATAMEM_P (type0) && TYPE_PTRDATAMEM_P (type1)))
    6169      3143851 :         result_type = composite_pointer_type (location,
    6170              :                                               type0, type1, op0, op1,
    6171              :                                               CPO_COMPARISON, complain);
    6172        88997 :       else if (null_ptr_cst_p (orig_op0) && null_ptr_cst_p (orig_op1))
    6173              :         /* One of the operands must be of nullptr_t type.  */
    6174           67 :         result_type = TREE_TYPE (nullptr_node);
    6175        88930 :       else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
    6176              :         {
    6177           58 :           result_type = type0;
    6178           58 :           if (complain & tf_error)
    6179           56 :             permerror (location, "ISO C++ forbids comparison between "
    6180              :                        "pointer and integer");
    6181              :           else
    6182            2 :             return error_mark_node;
    6183              :         }
    6184        88872 :       else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
    6185              :         {
    6186        86500 :           result_type = type1;
    6187        86500 :           if (complain & tf_error)
    6188           69 :             permerror (location, "ISO C++ forbids comparison between "
    6189              :                        "pointer and integer");
    6190              :           else
    6191        86431 :             return error_mark_node;
    6192              :         }
    6193         2372 :       else if (TYPE_PTRMEMFUNC_P (type0) && null_ptr_cst_p (orig_op1))
    6194              :         {
    6195          212 :           if (TARGET_PTRMEMFUNC_VBIT_LOCATION
    6196              :               == ptrmemfunc_vbit_in_delta)
    6197              :             {
    6198              :               tree pfn0, delta0, e1, e2;
    6199              : 
    6200              :               if (TREE_SIDE_EFFECTS (op0))
    6201              :                 op0 = cp_save_expr (op0);
    6202              : 
    6203              :               pfn0 = pfn_from_ptrmemfunc (op0);
    6204              :               delta0 = delta_from_ptrmemfunc (op0);
    6205              :               {
    6206              :                 /* If we will warn below about a null-address compare
    6207              :                    involving the orig_op0 ptrmemfunc, we'd likely also
    6208              :                    warn about the pfn0's null-address compare, and
    6209              :                    that would be redundant, so suppress it.  */
    6210              :                 warning_sentinel ws (warn_address);
    6211              :                 e1 = cp_build_binary_op (location,
    6212              :                                          EQ_EXPR,
    6213              :                                          pfn0,
    6214              :                                          build_zero_cst (TREE_TYPE (pfn0)),
    6215              :                                          complain);
    6216              :               }
    6217              :               e2 = cp_build_binary_op (location,
    6218              :                                        BIT_AND_EXPR,
    6219              :                                        delta0,
    6220              :                                        integer_one_node,
    6221              :                                        complain);
    6222              : 
    6223              :               if (complain & tf_warning)
    6224              :                 maybe_warn_zero_as_null_pointer_constant (op1, input_location);
    6225              : 
    6226              :               e2 = cp_build_binary_op (location,
    6227              :                                        EQ_EXPR, e2, integer_zero_node,
    6228              :                                        complain);
    6229              :               op0 = cp_build_binary_op (location,
    6230              :                                         TRUTH_ANDIF_EXPR, e1, e2,
    6231              :                                         complain);
    6232              :               op1 = cp_convert (TREE_TYPE (op0), integer_one_node, complain);
    6233              :             }
    6234              :           else
    6235              :             {
    6236          212 :               op0 = build_ptrmemfunc_access_expr (op0, pfn_identifier);
    6237          212 :               op1 = cp_convert (TREE_TYPE (op0), op1, complain);
    6238              :             }
    6239          212 :           result_type = TREE_TYPE (op0);
    6240              : 
    6241          212 :           warn_for_null_address (location, orig_op0, complain);
    6242              :         }
    6243         2160 :       else if (TYPE_PTRMEMFUNC_P (type1) && null_ptr_cst_p (orig_op0))
    6244           36 :         return cp_build_binary_op (location, code, op1, op0, complain);
    6245         2124 :       else if (TYPE_PTRMEMFUNC_P (type0) && TYPE_PTRMEMFUNC_P (type1))
    6246              :         {
    6247          125 :           tree type;
    6248              :           /* E will be the final comparison.  */
    6249          125 :           tree e;
    6250              :           /* E1 and E2 are for scratch.  */
    6251          125 :           tree e1;
    6252          125 :           tree e2;
    6253          125 :           tree pfn0;
    6254          125 :           tree pfn1;
    6255          125 :           tree delta0;
    6256          125 :           tree delta1;
    6257              : 
    6258          125 :           type = composite_pointer_type (location, type0, type1, op0, op1,
    6259              :                                          CPO_COMPARISON, complain);
    6260              : 
    6261          125 :           if (!same_type_p (TREE_TYPE (op0), type))
    6262            6 :             op0 = cp_convert_and_check (type, op0, complain);
    6263          125 :           if (!same_type_p (TREE_TYPE (op1), type))
    6264            9 :             op1 = cp_convert_and_check (type, op1, complain);
    6265              : 
    6266          125 :           if (op0 == error_mark_node || op1 == error_mark_node)
    6267              :             return error_mark_node;
    6268              : 
    6269          122 :           if (TREE_SIDE_EFFECTS (op0))
    6270           61 :             op0 = cp_save_expr (op0);
    6271          122 :           if (TREE_SIDE_EFFECTS (op1))
    6272            3 :             op1 = cp_save_expr (op1);
    6273              : 
    6274          122 :           pfn0 = pfn_from_ptrmemfunc (op0);
    6275          122 :           pfn0 = cp_fully_fold (pfn0);
    6276              :           /* Avoid -Waddress warnings (c++/64877).  */
    6277          122 :           if (TREE_CODE (pfn0) == ADDR_EXPR)
    6278           16 :             suppress_warning (pfn0, OPT_Waddress);
    6279          122 :           pfn1 = pfn_from_ptrmemfunc (op1);
    6280          122 :           pfn1 = cp_fully_fold (pfn1);
    6281          122 :           delta0 = delta_from_ptrmemfunc (op0);
    6282          122 :           delta1 = delta_from_ptrmemfunc (op1);
    6283          122 :           if (TARGET_PTRMEMFUNC_VBIT_LOCATION
    6284              :               == ptrmemfunc_vbit_in_delta)
    6285              :             {
    6286              :               /* We generate:
    6287              : 
    6288              :                  (op0.pfn == op1.pfn
    6289              :                   && ((op0.delta == op1.delta)
    6290              :                        || (!op0.pfn && op0.delta & 1 == 0
    6291              :                            && op1.delta & 1 == 0))
    6292              : 
    6293              :                  The reason for the `!op0.pfn' bit is that a NULL
    6294              :                  pointer-to-member is any member with a zero PFN and
    6295              :                  LSB of the DELTA field is 0.  */
    6296              : 
    6297              :               e1 = cp_build_binary_op (location, BIT_AND_EXPR,
    6298              :                                        delta0,
    6299              :                                        integer_one_node,
    6300              :                                        complain);
    6301              :               e1 = cp_build_binary_op (location,
    6302              :                                        EQ_EXPR, e1, integer_zero_node,
    6303              :                                        complain);
    6304              :               e2 = cp_build_binary_op (location, BIT_AND_EXPR,
    6305              :                                        delta1,
    6306              :                                        integer_one_node,
    6307              :                                        complain);
    6308              :               e2 = cp_build_binary_op (location,
    6309              :                                        EQ_EXPR, e2, integer_zero_node,
    6310              :                                        complain);
    6311              :               e1 = cp_build_binary_op (location,
    6312              :                                        TRUTH_ANDIF_EXPR, e2, e1,
    6313              :                                        complain);
    6314              :               e2 = cp_build_binary_op (location, EQ_EXPR,
    6315              :                                        pfn0,
    6316              :                                        build_zero_cst (TREE_TYPE (pfn0)),
    6317              :                                        complain);
    6318              :               e2 = cp_build_binary_op (location,
    6319              :                                        TRUTH_ANDIF_EXPR, e2, e1, complain);
    6320              :               e1 = cp_build_binary_op (location,
    6321              :                                        EQ_EXPR, delta0, delta1, complain);
    6322              :               e1 = cp_build_binary_op (location,
    6323              :                                        TRUTH_ORIF_EXPR, e1, e2, complain);
    6324              :             }
    6325              :           else
    6326              :             {
    6327              :               /* We generate:
    6328              : 
    6329              :                  (op0.pfn == op1.pfn
    6330              :                  && (!op0.pfn || op0.delta == op1.delta))
    6331              : 
    6332              :                  The reason for the `!op0.pfn' bit is that a NULL
    6333              :                  pointer-to-member is any member with a zero PFN; the
    6334              :                  DELTA field is unspecified.  */
    6335              : 
    6336          122 :               e1 = cp_build_binary_op (location,
    6337              :                                        EQ_EXPR, delta0, delta1, complain);
    6338          122 :               e2 = cp_build_binary_op (location,
    6339              :                                        EQ_EXPR,
    6340              :                                        pfn0,
    6341          122 :                                        build_zero_cst (TREE_TYPE (pfn0)),
    6342              :                                        complain);
    6343          122 :               e1 = cp_build_binary_op (location,
    6344              :                                        TRUTH_ORIF_EXPR, e1, e2, complain);
    6345              :             }
    6346          122 :           e2 = build2 (EQ_EXPR, boolean_type_node, pfn0, pfn1);
    6347          122 :           e = cp_build_binary_op (location,
    6348              :                                   TRUTH_ANDIF_EXPR, e2, e1, complain);
    6349          122 :           if (code == EQ_EXPR)
    6350              :             return e;
    6351           30 :           return cp_build_binary_op (location,
    6352           30 :                                      EQ_EXPR, e, integer_zero_node, complain);
    6353              :         }
    6354              :       /* [expr.eq]: "If both operands are of type std::meta::info,
    6355              :          comparison is defined as follows..."  */
    6356         1999 :       else if (code0 == META_TYPE && code1 == META_TYPE)
    6357              :         result_type = type0;
    6358              :       else
    6359              :         {
    6360           22 :           gcc_assert (!TYPE_PTRMEMFUNC_P (type0)
    6361              :                       || !same_type_p (TYPE_PTRMEMFUNC_FN_TYPE (type0),
    6362              :                                        type1));
    6363           22 :           gcc_assert (!TYPE_PTRMEMFUNC_P (type1)
    6364              :                       || !same_type_p (TYPE_PTRMEMFUNC_FN_TYPE (type1),
    6365              :                                        type0));
    6366              :         }
    6367              : 
    6368              :       break;
    6369              : 
    6370          241 :     case MAX_EXPR:
    6371          241 :     case MIN_EXPR:
    6372          241 :       if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
    6373          241 :            && (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
    6374              :         shorten = 1;
    6375            0 :       else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
    6376            0 :         result_type = composite_pointer_type (location,
    6377              :                                               type0, type1, op0, op1,
    6378              :                                               CPO_COMPARISON, complain);
    6379              :       break;
    6380              : 
    6381     27586793 :     case LE_EXPR:
    6382     27586793 :     case GE_EXPR:
    6383     27586793 :     case LT_EXPR:
    6384     27586793 :     case GT_EXPR:
    6385     27586793 :     case SPACESHIP_EXPR:
    6386     27586793 :       if (TREE_CODE (orig_op0) == STRING_CST
    6387     27586793 :           || TREE_CODE (orig_op1) == STRING_CST)
    6388              :         {
    6389            0 :           if (complain & tf_warning)
    6390            0 :             warning_at (location, OPT_Waddress,
    6391              :                         "comparison with string literal results "
    6392              :                         "in unspecified behavior");
    6393              :         }
    6394     27586793 :       else if (TREE_CODE (TREE_TYPE (orig_op0)) == ARRAY_TYPE
    6395          164 :                && TREE_CODE (TREE_TYPE (orig_op1)) == ARRAY_TYPE
    6396     27586908 :                && code != SPACESHIP_EXPR)
    6397              :         {
    6398           96 :           if (complain & tf_warning_or_error)
    6399           51 :             do_warn_array_compare (location, code,
    6400              :                                    tree_strip_any_location_wrapper (orig_op0),
    6401              :                                    tree_strip_any_location_wrapper (orig_op1));
    6402           45 :           else if (cxx_dialect >= cxx26)
    6403            1 :             return error_mark_node;
    6404              :         }
    6405              : 
    6406     27586792 :       if (gnu_vector_type_p (type0) && gnu_vector_type_p (type1))
    6407              :         {
    6408         7190 :         vector_compare:
    6409         7190 :           tree intt;
    6410         7190 :           if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (type0),
    6411         7190 :                                                           TREE_TYPE (type1))
    6412         7190 :               && !vector_types_compatible_elements_p (type0, type1))
    6413              :             {
    6414            3 :               if (complain & tf_error)
    6415              :                 {
    6416            3 :                   auto_diagnostic_group d;
    6417            3 :                   error_at (location, "comparing vectors with different "
    6418              :                                       "element types");
    6419            3 :                   inform (location, "operand types are %qT and %qT",
    6420              :                           type0, type1);
    6421            3 :                 }
    6422            3 :               return error_mark_node;
    6423              :             }
    6424              : 
    6425         7187 :           if (maybe_ne (TYPE_VECTOR_SUBPARTS (type0),
    6426        14374 :                         TYPE_VECTOR_SUBPARTS (type1)))
    6427              :             {
    6428            3 :               if (complain & tf_error)
    6429              :                 {
    6430            3 :                   auto_diagnostic_group d;
    6431            3 :                   error_at (location, "comparing vectors with different "
    6432              :                                       "number of elements");
    6433            3 :                   inform (location, "operand types are %qT and %qT",
    6434              :                           type0, type1);
    6435            3 :                 }
    6436            3 :               return error_mark_node;
    6437              :             }
    6438              : 
    6439              :           /* It's not precisely specified how the usual arithmetic
    6440              :              conversions apply to the vector types.  Here, we use
    6441              :              the unsigned type if one of the operands is signed and
    6442              :              the other one is unsigned.  */
    6443         7184 :           if (TYPE_UNSIGNED (type0) != TYPE_UNSIGNED (type1))
    6444              :             {
    6445           36 :               if (!TYPE_UNSIGNED (type0))
    6446           36 :                 op0 = build1 (VIEW_CONVERT_EXPR, type1, op0);
    6447              :               else
    6448            0 :                 op1 = build1 (VIEW_CONVERT_EXPR, type0, op1);
    6449           36 :               warning_at (location, OPT_Wsign_compare, "comparison between "
    6450              :                           "types %qT and %qT", type0, type1);
    6451              :             }
    6452              : 
    6453         7184 :           if (resultcode == SPACESHIP_EXPR)
    6454              :             {
    6455            3 :               if (complain & tf_error)
    6456            3 :                 sorry_at (location, "three-way comparison of vectors");
    6457            3 :               return error_mark_node;
    6458              :             }
    6459              : 
    6460         7181 :           if (VECTOR_BOOLEAN_TYPE_P (type0) && VECTOR_BOOLEAN_TYPE_P (type1))
    6461              :             result_type = type0;
    6462              :           else
    6463              :             {
    6464              :               /* Always construct signed integer vector type.  */
    6465         7181 :               auto intmode = SCALAR_TYPE_MODE (TREE_TYPE (type0));
    6466         7181 :               auto nelts = TYPE_VECTOR_SUBPARTS (type0);
    6467              : 
    6468        14362 :               intt = c_common_type_for_size (GET_MODE_BITSIZE (intmode), 0);
    6469         7181 :               if (!intt)
    6470              :                 {
    6471            0 :                   if (complain & tf_error)
    6472            0 :                     error_at (location, "could not find an integer type "
    6473            0 :                                 "of the same size as %qT", TREE_TYPE (type0));
    6474            0 :                   return error_mark_node;
    6475              :                 }
    6476         7181 :               result_type = build_opaque_vector_type (intt, nelts);
    6477              :             }
    6478         7181 :           return build_vec_cmp (resultcode, result_type, op0, op1);
    6479              :         }
    6480     27582257 :       build_type = boolean_type_node;
    6481     27582257 :       if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
    6482              :            || code0 == ENUMERAL_TYPE)
    6483     24510245 :            && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
    6484              :                || code1 == ENUMERAL_TYPE))
    6485              :         short_compare = 1;
    6486      3072115 :       else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
    6487      3071838 :         result_type = composite_pointer_type (location,
    6488              :                                               type0, type1, op0, op1,
    6489              :                                               CPO_COMPARISON, complain);
    6490           73 :       else if ((code0 == POINTER_TYPE && null_ptr_cst_p (orig_op1))
    6491          205 :                || (code1 == POINTER_TYPE && null_ptr_cst_p (orig_op0))
    6492          428 :                || (null_ptr_cst_p (orig_op0) && null_ptr_cst_p (orig_op1)))
    6493              :         {
    6494              :           /* Core Issue 1512 made this ill-formed.  */
    6495          190 :           if (complain & tf_error)
    6496          186 :             error_at (location, "ordered comparison of pointer with "
    6497              :                       "integer zero (%qT and %qT)", type0, type1);
    6498          190 :           return error_mark_node;
    6499              :         }
    6500           87 :       else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
    6501              :         {
    6502            0 :           result_type = type0;
    6503            0 :           if (complain & tf_error)
    6504            0 :             permerror (location, "ISO C++ forbids comparison between "
    6505              :                        "pointer and integer");
    6506              :           else
    6507            0 :             return error_mark_node;
    6508              :         }
    6509           87 :       else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
    6510              :         {
    6511           24 :           result_type = type1;
    6512           24 :           if (complain & tf_error)
    6513           24 :             permerror (location, "ISO C++ forbids comparison between "
    6514              :                        "pointer and integer");
    6515              :           else
    6516            0 :             return error_mark_node;
    6517              :         }
    6518              : 
    6519     27582067 :       if ((code0 == POINTER_TYPE || code1 == POINTER_TYPE)
    6520      3071863 :           && !processing_template_decl
    6521     30442971 :           && sanitize_flags_p (SANITIZE_POINTER_COMPARE))
    6522              :         {
    6523           49 :           op0 = cp_save_expr (op0);
    6524           49 :           op1 = cp_save_expr (op1);
    6525              : 
    6526           49 :           tree tt = builtin_decl_explicit (BUILT_IN_ASAN_POINTER_COMPARE);
    6527           49 :           instrument_expr = build_call_expr_loc (location, tt, 2, op0, op1);
    6528              :         }
    6529              : 
    6530              :       break;
    6531              : 
    6532            0 :     case UNORDERED_EXPR:
    6533            0 :     case ORDERED_EXPR:
    6534            0 :     case UNLT_EXPR:
    6535            0 :     case UNLE_EXPR:
    6536            0 :     case UNGT_EXPR:
    6537            0 :     case UNGE_EXPR:
    6538            0 :     case UNEQ_EXPR:
    6539            0 :       build_type = integer_type_node;
    6540            0 :       if (code0 != REAL_TYPE || code1 != REAL_TYPE)
    6541              :         {
    6542            0 :           if (complain & tf_error)
    6543            0 :             error ("unordered comparison on non-floating-point argument");
    6544            0 :           return error_mark_node;
    6545              :         }
    6546              :       common = 1;
    6547              :       break;
    6548              : 
    6549              :     default:
    6550              :       break;
    6551              :     }
    6552              : 
    6553    150415839 :   if (((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE
    6554              :         || code0 == ENUMERAL_TYPE)
    6555    123002482 :        && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
    6556              :            || code1 == COMPLEX_TYPE || code1 == ENUMERAL_TYPE)))
    6557              :     arithmetic_types_p = 1;
    6558              :   else
    6559              :     {
    6560     27849149 :       arithmetic_types_p = 0;
    6561              :       /* Vector arithmetic is only allowed when both sides are vectors.  */
    6562     27849149 :       if (gnu_vector_type_p (type0) && gnu_vector_type_p (type1))
    6563              :         {
    6564        59635 :           if (!tree_int_cst_equal (TYPE_SIZE (type0), TYPE_SIZE (type1))
    6565        59635 :               || !vector_types_compatible_elements_p (type0, type1))
    6566              :             {
    6567           18 :               if (complain & tf_error)
    6568              :                 {
    6569              :                   /* "location" already embeds the locations of the
    6570              :                      operands, so we don't need to add them separately
    6571              :                      to richloc.  */
    6572           18 :                   rich_location richloc (line_table, location);
    6573           18 :                   binary_op_error (&richloc, code, type0, type1);
    6574           18 :                 }
    6575           18 :               return error_mark_node;
    6576              :             }
    6577              :           arithmetic_types_p = 1;
    6578              :         }
    6579              :     }
    6580              :   /* Determine the RESULT_TYPE, if it is not already known.  */
    6581    150415821 :   if (!result_type
    6582    150415821 :       && arithmetic_types_p
    6583    117933469 :       && (shorten || common || short_compare))
    6584              :     {
    6585    117933392 :       result_type = cp_common_type (type0, type1);
    6586    117933392 :       if (result_type == error_mark_node)
    6587              :         {
    6588            6 :           tree t1 = type0;
    6589            6 :           tree t2 = type1;
    6590            6 :           if (TREE_CODE (t1) == COMPLEX_TYPE)
    6591            0 :             t1 = TREE_TYPE (t1);
    6592            6 :           if (TREE_CODE (t2) == COMPLEX_TYPE)
    6593            0 :             t2 = TREE_TYPE (t2);
    6594            6 :           gcc_checking_assert (TREE_CODE (t1) == REAL_TYPE
    6595              :                                && TREE_CODE (t2) == REAL_TYPE
    6596              :                                && (extended_float_type_p (t1)
    6597              :                                    || extended_float_type_p (t2))
    6598              :                                && cp_compare_floating_point_conversion_ranks
    6599              :                                     (t1, t2) == 3);
    6600            6 :           if (complain & tf_error)
    6601              :             {
    6602            6 :               rich_location richloc (line_table, location);
    6603            6 :               binary_op_error (&richloc, code, type0, type1);
    6604            6 :             }
    6605            6 :           return error_mark_node;
    6606              :         }
    6607    117933386 :       if (complain & tf_warning)
    6608    107643521 :         do_warn_double_promotion (result_type, type0, type1,
    6609              :                                   "implicit conversion from %qH to %qI "
    6610              :                                   "to match other operand of binary "
    6611              :                                   "expression", location);
    6612    117933386 :       if (do_warn_enum_conversions (location, code, TREE_TYPE (orig_op0),
    6613    117933386 :                                     TREE_TYPE (orig_op1), complain))
    6614            6 :         return error_mark_node;
    6615              :     }
    6616    150415809 :   if (may_need_excess_precision
    6617    111591794 :       && (orig_type0 != type0 || orig_type1 != type1)
    6618        39951 :       && build_type == NULL_TREE
    6619        39951 :       && result_type)
    6620              :     {
    6621        30630 :       gcc_assert (common);
    6622        30630 :       semantic_result_type = cp_common_type (orig_type0, orig_type1);
    6623        30630 :       if (semantic_result_type == error_mark_node)
    6624              :         {
    6625            0 :           tree t1 = orig_type0;
    6626            0 :           tree t2 = orig_type1;
    6627            0 :           if (TREE_CODE (t1) == COMPLEX_TYPE)
    6628            0 :             t1 = TREE_TYPE (t1);
    6629            0 :           if (TREE_CODE (t2) == COMPLEX_TYPE)
    6630            0 :             t2 = TREE_TYPE (t2);
    6631            0 :           gcc_checking_assert (TREE_CODE (t1) == REAL_TYPE
    6632              :                                && TREE_CODE (t2) == REAL_TYPE
    6633              :                                && (extended_float_type_p (t1)
    6634              :                                    || extended_float_type_p (t2))
    6635              :                                && cp_compare_floating_point_conversion_ranks
    6636              :                                     (t1, t2) == 3);
    6637            0 :           if (complain & tf_error)
    6638              :             {
    6639            0 :               rich_location richloc (line_table, location);
    6640            0 :               binary_op_error (&richloc, code, type0, type1);
    6641            0 :             }
    6642            0 :           return error_mark_node;
    6643              :         }
    6644              :     }
    6645              : 
    6646    150415809 :   if (code == SPACESHIP_EXPR)
    6647              :     {
    6648       695938 :       iloc_sentinel s (location);
    6649              : 
    6650       695938 :       tree orig_type0 = TREE_TYPE (orig_op0);
    6651       695938 :       tree_code orig_code0 = TREE_CODE (orig_type0);
    6652       695938 :       tree orig_type1 = TREE_TYPE (orig_op1);
    6653       695938 :       tree_code orig_code1 = TREE_CODE (orig_type1);
    6654       695938 :       if (!result_type || result_type == error_mark_node)
    6655              :         /* Nope.  */
    6656              :         result_type = NULL_TREE;
    6657       695917 :       else if ((orig_code0 == BOOLEAN_TYPE) != (orig_code1 == BOOLEAN_TYPE))
    6658              :         /* "If one of the operands is of type bool and the other is not, the
    6659              :            program is ill-formed."  */
    6660              :         result_type = NULL_TREE;
    6661       695914 :       else if (code0 == POINTER_TYPE && orig_code0 != POINTER_TYPE
    6662           19 :                && code1 == POINTER_TYPE && orig_code1 != POINTER_TYPE)
    6663              :         /* We only do array/function-to-pointer conversion if "at least one of
    6664              :            the operands is of pointer type".  */
    6665              :         result_type = NULL_TREE;
    6666       695895 :       else if (TYPE_PTRFN_P (result_type) || NULLPTR_TYPE_P (result_type))
    6667              :         /* <=> no longer supports equality relations.  */
    6668              :         result_type = NULL_TREE;
    6669       695892 :       else if (orig_code0 == ENUMERAL_TYPE && orig_code1 == ENUMERAL_TYPE
    6670       695922 :                && !(same_type_ignoring_top_level_qualifiers_p
    6671           30 :                     (orig_type0, orig_type1)))
    6672              :         /* "If both operands have arithmetic types, or one operand has integral
    6673              :            type and the other operand has unscoped enumeration type, the usual
    6674              :            arithmetic conversions are applied to the operands."  So we don't do
    6675              :            arithmetic conversions if the operands both have enumeral type.  */
    6676              :         result_type = NULL_TREE;
    6677       695877 :       else if ((orig_code0 == ENUMERAL_TYPE && orig_code1 == REAL_TYPE)
    6678       695871 :                || (orig_code0 == REAL_TYPE && orig_code1 == ENUMERAL_TYPE))
    6679              :         /* [depr.arith.conv.enum]: Three-way comparisons between such operands
    6680              :            [where one is of enumeration type and the other is of a different
    6681              :            enumeration type or a floating-point type] are ill-formed.  */
    6682              :         result_type = NULL_TREE;
    6683              : 
    6684       695865 :       if (result_type)
    6685              :         {
    6686       695865 :           build_type = spaceship_type (result_type, complain);
    6687       695865 :           if (build_type == error_mark_node)
    6688              :             return error_mark_node;
    6689              :         }
    6690              : 
    6691       695923 :       if (result_type && arithmetic_types_p)
    6692              :         {
    6693              :           /* If a narrowing conversion is required, other than from an integral
    6694              :              type to a floating point type, the program is ill-formed.  */
    6695       288006 :           bool ok = true;
    6696       288006 :           if (TREE_CODE (result_type) == REAL_TYPE
    6697          550 :               && CP_INTEGRAL_TYPE_P (orig_type0))
    6698              :             /* OK */;
    6699       287999 :           else if (!check_narrowing (result_type, orig_op0, complain))
    6700       288006 :             ok = false;
    6701       288006 :           if (TREE_CODE (result_type) == REAL_TYPE
    6702          550 :               && CP_INTEGRAL_TYPE_P (orig_type1))
    6703              :             /* OK */;
    6704       287999 :           else if (!check_narrowing (result_type, orig_op1, complain))
    6705              :             ok = false;
    6706       288006 :           if (!ok && !(complain & tf_error))
    6707            2 :             return error_mark_node;
    6708              :         }
    6709       695938 :     }
    6710              : 
    6711    150415792 :   if (!result_type)
    6712              :     {
    6713          526 :       if (complain & tf_error)
    6714              :         {
    6715          210 :           binary_op_rich_location richloc (location,
    6716          210 :                                            orig_op0, orig_op1, true);
    6717          210 :           error_at (&richloc,
    6718              :                     "invalid operands of types %qT and %qT to binary %qO",
    6719          210 :                     TREE_TYPE (orig_op0), TREE_TYPE (orig_op1), code);
    6720          210 :         }
    6721          526 :       return error_mark_node;
    6722              :     }
    6723              : 
    6724              :   /* If we're in a template, the only thing we need to know is the
    6725              :      RESULT_TYPE.  */
    6726    150415266 :   if (processing_template_decl)
    6727              :     {
    6728              :       /* Since the middle-end checks the type when doing a build2, we
    6729              :          need to build the tree in pieces.  This built tree will never
    6730              :          get out of the front-end as we replace it when instantiating
    6731              :          the template.  */
    6732     61013909 :       tree tmp = build2 (resultcode,
    6733              :                          build_type ? build_type : result_type,
    6734              :                          NULL_TREE, op1);
    6735     38451413 :       TREE_OPERAND (tmp, 0) = op0;
    6736     38451413 :       if (semantic_result_type)
    6737            0 :         tmp = build1 (EXCESS_PRECISION_EXPR, semantic_result_type, tmp);
    6738     38451413 :       return tmp;
    6739              :     }
    6740              : 
    6741              :   /* Remember the original type; RESULT_TYPE might be changed later on
    6742              :      by shorten_binary_op.  */
    6743    111963853 :   tree orig_type = result_type;
    6744              : 
    6745    111963853 :   if (arithmetic_types_p)
    6746              :     {
    6747     94964981 :       bool first_complex = (code0 == COMPLEX_TYPE);
    6748     94964981 :       bool second_complex = (code1 == COMPLEX_TYPE);
    6749     94964981 :       int none_complex = (!first_complex && !second_complex);
    6750              : 
    6751              :       /* Adapted from patch for c/24581.  */
    6752     94964981 :       if (first_complex != second_complex
    6753       156649 :           && (code == PLUS_EXPR
    6754              :               || code == MINUS_EXPR
    6755       156649 :               || code == MULT_EXPR
    6756        40982 :               || (code == TRUNC_DIV_EXPR && first_complex))
    6757       143142 :           && TREE_CODE (TREE_TYPE (result_type)) == REAL_TYPE
    6758     95107962 :           && flag_signed_zeros)
    6759              :         {
    6760              :           /* An operation on mixed real/complex operands must be
    6761              :              handled specially, but the language-independent code can
    6762              :              more easily optimize the plain complex arithmetic if
    6763              :              -fno-signed-zeros.  */
    6764       142981 :           tree real_type = TREE_TYPE (result_type);
    6765       142981 :           tree real, imag;
    6766       142981 :           if (first_complex)
    6767              :             {
    6768       109933 :               if (TREE_TYPE (op0) != result_type)
    6769            6 :                 op0 = cp_convert_and_check (result_type, op0, complain);
    6770       109933 :               if (TREE_TYPE (op1) != real_type)
    6771           26 :                 op1 = cp_convert_and_check (real_type, op1, complain);
    6772              :             }
    6773              :           else
    6774              :             {
    6775        33048 :               if (TREE_TYPE (op0) != real_type)
    6776           31 :                 op0 = cp_convert_and_check (real_type, op0, complain);
    6777        33048 :               if (TREE_TYPE (op1) != result_type)
    6778           32 :                 op1 = cp_convert_and_check (result_type, op1, complain);
    6779              :             }
    6780       142981 :           if (TREE_CODE (op0) == ERROR_MARK || TREE_CODE (op1) == ERROR_MARK)
    6781            0 :             return error_mark_node;
    6782       142981 :           if (first_complex)
    6783              :             {
    6784       109933 :               op0 = cp_save_expr (op0);
    6785       109933 :               real = cp_build_unary_op (REALPART_EXPR, op0, true, complain);
    6786       109933 :               imag = cp_build_unary_op (IMAGPART_EXPR, op0, true, complain);
    6787       109933 :               switch (code)
    6788              :                 {
    6789        54943 :                 case MULT_EXPR:
    6790        54943 :                 case TRUNC_DIV_EXPR:
    6791        54943 :                   op1 = cp_save_expr (op1);
    6792        54943 :                   imag = build2 (resultcode, real_type, imag, op1);
    6793              :                   /* Fall through.  */
    6794       109933 :                 case PLUS_EXPR:
    6795       109933 :                 case MINUS_EXPR:
    6796       109933 :                   real = build2 (resultcode, real_type, real, op1);
    6797       109933 :                   break;
    6798            0 :                 default:
    6799            0 :                   gcc_unreachable();
    6800              :                 }
    6801              :             }
    6802              :           else
    6803              :             {
    6804        33048 :               op1 = cp_save_expr (op1);
    6805        33048 :               real = cp_build_unary_op (REALPART_EXPR, op1, true, complain);
    6806        33048 :               imag = cp_build_unary_op (IMAGPART_EXPR, op1, true, complain);
    6807        33048 :               switch (code)
    6808              :                 {
    6809          638 :                 case MULT_EXPR:
    6810          638 :                   op0 = cp_save_expr (op0);
    6811          638 :                   imag = build2 (resultcode, real_type, op0, imag);
    6812              :                   /* Fall through.  */
    6813        17301 :                 case PLUS_EXPR:
    6814        17301 :                   real = build2 (resultcode, real_type, op0, real);
    6815        17301 :                   break;
    6816        15747 :                 case MINUS_EXPR:
    6817        15747 :                   real = build2 (resultcode, real_type, op0, real);
    6818        15747 :                   imag = build1 (NEGATE_EXPR, real_type, imag);
    6819        15747 :                   break;
    6820            0 :                 default:
    6821            0 :                   gcc_unreachable();
    6822              :                 }
    6823              :             }
    6824       142981 :           result = build2 (COMPLEX_EXPR, result_type, real, imag);
    6825       142981 :           if (semantic_result_type)
    6826           24 :             result = build1 (EXCESS_PRECISION_EXPR, semantic_result_type,
    6827              :                              result);
    6828       142981 :           return result;
    6829              :         }
    6830              : 
    6831              :       /* For certain operations (which identify themselves by shorten != 0)
    6832              :          if both args were extended from the same smaller type,
    6833              :          do the arithmetic in that type and then extend.
    6834              : 
    6835              :          shorten !=0 and !=1 indicates a bitwise operation.
    6836              :          For them, this optimization is safe only if
    6837              :          both args are zero-extended or both are sign-extended.
    6838              :          Otherwise, we might change the result.
    6839              :          E.g., (short)-1 | (unsigned short)-1 is (int)-1
    6840              :          but calculated in (unsigned short) it would be (unsigned short)-1.  */
    6841              : 
    6842     94822000 :       if (shorten && none_complex)
    6843              :         {
    6844      7049395 :           final_type = result_type;
    6845      7049395 :           result_type = shorten_binary_op (result_type, op0, op1,
    6846              :                                            shorten == -1);
    6847              :         }
    6848              : 
    6849              :       /* Shifts can be shortened if shifting right.  */
    6850              : 
    6851     94822000 :       if (short_shift)
    6852              :         {
    6853       854240 :           int unsigned_arg;
    6854       854240 :           tree arg0 = get_narrower (op0, &unsigned_arg);
    6855              :           /* We're not really warning here but when we set short_shift we
    6856              :              used fold_for_warn to fold the operand.  */
    6857       854240 :           tree const_op1 = fold_for_warn (op1);
    6858              : 
    6859       854240 :           final_type = result_type;
    6860              : 
    6861       854240 :           if (arg0 == op0 && final_type == TREE_TYPE (op0))
    6862       730089 :             unsigned_arg = TYPE_UNSIGNED (TREE_TYPE (op0));
    6863              : 
    6864       854240 :           if (TYPE_PRECISION (TREE_TYPE (arg0)) < TYPE_PRECISION (result_type)
    6865         2008 :               && tree_int_cst_sgn (const_op1) > 0
    6866              :               /* We can shorten only if the shift count is less than the
    6867              :                  number of bits in the smaller type size.  */
    6868         2008 :               && compare_tree_int (const_op1,
    6869         2008 :                                    TYPE_PRECISION (TREE_TYPE (arg0))) < 0
    6870              :               /* We cannot drop an unsigned shift after sign-extension.  */
    6871       856238 :               && (!TYPE_UNSIGNED (final_type) || unsigned_arg))
    6872              :             {
    6873              :               /* Do an unsigned shift if the operand was zero-extended.  */
    6874         1991 :               result_type
    6875         1991 :                 = c_common_signed_or_unsigned_type (unsigned_arg,
    6876         1991 :                                                     TREE_TYPE (arg0));
    6877              :               /* Convert value-to-be-shifted to that type.  */
    6878         1991 :               if (TREE_TYPE (op0) != result_type)
    6879         1991 :                 op0 = convert (result_type, op0);
    6880              :               converted = 1;
    6881              :             }
    6882              :         }
    6883              : 
    6884              :       /* Comparison operations are shortened too but differently.
    6885              :          They identify themselves by setting short_compare = 1.  */
    6886              : 
    6887     94822000 :       if (short_compare)
    6888              :         {
    6889              :           /* We call shorten_compare only for diagnostics.  */
    6890     36681300 :           tree xop0 = fold_simple (op0);
    6891     36681300 :           tree xop1 = fold_simple (op1);
    6892     36681300 :           tree xresult_type = result_type;
    6893     36681300 :           enum tree_code xresultcode = resultcode;
    6894     36681300 :           shorten_compare (location, &xop0, &xop1, &xresult_type,
    6895              :                            &xresultcode);
    6896              :         }
    6897              : 
    6898     58140613 :       if ((short_compare || code == MIN_EXPR || code == MAX_EXPR)
    6899     36681489 :           && warn_sign_compare
    6900              :           /* Do not warn until the template is instantiated; we cannot
    6901              :              bound the ranges of the arguments until that point.  */
    6902       334785 :           && !processing_template_decl
    6903       334785 :           && (complain & tf_warning)
    6904       327350 :           && c_inhibit_evaluation_warnings == 0
    6905              :           /* Even unsigned enum types promote to signed int.  We don't
    6906              :              want to issue -Wsign-compare warnings for this case.  */
    6907       310967 :           && !enum_cast_to_int (orig_op0)
    6908     95132967 :           && !enum_cast_to_int (orig_op1))
    6909              :         {
    6910       310960 :           warn_for_sign_compare (location, orig_op0, orig_op1, op0, op1,
    6911              :                                  result_type, resultcode);
    6912              :         }
    6913              :     }
    6914              : 
    6915              :   /* If CONVERTED is zero, both args will be converted to type RESULT_TYPE.
    6916              :      Then the expression will be built.
    6917              :      It will be given type FINAL_TYPE if that is nonzero;
    6918              :      otherwise, it will be given type RESULT_TYPE.  */
    6919    111820872 :   if (! converted)
    6920              :     {
    6921    108122736 :       warning_sentinel w (warn_sign_conversion, short_compare);
    6922    108122736 :       if (!same_type_p (TREE_TYPE (op0), result_type))
    6923      4878166 :         op0 = cp_convert_and_check (result_type, op0, complain);
    6924    108122736 :       if (!same_type_p (TREE_TYPE (op1), result_type))
    6925     21411185 :         op1 = cp_convert_and_check (result_type, op1, complain);
    6926              : 
    6927    108122736 :       if (op0 == error_mark_node || op1 == error_mark_node)
    6928           58 :         return error_mark_node;
    6929    108122736 :     }
    6930              : 
    6931    111820814 :   if (build_type == NULL_TREE)
    6932     67460961 :     build_type = result_type;
    6933              : 
    6934    111820814 :   if (doing_shift
    6935      3697554 :       && flag_strong_eval_order == 2
    6936      3602630 :       && TREE_SIDE_EFFECTS (op1)
    6937    111841368 :       && !processing_template_decl)
    6938              :     {
    6939              :       /* In C++17, in both op0 << op1 and op0 >> op1 op0 is sequenced before
    6940              :          op1, so if op1 has side-effects, use SAVE_EXPR around op0.  */
    6941        20554 :       op0 = cp_save_expr (op0);
    6942        20554 :       instrument_expr = op0;
    6943              :     }
    6944              : 
    6945    111820814 :   if (sanitize_flags_p ((SANITIZE_SHIFT
    6946              :                          | SANITIZE_DIVIDE
    6947              :                          | SANITIZE_FLOAT_DIVIDE
    6948              :                          | SANITIZE_SI_OVERFLOW))
    6949        13366 :       && current_function_decl != NULL_TREE
    6950        10956 :       && !processing_template_decl
    6951    111831770 :       && (doing_div_or_mod || doing_shift))
    6952              :     {
    6953              :       /* OP0 and/or OP1 might have side-effects.  */
    6954          924 :       op0 = cp_save_expr (op0);
    6955          924 :       op1 = cp_save_expr (op1);
    6956          924 :       op0 = fold_non_dependent_expr (op0, complain);
    6957          924 :       op1 = fold_non_dependent_expr (op1, complain);
    6958          924 :       tree instrument_expr1 = NULL_TREE;
    6959          924 :       if (doing_div_or_mod
    6960          924 :           && sanitize_flags_p (SANITIZE_DIVIDE
    6961              :                                | SANITIZE_FLOAT_DIVIDE
    6962              :                                | SANITIZE_SI_OVERFLOW))
    6963              :         {
    6964              :           /* For diagnostics we want to use the promoted types without
    6965              :              shorten_binary_op.  So convert the arguments to the
    6966              :              original result_type.  */
    6967          465 :           tree cop0 = op0;
    6968          465 :           tree cop1 = op1;
    6969          465 :           if (TREE_TYPE (cop0) != orig_type)
    6970            6 :             cop0 = cp_convert (orig_type, op0, complain);
    6971          465 :           if (TREE_TYPE (cop1) != orig_type)
    6972           39 :             cop1 = cp_convert (orig_type, op1, complain);
    6973          465 :           instrument_expr1 = ubsan_instrument_division (location, cop0, cop1);
    6974              :         }
    6975          459 :       else if (doing_shift && sanitize_flags_p (SANITIZE_SHIFT))
    6976          378 :         instrument_expr1 = ubsan_instrument_shift (location, code, op0, op1);
    6977          924 :       if (instrument_expr != NULL)
    6978           18 :         instrument_expr = add_stmt_to_compound (instrument_expr,
    6979              :                                                 instrument_expr1);
    6980              :       else
    6981          906 :         instrument_expr = instrument_expr1;
    6982              :     }
    6983              : 
    6984    111820814 :   result = build2_loc (location, resultcode, build_type, op0, op1);
    6985    111820814 :   if (final_type != 0)
    6986      7903635 :     result = cp_convert (final_type, result, complain);
    6987              : 
    6988    111820814 :   if (instrument_expr != NULL)
    6989        21052 :     result = build2 (COMPOUND_EXPR, TREE_TYPE (result),
    6990              :                      instrument_expr, result);
    6991              : 
    6992    111820814 :   if (resultcode == SPACESHIP_EXPR && !processing_template_decl)
    6993       605312 :     result = get_target_expr (result, complain);
    6994              : 
    6995    111820814 :   if (semantic_result_type)
    6996        30606 :     result = build1 (EXCESS_PRECISION_EXPR, semantic_result_type, result);
    6997              : 
    6998    111820814 :   if (!c_inhibit_evaluation_warnings)
    6999              :     {
    7000     95812942 :       if (!processing_template_decl)
    7001              :         {
    7002     95812942 :           op0 = cp_fully_fold (op0);
    7003              :           /* Only consider the second argument if the first isn't overflowed.  */
    7004     95812942 :           if (!CONSTANT_CLASS_P (op0) || TREE_OVERFLOW_P (op0))
    7005              :             return result;
    7006     24860297 :           op1 = cp_fully_fold (op1);
    7007     24860297 :           if (!CONSTANT_CLASS_P (op1) || TREE_OVERFLOW_P (op1))
    7008              :             return result;
    7009              :         }
    7010            0 :       else if (!CONSTANT_CLASS_P (op0) || !CONSTANT_CLASS_P (op1)
    7011            0 :                || TREE_OVERFLOW_P (op0) || TREE_OVERFLOW_P (op1))
    7012              :         return result;
    7013              : 
    7014     19291318 :       tree result_ovl = fold_build2 (resultcode, build_type, op0, op1);
    7015     19291318 :       if (TREE_OVERFLOW_P (result_ovl))
    7016          190 :         overflow_warning (location, result_ovl);
    7017              :     }
    7018              : 
    7019              :   return result;
    7020              : }
    7021              : 
    7022              : /* Build a VEC_PERM_EXPR.
    7023              :    This is a simple wrapper for c_build_vec_perm_expr.  */
    7024              : tree
    7025        17494 : build_x_vec_perm_expr (location_t loc,
    7026              :                         tree arg0, tree arg1, tree arg2,
    7027              :                         tsubst_flags_t complain)
    7028              : {
    7029        17494 :   tree orig_arg0 = arg0;
    7030        17494 :   tree orig_arg1 = arg1;
    7031        17494 :   tree orig_arg2 = arg2;
    7032        17494 :   if (processing_template_decl)
    7033              :     {
    7034           19 :       if (type_dependent_expression_p (arg0)
    7035           13 :           || type_dependent_expression_p (arg1)
    7036           32 :           || type_dependent_expression_p (arg2))
    7037            6 :         return build_min_nt_loc (loc, VEC_PERM_EXPR, arg0, arg1, arg2);
    7038              :     }
    7039        17488 :   tree exp = c_build_vec_perm_expr (loc, arg0, arg1, arg2, complain & tf_error);
    7040        17488 :   if (processing_template_decl && exp != error_mark_node)
    7041           13 :     return build_min_non_dep (VEC_PERM_EXPR, exp, orig_arg0,
    7042           13 :                               orig_arg1, orig_arg2);
    7043              :   return exp;
    7044              : }
    7045              : 
    7046              : /* Build a VEC_PERM_EXPR.
    7047              :    This is a simple wrapper for c_build_shufflevector.  */
    7048              : tree
    7049        41175 : build_x_shufflevector (location_t loc, vec<tree, va_gc> *args,
    7050              :                        tsubst_flags_t complain)
    7051              : {
    7052        41175 :   tree arg0 = (*args)[0];
    7053        41175 :   tree arg1 = (*args)[1];
    7054        41175 :   if (processing_template_decl)
    7055              :     {
    7056           43 :       for (unsigned i = 0; i < args->length (); ++i)
    7057           40 :         if (i <= 1
    7058           40 :             ? type_dependent_expression_p ((*args)[i])
    7059            9 :             : instantiation_dependent_expression_p ((*args)[i]))
    7060              :           {
    7061           22 :             tree exp = build_min_nt_call_vec (NULL, args);
    7062           22 :             CALL_EXPR_IFN (exp) = IFN_SHUFFLEVECTOR;
    7063           22 :             return exp;
    7064              :           }
    7065              :     }
    7066        41153 :   auto_vec<tree, 16> mask;
    7067       558709 :   for (unsigned i = 2; i < args->length (); ++i)
    7068              :     {
    7069       517556 :       tree idx = fold_non_dependent_expr ((*args)[i], complain);
    7070       517556 :       mask.safe_push (idx);
    7071              :     }
    7072        41153 :   tree exp = c_build_shufflevector (loc, arg0, arg1, mask, complain & tf_error);
    7073        41153 :   if (processing_template_decl && exp != error_mark_node)
    7074              :     {
    7075            3 :       exp = build_min_non_dep_call_vec (exp, NULL, args);
    7076            3 :       CALL_EXPR_IFN (exp) = IFN_SHUFFLEVECTOR;
    7077              :     }
    7078        41153 :   return exp;
    7079        41153 : }
    7080              : 
    7081              : /* Return a tree for the sum or difference (RESULTCODE says which)
    7082              :    of pointer PTROP and integer INTOP.  */
    7083              : 
    7084              : static tree
    7085      7974410 : cp_pointer_int_sum (location_t loc, enum tree_code resultcode, tree ptrop,
    7086              :                     tree intop, tsubst_flags_t complain)
    7087              : {
    7088      7974410 :   tree res_type = TREE_TYPE (ptrop);
    7089              : 
    7090              :   /* pointer_int_sum() uses size_in_bytes() on the TREE_TYPE(res_type)
    7091              :      in certain circumstance (when it's valid to do so).  So we need
    7092              :      to make sure it's complete.  We don't need to check here, if we
    7093              :      can actually complete it at all, as those checks will be done in
    7094              :      pointer_int_sum() anyway.  */
    7095      7974410 :   complete_type (TREE_TYPE (res_type));
    7096              : 
    7097      7974410 :   return pointer_int_sum (loc, resultcode, ptrop,
    7098      7974410 :                           intop, complain & tf_warning_or_error);
    7099              : }
    7100              : 
    7101              : /* Return a tree for the difference of pointers OP0 and OP1.
    7102              :    The resulting tree has type int.  If POINTER_SUBTRACT sanitization is
    7103              :    enabled, assign to INSTRUMENT_EXPR call to libsanitizer.  */
    7104              : 
    7105              : static tree
    7106      2076086 : pointer_diff (location_t loc, tree op0, tree op1, tree ptrtype,
    7107              :               tsubst_flags_t complain, tree *instrument_expr)
    7108              : {
    7109      2076086 :   tree result, inttype;
    7110      2076086 :   tree restype = ptrdiff_type_node;
    7111      2076086 :   tree target_type = TREE_TYPE (ptrtype);
    7112              : 
    7113      2076086 :   if (!complete_type_or_maybe_complain (target_type, NULL_TREE, complain))
    7114            9 :     return error_mark_node;
    7115              : 
    7116      2076077 :   if (VOID_TYPE_P (target_type))
    7117              :     {
    7118            0 :       if (complain & tf_error)
    7119            0 :         permerror (loc, "ISO C++ forbids using pointer of "
    7120              :                    "type %<void *%> in subtraction");
    7121              :       else
    7122            0 :         return error_mark_node;
    7123              :     }
    7124      2076077 :   if (TREE_CODE (target_type) == FUNCTION_TYPE)
    7125              :     {
    7126            9 :       if (complain & tf_error)
    7127            3 :         permerror (loc, "ISO C++ forbids using pointer to "
    7128              :                    "a function in subtraction");
    7129              :       else
    7130            6 :         return error_mark_node;
    7131              :     }
    7132      2076071 :   if (TREE_CODE (target_type) == METHOD_TYPE)
    7133              :     {
    7134            0 :       if (complain & tf_error)
    7135            0 :         permerror (loc, "ISO C++ forbids using pointer to "
    7136              :                    "a method in subtraction");
    7137              :       else
    7138            0 :         return error_mark_node;
    7139              :     }
    7140      4152142 :   else if (!verify_type_context (loc, TCTX_POINTER_ARITH,
    7141      2076071 :                                  TREE_TYPE (TREE_TYPE (op0)),
    7142              :                                  !(complain & tf_error))
    7143      4152142 :            || !verify_type_context (loc, TCTX_POINTER_ARITH,
    7144      2076071 :                                     TREE_TYPE (TREE_TYPE (op1)),
    7145              :                                     !(complain & tf_error)))
    7146            0 :     return error_mark_node;
    7147              : 
    7148              :   /* Determine integer type result of the subtraction.  This will usually
    7149              :      be the same as the result type (ptrdiff_t), but may need to be a wider
    7150              :      type if pointers for the address space are wider than ptrdiff_t.  */
    7151      2076071 :   if (TYPE_PRECISION (restype) < TYPE_PRECISION (TREE_TYPE (op0)))
    7152            0 :     inttype = c_common_type_for_size (TYPE_PRECISION (TREE_TYPE (op0)), 0);
    7153              :   else
    7154              :     inttype = restype;
    7155              : 
    7156      2076071 :   if (!processing_template_decl
    7157      2076071 :       && sanitize_flags_p (SANITIZE_POINTER_SUBTRACT))
    7158              :     {
    7159           84 :       op0 = save_expr (op0);
    7160           84 :       op1 = save_expr (op1);
    7161              : 
    7162           84 :       tree tt = builtin_decl_explicit (BUILT_IN_ASAN_POINTER_SUBTRACT);
    7163           84 :       *instrument_expr = build_call_expr_loc (loc, tt, 2, op0, op1);
    7164              :     }
    7165              : 
    7166              :   /* First do the subtraction, then build the divide operator
    7167              :      and only convert at the very end.
    7168              :      Do not do default conversions in case restype is a short type.  */
    7169              : 
    7170              :   /* POINTER_DIFF_EXPR requires a signed integer type of the same size as
    7171              :      pointers.  If some platform cannot provide that, or has a larger
    7172              :      ptrdiff_type to support differences larger than half the address
    7173              :      space, cast the pointers to some larger integer type and do the
    7174              :      computations in that type.  */
    7175      2076071 :   if (TYPE_PRECISION (inttype) > TYPE_PRECISION (TREE_TYPE (op0)))
    7176            0 :     op0 = cp_build_binary_op (loc,
    7177              :                               MINUS_EXPR,
    7178              :                               cp_convert (inttype, op0, complain),
    7179              :                               cp_convert (inttype, op1, complain),
    7180              :                               complain);
    7181              :   else
    7182      2076071 :     op0 = build2_loc (loc, POINTER_DIFF_EXPR, inttype, op0, op1);
    7183              : 
    7184              :   /* This generates an error if op1 is a pointer to an incomplete type.  */
    7185      2076071 :   if (!COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (op1))))
    7186              :     {
    7187            0 :       if (complain & tf_error)
    7188            0 :         error_at (loc, "invalid use of a pointer to an incomplete type in "
    7189              :                   "pointer arithmetic");
    7190              :       else
    7191            0 :         return error_mark_node;
    7192              :     }
    7193              : 
    7194      2076071 :   if (pointer_to_zero_sized_aggr_p (TREE_TYPE (op1)))
    7195              :     {
    7196           15 :       if (complain & tf_error)
    7197           15 :         error_at (loc, "arithmetic on pointer to an empty aggregate");
    7198              :       else
    7199            0 :         return error_mark_node;
    7200              :     }
    7201              : 
    7202      4152139 :   op1 = (TYPE_PTROB_P (ptrtype)
    7203      4152139 :          ? size_in_bytes_loc (loc, target_type)
    7204              :          : integer_one_node);
    7205              : 
    7206              :   /* Do the division.  */
    7207              : 
    7208      2076071 :   result = build2_loc (loc, EXACT_DIV_EXPR, inttype, op0,
    7209              :                        cp_convert (inttype, op1, complain));
    7210      2076071 :   return cp_convert (restype, result, complain);
    7211              : }
    7212              : 
    7213              : /* Construct and perhaps optimize a tree representation
    7214              :    for a unary operation.  CODE, a tree_code, specifies the operation
    7215              :    and XARG is the operand.  */
    7216              : 
    7217              : tree
    7218     65632786 : build_x_unary_op (location_t loc, enum tree_code code, cp_expr xarg,
    7219              :                   tree lookups, tsubst_flags_t complain)
    7220              : {
    7221     65632786 :   tree orig_expr = xarg;
    7222     65632786 :   tree exp;
    7223     65632786 :   int ptrmem = 0;
    7224     65632786 :   tree overload = NULL_TREE;
    7225              : 
    7226     65632786 :   if (processing_template_decl)
    7227              :     {
    7228     42026514 :       if (type_dependent_expression_p (xarg))
    7229              :         {
    7230     27480895 :           tree e = build_min_nt_loc (loc, code, xarg.get_value (), NULL_TREE);
    7231     27480895 :           TREE_TYPE (e) = build_dependent_operator_type (lookups, code, false);
    7232     27480895 :           return e;
    7233              :         }
    7234              :     }
    7235              : 
    7236     38151891 :   exp = NULL_TREE;
    7237              : 
    7238              :   /* [expr.unary.op] says:
    7239              : 
    7240              :        The address of an object of incomplete type can be taken.
    7241              : 
    7242              :      (And is just the ordinary address operator, not an overloaded
    7243              :      "operator &".)  However, if the type is a template
    7244              :      specialization, we must complete the type at this point so that
    7245              :      an overloaded "operator &" will be available if required.  */
    7246     38151891 :   if (code == ADDR_EXPR
    7247      4072291 :       && TREE_CODE (xarg) != TEMPLATE_ID_EXPR
    7248     42223780 :       && ((CLASS_TYPE_P (TREE_TYPE (xarg))
    7249      1755286 :            && !COMPLETE_TYPE_P (complete_type (TREE_TYPE (xarg))))
    7250      4062867 :           || (TREE_CODE (xarg) == OFFSET_REF)))
    7251              :     /* Don't look for a function.  */;
    7252              :   else
    7253     38081506 :     exp = build_new_op (loc, code, LOOKUP_NORMAL, xarg, NULL_TREE,
    7254              :                         NULL_TREE, lookups, &overload, complain);
    7255              : 
    7256     38151891 :   if (!exp && code == ADDR_EXPR)
    7257              :     {
    7258      4071984 :       if (is_overloaded_fn (xarg))
    7259              :         {
    7260       365788 :           tree fn = get_first_fn (xarg);
    7261       731576 :           if (DECL_CONSTRUCTOR_P (fn) || DECL_DESTRUCTOR_P (fn))
    7262              :             {
    7263           12 :               if (complain & tf_error)
    7264           21 :                 error_at (loc, DECL_CONSTRUCTOR_P (fn)
    7265              :                           ? G_("taking address of constructor %qD")
    7266              :                           : G_("taking address of destructor %qD"),
    7267              :                           fn);
    7268           12 :               return error_mark_node;
    7269              :             }
    7270              :         }
    7271              : 
    7272              :       /* A pointer to member-function can be formed only by saying
    7273              :          &X::mf.  */
    7274      4071966 :       if (!flag_ms_extensions && TREE_CODE (TREE_TYPE (xarg)) == METHOD_TYPE
    7275      4129796 :           && (TREE_CODE (xarg) != OFFSET_REF || !PTRMEM_OK_P (xarg)))
    7276              :         {
    7277            9 :           if (TREE_CODE (xarg) != OFFSET_REF
    7278            9 :               || !TYPE_P (TREE_OPERAND (xarg, 0)))
    7279              :             {
    7280            9 :               if (complain & tf_error)
    7281              :                 {
    7282            9 :                   auto_diagnostic_group d;
    7283            9 :                   error_at (loc, "invalid use of %qE to form a "
    7284              :                             "pointer-to-member-function", xarg.get_value ());
    7285            9 :                   if (TREE_CODE (xarg) != OFFSET_REF)
    7286            6 :                     inform (loc, "  a qualified-id is required");
    7287            9 :                 }
    7288            9 :               return error_mark_node;
    7289              :             }
    7290              :           else
    7291              :             {
    7292            0 :               if (complain & tf_error)
    7293            0 :                 error_at (loc, "parentheses around %qE cannot be used to "
    7294              :                           "form a pointer-to-member-function",
    7295              :                           xarg.get_value ());
    7296              :               else
    7297            0 :                 return error_mark_node;
    7298            0 :               PTRMEM_OK_P (xarg) = 1;
    7299              :             }
    7300              :         }
    7301              : 
    7302      4071963 :       if (TREE_CODE (xarg) == OFFSET_REF)
    7303              :         {
    7304        61348 :           ptrmem = PTRMEM_OK_P (xarg);
    7305              : 
    7306            0 :           if (!ptrmem && !flag_ms_extensions
    7307        61348 :               && TREE_CODE (TREE_TYPE (TREE_OPERAND (xarg, 1))) == METHOD_TYPE)
    7308              :             {
    7309              :               /* A single non-static member, make sure we don't allow a
    7310              :                  pointer-to-member.  */
    7311            0 :               xarg = build2 (OFFSET_REF, TREE_TYPE (xarg),
    7312            0 :                              TREE_OPERAND (xarg, 0),
    7313            0 :                              ovl_make (TREE_OPERAND (xarg, 1)));
    7314            0 :               PTRMEM_OK_P (xarg) = ptrmem;
    7315              :             }
    7316              :         }
    7317              : 
    7318      8143926 :       exp = cp_build_addr_expr_strict (xarg, complain);
    7319              : 
    7320      4071963 :       if (TREE_CODE (exp) == PTRMEM_CST)
    7321        60368 :         PTRMEM_CST_LOCATION (exp) = loc;
    7322              :       else
    7323      4011595 :         protected_set_expr_location (exp, loc);
    7324              :     }
    7325              : 
    7326     38151870 :   if (processing_template_decl && exp != error_mark_node)
    7327              :     {
    7328     14545468 :       if (overload != NULL_TREE)
    7329       202389 :         return (build_min_non_dep_op_overload
    7330       202389 :                 (code, exp, overload, orig_expr, integer_zero_node));
    7331              : 
    7332     14343079 :       exp = build_min_non_dep (code, exp, orig_expr,
    7333              :                                /*For {PRE,POST}{INC,DEC}REMENT_EXPR*/NULL_TREE);
    7334              :     }
    7335     37949481 :   if (TREE_CODE (exp) == ADDR_EXPR)
    7336      3285278 :     PTRMEM_OK_P (exp) = ptrmem;
    7337              :   return exp;
    7338              : }
    7339              : 
    7340              : /* Construct and perhaps optimize a tree representation
    7341              :    for __builtin_addressof operation.  ARG specifies the operand.  */
    7342              : 
    7343              : tree
    7344       656209 : cp_build_addressof (location_t loc, tree arg, tsubst_flags_t complain)
    7345              : {
    7346       656209 :   tree orig_expr = arg;
    7347              : 
    7348       656209 :   if (processing_template_decl)
    7349              :     {
    7350       161173 :       if (type_dependent_expression_p (arg))
    7351       161173 :         return build_min_nt_loc (loc, ADDRESSOF_EXPR, arg, NULL_TREE);
    7352              :     }
    7353              : 
    7354       990072 :   tree exp = cp_build_addr_expr_strict (arg, complain);
    7355              : 
    7356       495036 :   if (processing_template_decl && exp != error_mark_node)
    7357            0 :     exp = build_min_non_dep (ADDRESSOF_EXPR, exp, orig_expr, NULL_TREE);
    7358              :   return exp;
    7359              : }
    7360              : 
    7361              : /* Like c_common_truthvalue_conversion, but handle pointer-to-member
    7362              :    constants, where a null value is represented by an INTEGER_CST of
    7363              :    -1.  */
    7364              : 
    7365              : tree
    7366     10183527 : cp_truthvalue_conversion (tree expr, tsubst_flags_t complain)
    7367              : {
    7368     10183527 :   tree type = TREE_TYPE (expr);
    7369     10183527 :   location_t loc = cp_expr_loc_or_input_loc (expr);
    7370      8817262 :   if (TYPE_PTR_OR_PTRMEM_P (type)
    7371              :       /* Avoid ICE on invalid use of non-static member function.  */
    7372     19000502 :       || TREE_CODE (expr) == FUNCTION_DECL)
    7373      1366552 :     return cp_build_binary_op (loc, NE_EXPR, expr, nullptr_node, complain);
    7374              :   else
    7375      8816975 :     return c_common_truthvalue_conversion (loc, expr);
    7376              : }
    7377              : 
    7378              : /* Returns EXPR contextually converted to bool.  */
    7379              : 
    7380              : tree
    7381     68801309 : contextual_conv_bool (tree expr, tsubst_flags_t complain)
    7382              : {
    7383     68801309 :   return perform_implicit_conversion_flags (boolean_type_node, expr,
    7384     68801309 :                                             complain, LOOKUP_NORMAL);
    7385              : }
    7386              : 
    7387              : /* Just like cp_truthvalue_conversion, but we want a CLEANUP_POINT_EXPR.  This
    7388              :    is a low-level function; most callers should use maybe_convert_cond.  */
    7389              : 
    7390              : tree
    7391     62315397 : condition_conversion (tree expr)
    7392              : {
    7393     62315397 :   tree t = contextual_conv_bool (expr, tf_warning_or_error);
    7394     62315397 :   if (!processing_template_decl)
    7395     37035684 :     t = fold_build_cleanup_point_expr (boolean_type_node, t);
    7396     62315397 :   return t;
    7397              : }
    7398              : 
    7399              : /* Returns the address of T.  This function will fold away
    7400              :    ADDR_EXPR of INDIRECT_REF.  This is only for low-level usage;
    7401              :    most places should use cp_build_addr_expr instead.  */
    7402              : 
    7403              : tree
    7404    471226320 : build_address (tree t)
    7405              : {
    7406    471226320 :   if (error_operand_p (t) || !cxx_mark_addressable (t))
    7407           24 :     return error_mark_node;
    7408    471226296 :   gcc_checking_assert (TREE_CODE (t) != CONSTRUCTOR
    7409              :                        || processing_template_decl);
    7410    471226296 :   t = build_fold_addr_expr_loc (EXPR_LOCATION (t), t);
    7411    471226296 :   if (TREE_CODE (t) != ADDR_EXPR)
    7412     75275754 :     t = rvalue (t);
    7413              :   return t;
    7414              : }
    7415              : 
    7416              : /* Return a NOP_EXPR converting EXPR to TYPE.  */
    7417              : 
    7418              : tree
    7419    670096526 : build_nop (tree type, tree expr MEM_STAT_DECL)
    7420              : {
    7421    670096526 :   if (type == error_mark_node || error_operand_p (expr))
    7422              :     return expr;
    7423    670096450 :   return build1_loc (EXPR_LOCATION (expr), NOP_EXPR, type, expr PASS_MEM_STAT);
    7424              : }
    7425              : 
    7426              : /* Take the address of ARG, whatever that means under C++ semantics.
    7427              :    If STRICT_LVALUE is true, require an lvalue; otherwise, allow xvalues
    7428              :    and class rvalues as well.
    7429              : 
    7430              :    Nothing should call this function directly; instead, callers should use
    7431              :    cp_build_addr_expr or cp_build_addr_expr_strict.  */
    7432              : 
    7433              : static tree
    7434    375374603 : cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain)
    7435              : {
    7436    375374603 :   tree argtype;
    7437    375374603 :   tree val;
    7438              : 
    7439    375374603 :   if (!arg || error_operand_p (arg))
    7440           12 :     return error_mark_node;
    7441              : 
    7442    375374591 :   arg = mark_lvalue_use (arg);
    7443    375374591 :   if (error_operand_p (arg))
    7444            3 :     return error_mark_node;
    7445              : 
    7446    375374588 :   argtype = lvalue_type (arg);
    7447    375374588 :   location_t loc = cp_expr_loc_or_input_loc (arg);
    7448              : 
    7449    375374588 :   gcc_assert (!(identifier_p (arg) && IDENTIFIER_ANY_OP_P (arg)));
    7450              : 
    7451     19818947 :   if (TREE_CODE (arg) == COMPONENT_REF && type_unknown_p (arg)
    7452    375374782 :       && !really_overloaded_fn (arg))
    7453              :     {
    7454              :       /* They're trying to take the address of a unique non-static
    7455              :          member function.  This is ill-formed (except in MS-land),
    7456              :          but let's try to DTRT.
    7457              :          Note: We only handle unique functions here because we don't
    7458              :          want to complain if there's a static overload; non-unique
    7459              :          cases will be handled by instantiate_type.  But we need to
    7460              :          handle this case here to allow casts on the resulting PMF.
    7461              :          We could defer this in non-MS mode, but it's easier to give
    7462              :          a useful error here.  */
    7463              : 
    7464              :       /* Inside constant member functions, the `this' pointer
    7465              :          contains an extra const qualifier.  TYPE_MAIN_VARIANT
    7466              :          is used here to remove this const from the diagnostics
    7467              :          and the created OFFSET_REF.  */
    7468           70 :       tree base = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (arg, 0)));
    7469           70 :       tree fn = get_first_fn (TREE_OPERAND (arg, 1));
    7470           70 :       if (!mark_used (fn, complain) && !(complain & tf_error))
    7471            0 :         return error_mark_node;
    7472              :       /* Until microsoft headers are known to incorrectly take the address of
    7473              :          unqualified xobj member functions we should not support this
    7474              :          extension.
    7475              :          See comment in class.cc:resolve_address_of_overloaded_function for
    7476              :          the extended reasoning.  */
    7477           70 :       if (!flag_ms_extensions || DECL_XOBJ_MEMBER_FUNCTION_P (fn))
    7478              :         {
    7479           64 :           auto_diagnostic_group d;
    7480           64 :           tree name = DECL_NAME (fn);
    7481           64 :           if (!(complain & tf_error))
    7482            0 :             return error_mark_node;
    7483           64 :           else if (current_class_type
    7484           64 :                    && TREE_OPERAND (arg, 0) == current_class_ref)
    7485              :             /* An expression like &memfn.  */
    7486           31 :             if (!DECL_XOBJ_MEMBER_FUNCTION_P (fn))
    7487           21 :               permerror (loc,
    7488              :                          "ISO C++ forbids taking the address of an unqualified"
    7489              :                          " or parenthesized non-static member function to form"
    7490              :                          " a pointer to member function.  Say %<&%T::%D%>",
    7491              :                          base, name);
    7492              :             else
    7493           10 :               error_at (loc,
    7494              :                         "ISO C++ forbids taking the address of an unqualified"
    7495              :                         " or parenthesized non-static member function to form"
    7496              :                         " a pointer to explicit object member function");
    7497              :           else
    7498           33 :             if (!DECL_XOBJ_MEMBER_FUNCTION_P (fn))
    7499            9 :               permerror (loc,
    7500              :                          "ISO C++ forbids taking the address of a bound member"
    7501              :                          " function to form a pointer to member function."
    7502              :                          "  Say %<&%T::%D%>",
    7503              :                          base, name);
    7504              :             else
    7505           24 :               error_at (loc,
    7506              :                         "ISO C++ forbids taking the address of a bound member"
    7507              :                         " function to form a pointer to explicit object member"
    7508              :                         " function");
    7509           64 :           if (DECL_XOBJ_MEMBER_FUNCTION_P (fn))
    7510           34 :             inform (loc,
    7511              :                     "a pointer to explicit object member function can only be "
    7512              :                     "formed with %<&%T::%D%>", base, name);
    7513           64 :         }
    7514           70 :       arg = build_offset_ref (base, fn, /*address_p=*/true, complain);
    7515              :     }
    7516              : 
    7517              :   /* Uninstantiated types are all functions.  Taking the
    7518              :      address of a function is a no-op, so just return the
    7519              :      argument.  */
    7520    375374588 :   if (type_unknown_p (arg))
    7521         1979 :     return build1 (ADDR_EXPR, unknown_type_node, arg);
    7522              : 
    7523    375372609 :   if (TREE_CODE (arg) == OFFSET_REF)
    7524              :     /* We want a pointer to member; bypass all the code for actually taking
    7525              :        the address of something.  */
    7526        60529 :     goto offset_ref;
    7527              : 
    7528              :   /* Anything not already handled and not a true memory reference
    7529              :      is an error.  */
    7530    375312080 :   if (!FUNC_OR_METHOD_TYPE_P (argtype))
    7531              :     {
    7532    206711092 :       cp_lvalue_kind kind = lvalue_kind (arg);
    7533    206711092 :       if (kind == clk_none)
    7534              :         {
    7535           24 :           if (complain & tf_error)
    7536           24 :             lvalue_error (loc, lv_addressof);
    7537           24 :           return error_mark_node;
    7538              :         }
    7539    206711068 :       if (strict_lvalue && (kind & (clk_rvalueref|clk_class)))
    7540              :         {
    7541           36 :           if (!(complain & tf_error))
    7542            9 :             return error_mark_node;
    7543              :           /* Make this a permerror because we used to accept it.  */
    7544           27 :           permerror (loc, "taking address of rvalue");
    7545              :         }
    7546              :     }
    7547              : 
    7548    375312047 :   if (TYPE_REF_P (argtype))
    7549              :     {
    7550          236 :       tree type = build_pointer_type (TREE_TYPE (argtype));
    7551          236 :       arg = build1 (CONVERT_EXPR, type, arg);
    7552          236 :       return arg;
    7553              :     }
    7554    375311811 :   else if (pedantic && DECL_MAIN_P (tree_strip_any_location_wrapper (arg)))
    7555              :     {
    7556              :       /* ARM $3.4 */
    7557              :       /* Apparently a lot of autoconf scripts for C++ packages do this,
    7558              :          so only complain if -Wpedantic.  */
    7559            9 :       if (complain & (flag_pedantic_errors ? tf_error : tf_warning))
    7560            9 :         pedwarn (loc, OPT_Wpedantic,
    7561              :                  "ISO C++ forbids taking address of function %<::main%>");
    7562            0 :       else if (flag_pedantic_errors)
    7563            0 :         return error_mark_node;
    7564              :     }
    7565              : 
    7566              :   /* Let &* cancel out to simplify resulting code.  */
    7567    375311811 :   if (INDIRECT_REF_P (arg))
    7568              :     {
    7569    138057801 :       arg = TREE_OPERAND (arg, 0);
    7570    138057801 :       if (TYPE_REF_P (TREE_TYPE (arg)))
    7571              :         {
    7572     90231325 :           tree type = build_pointer_type (TREE_TYPE (TREE_TYPE (arg)));
    7573     90231325 :           arg = build1 (CONVERT_EXPR, type, arg);
    7574              :         }
    7575              :       else
    7576              :         /* Don't let this be an lvalue.  */
    7577     47826476 :         arg = rvalue (arg);
    7578    138057801 :       return arg;
    7579              :     }
    7580              : 
    7581              :   /* Handle complex lvalues (when permitted)
    7582              :      by reduction to simpler cases.  */
    7583    237254010 :   val = unary_complex_lvalue (ADDR_EXPR, arg);
    7584    237254010 :   if (val != 0)
    7585              :     return val;
    7586              : 
    7587    236559407 :   switch (TREE_CODE (arg))
    7588              :     {
    7589            0 :     CASE_CONVERT:
    7590            0 :     case FLOAT_EXPR:
    7591            0 :     case FIX_TRUNC_EXPR:
    7592              :       /* We should have handled this above in the lvalue_kind check.  */
    7593            0 :       gcc_unreachable ();
    7594        76813 :       break;
    7595              : 
    7596        76813 :     case BASELINK:
    7597        76813 :       arg = BASELINK_FUNCTIONS (arg);
    7598              :       /* Fall through.  */
    7599              : 
    7600        76813 :     case OVERLOAD:
    7601        76813 :       arg = OVL_FIRST (arg);
    7602              :       break;
    7603              : 
    7604        60529 :     case OFFSET_REF:
    7605        60529 :     offset_ref:
    7606              :       /* Turn a reference to a non-static data member into a
    7607              :          pointer-to-member.  */
    7608        60529 :       {
    7609        60529 :         tree type;
    7610        60529 :         tree t;
    7611              : 
    7612        60529 :         gcc_assert (PTRMEM_OK_P (arg));
    7613              : 
    7614        60529 :         t = TREE_OPERAND (arg, 1);
    7615        60529 :         if (TYPE_REF_P (TREE_TYPE (t)))
    7616              :           {
    7617           15 :             if (complain & tf_error)
    7618           15 :               error_at (loc,
    7619              :                         "cannot create pointer to reference member %qD", t);
    7620           15 :             return error_mark_node;
    7621              :           }
    7622              : 
    7623              :         /* Forming a pointer-to-member is a use of non-pure-virtual fns.  */
    7624        60514 :         if (TREE_CODE (t) == FUNCTION_DECL
    7625        57985 :             && !DECL_PURE_VIRTUAL_P (t)
    7626       118477 :             && !mark_used (t, complain) && !(complain & tf_error))
    7627            3 :           return error_mark_node;
    7628              : 
    7629              :         /* Pull out the function_decl for a single xobj member function, and
    7630              :            let the rest of this function handle it.  This is similar to how
    7631              :            static member functions are handled in the BASELINK case above.  */
    7632        60511 :         if (DECL_XOBJ_MEMBER_FUNCTION_P (t))
    7633              :           {
    7634              :             arg = t;
    7635              :             break;
    7636              :           }
    7637              : 
    7638        60445 :         type = build_ptrmem_type (context_for_name_lookup (t),
    7639        60445 :                                   TREE_TYPE (t));
    7640        60445 :         t = make_ptrmem_cst (type, t);
    7641        60445 :         return t;
    7642              :       }
    7643              : 
    7644              :     default:
    7645              :       break;
    7646              :     }
    7647              : 
    7648    236559473 :   if (argtype != error_mark_node)
    7649    236559473 :     argtype = build_pointer_type (argtype);
    7650              : 
    7651    236559473 :   if (bitfield_p (arg))
    7652              :     {
    7653           33 :       if (complain & tf_error)
    7654           33 :         error_at (loc, "attempt to take address of bit-field");
    7655           33 :       return error_mark_node;
    7656              :     }
    7657              : 
    7658              :   /* In a template, we are processing a non-dependent expression
    7659              :      so we can just form an ADDR_EXPR with the correct type.  */
    7660    236559440 :   if (processing_template_decl || TREE_CODE (arg) != COMPONENT_REF)
    7661              :     {
    7662    217205785 :       if (!mark_single_function (arg, complain))
    7663            3 :         return error_mark_node;
    7664    217205782 :       val = build_address (arg);
    7665    217205782 :       if (TREE_CODE (arg) == OFFSET_REF)
    7666            0 :         PTRMEM_OK_P (val) = PTRMEM_OK_P (arg);
    7667              :     }
    7668     19353655 :   else if (BASELINK_P (TREE_OPERAND (arg, 1)))
    7669              :     {
    7670           27 :       tree fn = BASELINK_FUNCTIONS (TREE_OPERAND (arg, 1));
    7671              : 
    7672           27 :       if (TREE_CODE (fn) == OVERLOAD && OVL_SINGLE_P (fn))
    7673           27 :         fn = OVL_FIRST (fn);
    7674              : 
    7675              :       /* We can only get here with a single static member
    7676              :          function.  */
    7677           27 :       gcc_assert (TREE_CODE (fn) == FUNCTION_DECL
    7678              :                   && DECL_STATIC_FUNCTION_P (fn));
    7679           27 :       if (!mark_used (fn, complain) && !(complain & tf_error))
    7680            0 :         return error_mark_node;
    7681           27 :       val = build_address (fn);
    7682           27 :       if (TREE_SIDE_EFFECTS (TREE_OPERAND (arg, 0)))
    7683              :         /* Do not lose object's side effects.  */
    7684           12 :         val = build2 (COMPOUND_EXPR, TREE_TYPE (val),
    7685           12 :                       TREE_OPERAND (arg, 0), val);
    7686              :     }
    7687              :   else
    7688              :     {
    7689     19353628 :       tree object = TREE_OPERAND (arg, 0);
    7690     19353628 :       tree field = TREE_OPERAND (arg, 1);
    7691     19353628 :       gcc_assert (same_type_ignoring_top_level_qualifiers_p
    7692              :                   (TREE_TYPE (object), decl_type_context (field)));
    7693     19353628 :       val = build_address (arg);
    7694              :     }
    7695              : 
    7696    236559437 :   if (TYPE_PTR_P (argtype)
    7697    236559437 :       && TREE_CODE (TREE_TYPE (argtype)) == METHOD_TYPE)
    7698              :     {
    7699         1078 :       build_ptrmemfunc_type (argtype);
    7700         1078 :       val = build_ptrmemfunc (argtype, val, 0,
    7701              :                               /*c_cast_p=*/false,
    7702              :                               complain);
    7703              :     }
    7704              : 
    7705              :   /* Ensure we have EXPR_LOCATION set for possible later diagnostics.  */
    7706    236559437 :   if (TREE_CODE (val) == ADDR_EXPR
    7707    236559437 :       && TREE_CODE (TREE_OPERAND (val, 0)) == FUNCTION_DECL)
    7708    162367277 :     SET_EXPR_LOCATION (val, input_location);
    7709              : 
    7710              :   return val;
    7711              : }
    7712              : 
    7713              : /* Take the address of ARG if it has one, even if it's an rvalue.  */
    7714              : 
    7715              : tree
    7716    370807604 : cp_build_addr_expr (tree arg, tsubst_flags_t complain)
    7717              : {
    7718    370807604 :   return cp_build_addr_expr_1 (arg, 0, complain);
    7719              : }
    7720              : 
    7721              : /* Take the address of ARG, but only if it's an lvalue.  */
    7722              : 
    7723              : static tree
    7724      4566999 : cp_build_addr_expr_strict (tree arg, tsubst_flags_t complain)
    7725              : {
    7726      4566999 :   return cp_build_addr_expr_1 (arg, 1, complain);
    7727              : }
    7728              : 
    7729              : /* C++: Must handle pointers to members.
    7730              : 
    7731              :    Perhaps type instantiation should be extended to handle conversion
    7732              :    from aggregates to types we don't yet know we want?  (Or are those
    7733              :    cases typically errors which should be reported?)
    7734              : 
    7735              :    NOCONVERT suppresses the default promotions (such as from short to int).  */
    7736              : 
    7737              : tree
    7738     33603971 : cp_build_unary_op (enum tree_code code, tree xarg, bool noconvert,
    7739              :                    tsubst_flags_t complain)
    7740              : {
    7741              :   /* No default_conversion here.  It causes trouble for ADDR_EXPR.  */
    7742     33603971 :   tree arg = xarg;
    7743     33603971 :   location_t location = cp_expr_loc_or_input_loc (arg);
    7744     33603971 :   tree argtype = 0;
    7745     33603971 :   tree eptype = NULL_TREE;
    7746     33603971 :   const char *errstring = NULL;
    7747     33603971 :   tree val;
    7748     33603971 :   const char *invalid_op_diag;
    7749              : 
    7750     33603971 :   if (!arg || error_operand_p (arg))
    7751            0 :     return error_mark_node;
    7752              : 
    7753     33603971 :   arg = resolve_nondeduced_context (arg, complain);
    7754              : 
    7755     67207942 :   if ((invalid_op_diag
    7756     33603971 :        = targetm.invalid_unary_op ((code == UNARY_PLUS_EXPR
    7757              :                                     ? CONVERT_EXPR
    7758              :                                     : code),
    7759     33603971 :                                    TREE_TYPE (arg))))
    7760              :     {
    7761            0 :       if (complain & tf_error)
    7762            0 :         error (invalid_op_diag);
    7763            0 :       return error_mark_node;
    7764              :     }
    7765              : 
    7766     33603971 :   if (TREE_CODE (arg) == EXCESS_PRECISION_EXPR)
    7767              :     {
    7768         6362 :       eptype = TREE_TYPE (arg);
    7769         6362 :       arg = TREE_OPERAND (arg, 0);
    7770              :     }
    7771              : 
    7772     33603971 :   switch (code)
    7773              :     {
    7774      2463940 :     case UNARY_PLUS_EXPR:
    7775      2463940 :     case NEGATE_EXPR:
    7776      2463940 :       {
    7777      2463940 :         int flags = WANT_ARITH | WANT_ENUM;
    7778              :         /* Unary plus (but not unary minus) is allowed on pointers.  */
    7779      2463940 :         if (code == UNARY_PLUS_EXPR)
    7780       157694 :           flags |= WANT_POINTER;
    7781      2463940 :         arg = build_expr_type_conversion (flags, arg, true);
    7782      2463940 :         if (!arg)
    7783           34 :           errstring = (code == NEGATE_EXPR
    7784           27 :                        ? _("wrong type argument to unary minus")
    7785            7 :                        : _("wrong type argument to unary plus"));
    7786              :         else
    7787              :           {
    7788      2463906 :             if (!noconvert && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (arg)))
    7789       786762 :               arg = cp_perform_integral_promotions (arg, complain);
    7790              : 
    7791              :             /* Make sure the result is not an lvalue: a unary plus or minus
    7792              :                expression is always a rvalue.  */
    7793      2463906 :             arg = rvalue (arg);
    7794              :           }
    7795              :       }
    7796              :       break;
    7797              : 
    7798       948221 :     case BIT_NOT_EXPR:
    7799       948221 :       if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
    7800              :         {
    7801           15 :           code = CONJ_EXPR;
    7802           15 :           if (!noconvert)
    7803              :             {
    7804           15 :               arg = cp_default_conversion (arg, complain);
    7805           15 :               if (arg == error_mark_node)
    7806              :                 return error_mark_node;
    7807              :             }
    7808              :         }
    7809       948206 :       else if (!(arg = build_expr_type_conversion (WANT_INT | WANT_ENUM
    7810              :                                                    | WANT_VECTOR_OR_COMPLEX,
    7811              :                                                    arg, true)))
    7812           14 :         errstring = _("wrong type argument to bit-complement");
    7813       948192 :       else if (!noconvert && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (arg)))
    7814              :         {
    7815              :           /* Warn if the expression has boolean value.  */
    7816       947957 :           if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE
    7817       947957 :               && (complain & tf_warning))
    7818              :             {
    7819           61 :               auto_diagnostic_group d;
    7820           61 :               if (warning_at (location, OPT_Wbool_operation,
    7821              :                               "%<~%> on an expression of type %<bool%>"))
    7822           42 :                 inform (location, "did you mean to use logical not (%<!%>)?");
    7823           61 :             }
    7824       947957 :           arg = cp_perform_integral_promotions (arg, complain);
    7825              :         }
    7826          235 :       else if (!noconvert && VECTOR_TYPE_P (TREE_TYPE (arg)))
    7827          235 :         arg = mark_rvalue_use (arg);
    7828              :       break;
    7829              : 
    7830            0 :     case ABS_EXPR:
    7831            0 :       if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, arg, true)))
    7832            0 :         errstring = _("wrong type argument to abs");
    7833            0 :       else if (!noconvert)
    7834              :         {
    7835            0 :           arg = cp_default_conversion (arg, complain);
    7836            0 :           if (arg == error_mark_node)
    7837              :             return error_mark_node;
    7838              :         }
    7839              :       break;
    7840              : 
    7841            0 :     case CONJ_EXPR:
    7842              :       /* Conjugating a real value is a no-op, but allow it anyway.  */
    7843            0 :       if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, arg, true)))
    7844            0 :         errstring = _("wrong type argument to conjugation");
    7845            0 :       else if (!noconvert)
    7846              :         {
    7847            0 :           arg = cp_default_conversion (arg, complain);
    7848            0 :           if (arg == error_mark_node)
    7849              :             return error_mark_node;
    7850              :         }
    7851              :       break;
    7852              : 
    7853     19026094 :     case TRUTH_NOT_EXPR:
    7854     19026094 :       if (gnu_vector_type_p (TREE_TYPE (arg)))
    7855           60 :         return cp_build_binary_op (input_location, EQ_EXPR, arg,
    7856           60 :                                    build_zero_cst (TREE_TYPE (arg)), complain);
    7857     19026034 :       arg = perform_implicit_conversion (boolean_type_node, arg,
    7858              :                                          complain);
    7859     19026034 :       if (arg != error_mark_node)
    7860              :         {
    7861     19026025 :           if (processing_template_decl)
    7862      8106317 :             return build1_loc (location, TRUTH_NOT_EXPR, boolean_type_node, arg);
    7863     10919708 :           val = invert_truthvalue_loc (location, arg);
    7864     10919708 :           if (obvalue_p (val))
    7865        11931 :             val = non_lvalue_loc (location, val);
    7866     10919708 :           return val;
    7867              :         }
    7868            9 :       errstring = _("in argument to unary !");
    7869            9 :       break;
    7870              : 
    7871              :     case NOP_EXPR:
    7872              :       break;
    7873              : 
    7874       440416 :     case REALPART_EXPR:
    7875       440416 :     case IMAGPART_EXPR:
    7876       440416 :       val = build_real_imag_expr (input_location, code, arg);
    7877       440416 :       if (eptype && TREE_CODE (eptype) == COMPLEX_EXPR)
    7878            0 :         val = build1_loc (input_location, EXCESS_PRECISION_EXPR,
    7879            0 :                           TREE_TYPE (eptype), val);
    7880              :       return val;
    7881              : 
    7882      9723487 :     case PREINCREMENT_EXPR:
    7883      9723487 :     case POSTINCREMENT_EXPR:
    7884      9723487 :     case PREDECREMENT_EXPR:
    7885      9723487 :     case POSTDECREMENT_EXPR:
    7886              :       /* Handle complex lvalues (when permitted)
    7887              :          by reduction to simpler cases.  */
    7888              : 
    7889      9723487 :       val = unary_complex_lvalue (code, arg);
    7890      9723487 :       if (val != 0)
    7891           32 :         goto return_build_unary_op;
    7892              : 
    7893      9723455 :       tree stripped_arg;
    7894      9723455 :       stripped_arg = tree_strip_any_location_wrapper (arg);
    7895      2561924 :       if ((VAR_P (stripped_arg) || TREE_CODE (stripped_arg) == PARM_DECL)
    7896      8949240 :           && !DECL_READ_P (stripped_arg)
    7897     10807207 :           && (VAR_P (stripped_arg) ? warn_unused_but_set_variable
    7898              :                                    : warn_unused_but_set_parameter) > 1)
    7899              :         {
    7900         9483 :           arg = mark_lvalue_use (arg);
    7901         9483 :           DECL_READ_P (stripped_arg) = 0;
    7902              :         }
    7903              :       else
    7904      9713972 :         arg = mark_lvalue_use (arg);
    7905              : 
    7906              :       /* Increment or decrement the real part of the value,
    7907              :          and don't change the imaginary part.  */
    7908      9723455 :       if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
    7909              :         {
    7910           18 :           tree real, imag;
    7911              : 
    7912           18 :           arg = cp_stabilize_reference (arg);
    7913           18 :           real = cp_build_unary_op (REALPART_EXPR, arg, true, complain);
    7914           18 :           imag = cp_build_unary_op (IMAGPART_EXPR, arg, true, complain);
    7915           18 :           real = cp_build_unary_op (code, real, true, complain);
    7916           18 :           if (real == error_mark_node || imag == error_mark_node)
    7917              :             return error_mark_node;
    7918           15 :           val = build2 (COMPLEX_EXPR, TREE_TYPE (arg), real, imag);
    7919           15 :           goto return_build_unary_op;
    7920              :         }
    7921              : 
    7922              :       /* Report invalid types.  */
    7923              : 
    7924      9723437 :       if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_POINTER,
    7925              :                                               arg, true)))
    7926              :         {
    7927           36 :           if (code == PREINCREMENT_EXPR)
    7928            9 :             errstring = _("no pre-increment operator for type");
    7929           27 :           else if (code == POSTINCREMENT_EXPR)
    7930            9 :             errstring = _("no post-increment operator for type");
    7931           18 :           else if (code == PREDECREMENT_EXPR)
    7932            9 :             errstring = _("no pre-decrement operator for type");
    7933              :           else
    7934            9 :             errstring = _("no post-decrement operator for type");
    7935              :           break;
    7936              :         }
    7937      9723401 :       else if (arg == error_mark_node)
    7938              :         return error_mark_node;
    7939              : 
    7940              :       /* Report something read-only.  */
    7941              : 
    7942      9723401 :       if (CP_TYPE_CONST_P (TREE_TYPE (arg))
    7943      9723401 :           || TREE_READONLY (arg))
    7944              :         {
    7945          119 :           if (complain & tf_error)
    7946          119 :             cxx_readonly_error (location, arg,
    7947          119 :                                 ((code == PREINCREMENT_EXPR
    7948          119 :                                   || code == POSTINCREMENT_EXPR)
    7949              :                                  ? lv_increment : lv_decrement));
    7950              :           else
    7951            0 :             return error_mark_node;
    7952              :         }
    7953              : 
    7954      9723401 :       {
    7955      9723401 :         tree inc;
    7956      9723401 :         tree declared_type = unlowered_expr_type (arg);
    7957              : 
    7958      9723401 :         argtype = TREE_TYPE (arg);
    7959              : 
    7960              :         /* ARM $5.2.5 last annotation says this should be forbidden.  */
    7961      9723401 :         if (TREE_CODE (argtype) == ENUMERAL_TYPE)
    7962              :           {
    7963            0 :             if (complain & tf_error)
    7964            0 :               permerror (location, (code == PREINCREMENT_EXPR
    7965            0 :                                     || code == POSTINCREMENT_EXPR)
    7966              :                          ? G_("ISO C++ forbids incrementing an enum")
    7967              :                          : G_("ISO C++ forbids decrementing an enum"));
    7968              :             else
    7969            0 :               return error_mark_node;
    7970              :           }
    7971              : 
    7972              :         /* Compute the increment.  */
    7973              : 
    7974      9723401 :         if (TYPE_PTR_P (argtype))
    7975              :           {
    7976      3750967 :             tree type = complete_type (TREE_TYPE (argtype));
    7977              : 
    7978      3750967 :             if (!COMPLETE_OR_VOID_TYPE_P (type))
    7979              :               {
    7980           10 :                 if (complain & tf_error)
    7981            9 :                   error_at (location, ((code == PREINCREMENT_EXPR
    7982            9 :                                         || code == POSTINCREMENT_EXPR))
    7983              :                             ? G_("cannot increment a pointer to incomplete "
    7984              :                                  "type %qT")
    7985              :                             : G_("cannot decrement a pointer to incomplete "
    7986              :                                  "type %qT"),
    7987            9 :                             TREE_TYPE (argtype));
    7988              :                 else
    7989            1 :                   return error_mark_node;
    7990              :               }
    7991      3750957 :             else if (!TYPE_PTROB_P (argtype))
    7992              :               {
    7993           69 :                 if (complain & tf_error)
    7994           63 :                   pedwarn (location, OPT_Wpointer_arith,
    7995           63 :                            (code == PREINCREMENT_EXPR
    7996           63 :                               || code == POSTINCREMENT_EXPR)
    7997              :                            ? G_("ISO C++ forbids incrementing a pointer "
    7998              :                                 "of type %qT")
    7999              :                            : G_("ISO C++ forbids decrementing a pointer "
    8000              :                                 "of type %qT"),
    8001              :                            argtype);
    8002              :                 else
    8003            6 :                   return error_mark_node;
    8004              :               }
    8005      3750888 :             else if (!verify_type_context (location, TCTX_POINTER_ARITH,
    8006      3750888 :                                            TREE_TYPE (argtype),
    8007              :                                            !(complain & tf_error)))
    8008            0 :               return error_mark_node;
    8009              : 
    8010      3750960 :             inc = cxx_sizeof_nowarn (TREE_TYPE (argtype));
    8011              :           }
    8012              :         else
    8013      5972291 :           inc = VECTOR_TYPE_P (argtype)
    8014      5972434 :             ? build_one_cst (argtype)
    8015              :             : integer_one_node;
    8016              : 
    8017      9723394 :         inc = cp_convert (argtype, inc, complain);
    8018              : 
    8019              :         /* If 'arg' is an Objective-C PROPERTY_REF expression, then we
    8020              :            need to ask Objective-C to build the increment or decrement
    8021              :            expression for it.  */
    8022      9723394 :         if (objc_is_property_ref (arg))
    8023            0 :           return objc_build_incr_expr_for_property_ref (input_location, code,
    8024            0 :                                                         arg, inc);
    8025              : 
    8026              :         /* Complain about anything else that is not a true lvalue.  */
    8027      9723394 :         if (!lvalue_or_else (arg, ((code == PREINCREMENT_EXPR
    8028      9723394 :                                     || code == POSTINCREMENT_EXPR)
    8029              :                                    ? lv_increment : lv_decrement),
    8030              :                              complain))
    8031           36 :           return error_mark_node;
    8032              : 
    8033              :         /* [depr.volatile.type] "Postfix ++ and -- expressions and
    8034              :            prefix ++ and -- expressions of volatile-qualified arithmetic
    8035              :            and pointer types are deprecated."  */
    8036      9723073 :         if ((TREE_THIS_VOLATILE (arg) || CP_TYPE_VOLATILE_P (TREE_TYPE (arg)))
    8037      9723358 :             && (complain & tf_warning))
    8038          398 :           warning_at (location, OPT_Wvolatile,
    8039              :                       "%qs expression of %<volatile%>-qualified type is "
    8040              :                       "deprecated",
    8041              :                       ((code == PREINCREMENT_EXPR
    8042              :                         || code == POSTINCREMENT_EXPR)
    8043              :                        ? "++" : "--"));
    8044              : 
    8045              :         /* Forbid using -- or ++ in C++17 on `bool'.  */
    8046      9723358 :         if (TREE_CODE (declared_type) == BOOLEAN_TYPE)
    8047              :           {
    8048           95 :             if (code == POSTDECREMENT_EXPR || code == PREDECREMENT_EXPR)
    8049              :               {
    8050           33 :                 if (complain & tf_error)
    8051           33 :                   error_at (location,
    8052              :                             "use of an operand of type %qT in %<operator--%> "
    8053              :                             "is forbidden", boolean_type_node);
    8054           33 :                 return error_mark_node;
    8055              :               }
    8056              :             else
    8057              :               {
    8058           62 :                 if (cxx_dialect >= cxx17)
    8059              :                   {
    8060           33 :                     if (complain & tf_error)
    8061           32 :                       error_at (location,
    8062              :                                 "use of an operand of type %qT in "
    8063              :                                 "%<operator++%> is forbidden in C++17",
    8064              :                                 boolean_type_node);
    8065           33 :                     return error_mark_node;
    8066              :                   }
    8067              :                 /* Otherwise, [depr.incr.bool] says this is deprecated.  */
    8068           29 :                 else if (complain & tf_warning)
    8069           25 :                   warning_at (location, OPT_Wdeprecated,
    8070              :                               "use of an operand of type %qT "
    8071              :                               "in %<operator++%> is deprecated",
    8072              :                               boolean_type_node);
    8073              :               }
    8074           29 :             val = boolean_increment (code, arg);
    8075              :           }
    8076      9723263 :         else if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
    8077              :           /* An rvalue has no cv-qualifiers.  */
    8078      1712659 :           val = build2 (code, cv_unqualified (TREE_TYPE (arg)), arg, inc);
    8079              :         else
    8080      8010604 :           val = build2 (code, TREE_TYPE (arg), arg, inc);
    8081              : 
    8082      9723292 :         TREE_SIDE_EFFECTS (val) = 1;
    8083      9723292 :         goto return_build_unary_op;
    8084              :       }
    8085              : 
    8086      1001813 :     case ADDR_EXPR:
    8087              :       /* Note that this operation never does default_conversion
    8088              :          regardless of NOCONVERT.  */
    8089      1001813 :       return cp_build_addr_expr (arg, complain);
    8090              : 
    8091              :     default:
    8092              :       break;
    8093              :     }
    8094              : 
    8095      3412191 :   if (!errstring)
    8096              :     {
    8097      3412113 :       if (argtype == 0)
    8098      3412113 :         argtype = TREE_TYPE (arg);
    8099      3412113 :       val = build1 (code, argtype, arg);
    8100     13135452 :     return_build_unary_op:
    8101     13135452 :       if (eptype)
    8102         6353 :         val = build1 (EXCESS_PRECISION_EXPR, eptype, val);
    8103     13135452 :       return val;
    8104              :     }
    8105              : 
    8106           93 :   if (complain & tf_error)
    8107           50 :     error_at (location, "%s", errstring);
    8108           93 :   return error_mark_node;
    8109              : }
    8110              : 
    8111              : /* Hook for the c-common bits that build a unary op.  */
    8112              : tree
    8113         4136 : build_unary_op (location_t /*location*/,
    8114              :                 enum tree_code code, tree xarg, bool noconvert)
    8115              : {
    8116         4136 :   return cp_build_unary_op (code, xarg, noconvert, tf_warning_or_error);
    8117              : }
    8118              : 
    8119              : /* Adjust LVALUE, an MODIFY_EXPR, PREINCREMENT_EXPR or PREDECREMENT_EXPR,
    8120              :    so that it is a valid lvalue even for GENERIC by replacing
    8121              :    (lhs = rhs) with ((lhs = rhs), lhs)
    8122              :    (--lhs) with ((--lhs), lhs)
    8123              :    (++lhs) with ((++lhs), lhs)
    8124              :    and if lhs has side-effects, calling cp_stabilize_reference on it, so
    8125              :    that it can be evaluated multiple times.  */
    8126              : 
    8127              : tree
    8128       390318 : genericize_compound_lvalue (tree lvalue)
    8129              : {
    8130       390318 :   if (TREE_SIDE_EFFECTS (TREE_OPERAND (lvalue, 0)))
    8131          196 :     lvalue = build2 (TREE_CODE (lvalue), TREE_TYPE (lvalue),
    8132          196 :                      cp_stabilize_reference (TREE_OPERAND (lvalue, 0)),
    8133          196 :                      TREE_OPERAND (lvalue, 1));
    8134       390318 :   return build2 (COMPOUND_EXPR, TREE_TYPE (TREE_OPERAND (lvalue, 0)),
    8135       390318 :                  lvalue, TREE_OPERAND (lvalue, 0));
    8136              : }
    8137              : 
    8138              : /* Apply unary lvalue-demanding operator CODE to the expression ARG
    8139              :    for certain kinds of expressions which are not really lvalues
    8140              :    but which we can accept as lvalues.
    8141              : 
    8142              :    If ARG is not a kind of expression we can handle, return
    8143              :    NULL_TREE.  */
    8144              : 
    8145              : tree
    8146    405101915 : unary_complex_lvalue (enum tree_code code, tree arg)
    8147              : {
    8148              :   /* Inside a template, making these kinds of adjustments is
    8149              :      pointless; we are only concerned with the type of the
    8150              :      expression.  */
    8151    405492003 :   if (processing_template_decl)
    8152              :     return NULL_TREE;
    8153              : 
    8154              :   /* Handle (a, b) used as an "lvalue".  */
    8155    319654370 :   if (TREE_CODE (arg) == COMPOUND_EXPR)
    8156              :     {
    8157       391274 :       tree real_result = cp_build_unary_op (code, TREE_OPERAND (arg, 1), false,
    8158              :                                             tf_warning_or_error);
    8159       391274 :       return build2 (COMPOUND_EXPR, TREE_TYPE (real_result),
    8160       782548 :                      TREE_OPERAND (arg, 0), real_result);
    8161              :     }
    8162              : 
    8163              :   /* Handle (a ? b : c) used as an "lvalue".  */
    8164    319263096 :   if (TREE_CODE (arg) == COND_EXPR
    8165    318959717 :       || TREE_CODE (arg) == MIN_EXPR || TREE_CODE (arg) == MAX_EXPR)
    8166       303379 :     return rationalize_conditional_expr (code, arg, tf_warning_or_error);
    8167              : 
    8168              :   /* Handle (a = b), (++a), and (--a) used as an "lvalue".  */
    8169    318959717 :   if (TREE_CODE (arg) == MODIFY_EXPR
    8170    318569752 :       || TREE_CODE (arg) == PREINCREMENT_EXPR
    8171    318569691 :       || TREE_CODE (arg) == PREDECREMENT_EXPR)
    8172       390088 :     return unary_complex_lvalue (code, genericize_compound_lvalue (arg));
    8173              : 
    8174    318569629 :   if (code != ADDR_EXPR)
    8175              :     return NULL_TREE;
    8176              : 
    8177              :   /* Handle (a = b) used as an "lvalue" for `&'.  */
    8178    313391549 :   if (TREE_CODE (arg) == MODIFY_EXPR
    8179    313391549 :       || TREE_CODE (arg) == INIT_EXPR)
    8180              :     {
    8181            0 :       tree real_result = cp_build_unary_op (code, TREE_OPERAND (arg, 0), false,
    8182              :                                             tf_warning_or_error);
    8183            0 :       arg = build2 (COMPOUND_EXPR, TREE_TYPE (real_result),
    8184              :                     arg, real_result);
    8185            0 :       suppress_warning (arg /* What warning? */);
    8186            0 :       return arg;
    8187              :     }
    8188              : 
    8189    485550329 :   if (FUNC_OR_METHOD_TYPE_P (TREE_TYPE (arg))
    8190    485549272 :       || TREE_CODE (arg) == OFFSET_REF)
    8191              :     return NULL_TREE;
    8192              : 
    8193              :   /* We permit compiler to make function calls returning
    8194              :      objects of aggregate type look like lvalues.  */
    8195    172157723 :   {
    8196    172157723 :     tree targ = arg;
    8197              : 
    8198    172157723 :     if (TREE_CODE (targ) == SAVE_EXPR)
    8199            0 :       targ = TREE_OPERAND (targ, 0);
    8200              : 
    8201    172157723 :     if (TREE_CODE (targ) == CALL_EXPR && MAYBE_CLASS_TYPE_P (TREE_TYPE (targ)))
    8202              :       {
    8203           26 :         if (TREE_CODE (arg) == SAVE_EXPR)
    8204              :           targ = arg;
    8205              :         else
    8206           26 :           targ = build_cplus_new (TREE_TYPE (arg), arg, tf_warning_or_error);
    8207           26 :         return build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg)), targ);
    8208              :       }
    8209              : 
    8210    172157697 :     if (TREE_CODE (arg) == SAVE_EXPR && INDIRECT_REF_P (targ))
    8211            0 :       return build3 (SAVE_EXPR, build_pointer_type (TREE_TYPE (arg)),
    8212            0 :                      TREE_OPERAND (targ, 0), current_function_decl, NULL);
    8213              :   }
    8214              : 
    8215              :   /* Don't let anything else be handled specially.  */
    8216              :   return NULL_TREE;
    8217              : }
    8218              : 
    8219              : /* Mark EXP saying that we need to be able to take the
    8220              :    address of it; it should not be allocated in a register.
    8221              :    Value is true if successful.  ARRAY_REF_P is true if this
    8222              :    is for ARRAY_REF construction - in that case we don't want
    8223              :    to look through VIEW_CONVERT_EXPR from VECTOR_TYPE to ARRAY_TYPE,
    8224              :    it is fine to use ARRAY_REFs for vector subscripts on vector
    8225              :    register variables.
    8226              : 
    8227              :    C++: we do not allow `current_class_ptr' to be addressable.  */
    8228              : 
    8229              : bool
    8230    496163194 : cxx_mark_addressable (tree exp, bool array_ref_p)
    8231              : {
    8232    496163194 :   tree x = exp;
    8233              : 
    8234    593799061 :   while (1)
    8235    593799061 :     switch (TREE_CODE (x))
    8236              :       {
    8237     54969048 :       case VIEW_CONVERT_EXPR:
    8238     54969048 :         if (array_ref_p
    8239       771753 :             && TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE
    8240     55547661 :             && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (x, 0))))
    8241              :           return true;
    8242     54966151 :         x = TREE_OPERAND (x, 0);
    8243     54966151 :         break;
    8244              : 
    8245     42293869 :       case COMPONENT_REF:
    8246     42293869 :         if (bitfield_p (x))
    8247            9 :           error ("attempt to take address of bit-field");
    8248              :         /* FALLTHRU */
    8249     42669716 :       case ADDR_EXPR:
    8250     42669716 :       case ARRAY_REF:
    8251     42669716 :       case REALPART_EXPR:
    8252     42669716 :       case IMAGPART_EXPR:
    8253     42669716 :         x = TREE_OPERAND (x, 0);
    8254     42669716 :         break;
    8255              : 
    8256     13573569 :       case PARM_DECL:
    8257     13573569 :         if (x == current_class_ptr)
    8258              :           {
    8259           18 :             error ("cannot take the address of %<this%>, which is an rvalue expression");
    8260           18 :             TREE_ADDRESSABLE (x) = 1; /* so compiler doesn't die later.  */
    8261           18 :             return true;
    8262              :           }
    8263              :         /* Fall through.  */
    8264              : 
    8265    113912992 :       case VAR_DECL:
    8266              :         /* Caller should not be trying to mark initialized
    8267              :            constant fields addressable.  */
    8268    113912992 :         gcc_assert (DECL_LANG_SPECIFIC (x) == 0
    8269              :                     || DECL_IN_AGGR_P (x) == 0
    8270              :                     || TREE_STATIC (x)
    8271              :                     || DECL_EXTERNAL (x));
    8272              :         /* Fall through.  */
    8273              : 
    8274    114028244 :       case RESULT_DECL:
    8275    114028335 :         if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)
    8276    114028326 :             && !DECL_ARTIFICIAL (x))
    8277              :           {
    8278           31 :             if (VAR_P (x) && DECL_HARD_REGISTER (x))
    8279              :               {
    8280           15 :                 error
    8281           15 :                   ("address of explicit register variable %qD requested", x);
    8282           15 :                 return false;
    8283              :               }
    8284           16 :             else if (extra_warnings)
    8285            3 :               warning
    8286            3 :                 (OPT_Wextra, "address requested for %qD, which is declared %<register%>", x);
    8287              :           }
    8288    114028229 :         TREE_ADDRESSABLE (x) = 1;
    8289    114028229 :         return true;
    8290              : 
    8291    241143970 :       case CONST_DECL:
    8292    241143970 :       case FUNCTION_DECL:
    8293    241143970 :         TREE_ADDRESSABLE (x) = 1;
    8294    241143970 :         return true;
    8295              : 
    8296        52350 :       case CONSTRUCTOR:
    8297        52350 :         TREE_ADDRESSABLE (x) = 1;
    8298        52350 :         return true;
    8299              : 
    8300     22208983 :       case TARGET_EXPR:
    8301     22208983 :         TREE_ADDRESSABLE (x) = 1;
    8302     22208983 :         cxx_mark_addressable (TARGET_EXPR_SLOT (x));
    8303     22208983 :         return true;
    8304              : 
    8305              :       default:
    8306              :         return true;
    8307              :     }
    8308              : }
    8309              : 
    8310              : /* Build and return a conditional expression IFEXP ? OP1 : OP2.  */
    8311              : 
    8312              : tree
    8313     10242834 : build_x_conditional_expr (location_t loc, tree ifexp, tree op1, tree op2,
    8314              :                           tsubst_flags_t complain)
    8315              : {
    8316     10242834 :   tree orig_ifexp = ifexp;
    8317     10242834 :   tree orig_op1 = op1;
    8318     10242834 :   tree orig_op2 = op2;
    8319     10242834 :   tree expr;
    8320              : 
    8321     10242834 :   if (processing_template_decl)
    8322              :     {
    8323              :       /* The standard says that the expression is type-dependent if
    8324              :          IFEXP is type-dependent, even though the eventual type of the
    8325              :          expression doesn't dependent on IFEXP.  */
    8326      3342826 :       if (type_dependent_expression_p (ifexp)
    8327              :           /* As a GNU extension, the middle operand may be omitted.  */
    8328      1829662 :           || (op1 && type_dependent_expression_p (op1))
    8329      4674214 :           || type_dependent_expression_p (op2))
    8330      2039183 :         return build_min_nt_loc (loc, COND_EXPR, ifexp, op1, op2);
    8331              :     }
    8332              : 
    8333      8203651 :   expr = build_conditional_expr (loc, ifexp, op1, op2, complain);
    8334      8203651 :   if (processing_template_decl && expr != error_mark_node)
    8335              :     {
    8336      1303637 :       tree min = build_min_non_dep (COND_EXPR, expr,
    8337              :                                     orig_ifexp, orig_op1, orig_op2);
    8338      1303637 :       expr = convert_from_reference (min);
    8339              :     }
    8340              :   return expr;
    8341              : }
    8342              : 
    8343              : /* Given a list of expressions, return a compound expression
    8344              :    that performs them all and returns the value of the last of them.  */
    8345              : 
    8346              : tree
    8347     33358019 : build_x_compound_expr_from_list (tree list, expr_list_kind exp,
    8348              :                                  tsubst_flags_t complain)
    8349              : {
    8350     33358019 :   tree expr = TREE_VALUE (list);
    8351              : 
    8352       512801 :   if (BRACE_ENCLOSED_INITIALIZER_P (expr)
    8353     33870808 :       && !CONSTRUCTOR_IS_DIRECT_INIT (expr))
    8354              :     {
    8355           14 :       if (complain & tf_error)
    8356           28 :         pedwarn (cp_expr_loc_or_input_loc (expr), 0,
    8357              :                  "list-initializer for non-class type must not "
    8358              :                  "be parenthesized");
    8359              :       else
    8360            0 :         return error_mark_node;
    8361              :     }
    8362              : 
    8363     33358019 :   if (TREE_CHAIN (list))
    8364              :     {
    8365           23 :       if (complain & tf_error)
    8366           14 :         switch (exp)
    8367              :           {
    8368           12 :           case ELK_INIT:
    8369           12 :             permerror (input_location, "expression list treated as compound "
    8370              :                                        "expression in initializer");
    8371           12 :             break;
    8372            1 :           case ELK_MEM_INIT:
    8373            1 :             permerror (input_location, "expression list treated as compound "
    8374              :                                        "expression in mem-initializer");
    8375            1 :             break;
    8376            1 :           case ELK_FUNC_CAST:
    8377            1 :             permerror (input_location, "expression list treated as compound "
    8378              :                                        "expression in functional cast");
    8379            1 :             break;
    8380            0 :           default:
    8381            0 :             gcc_unreachable ();
    8382              :           }
    8383              :       else
    8384            9 :         return error_mark_node;
    8385              : 
    8386           28 :       for (list = TREE_CHAIN (list); list; list = TREE_CHAIN (list))
    8387           28 :         expr = build_x_compound_expr (EXPR_LOCATION (TREE_VALUE (list)),
    8388           14 :                                       expr, TREE_VALUE (list), NULL_TREE,
    8389              :                                       complain);
    8390              :     }
    8391              : 
    8392              :   return expr;
    8393              : }
    8394              : 
    8395              : /* Like build_x_compound_expr_from_list, but using a VEC.  */
    8396              : 
    8397              : tree
    8398       381047 : build_x_compound_expr_from_vec (vec<tree, va_gc> *vec, const char *msg,
    8399              :                                 tsubst_flags_t complain)
    8400              : {
    8401       381047 :   if (vec_safe_is_empty (vec))
    8402              :     return NULL_TREE;
    8403       381047 :   else if (vec->length () == 1)
    8404       380983 :     return (*vec)[0];
    8405              :   else
    8406              :     {
    8407           64 :       tree expr;
    8408           64 :       unsigned int ix;
    8409           64 :       tree t;
    8410              : 
    8411           64 :       if (msg != NULL)
    8412              :         {
    8413            4 :           if (complain & tf_error)
    8414            0 :             permerror (input_location,
    8415              :                        "%s expression list treated as compound expression",
    8416              :                        msg);
    8417              :           else
    8418            4 :             return error_mark_node;
    8419              :         }
    8420              : 
    8421           60 :       expr = (*vec)[0];
    8422          134 :       for (ix = 1; vec->iterate (ix, &t); ++ix)
    8423           74 :         expr = build_x_compound_expr (EXPR_LOCATION (t), expr,
    8424              :                                       t, NULL_TREE, complain);
    8425              : 
    8426              :       return expr;
    8427              :     }
    8428              : }
    8429              : 
    8430              : /* Handle overloading of the ',' operator when needed.  */
    8431              : 
    8432              : tree
    8433      3021588 : build_x_compound_expr (location_t loc, tree op1, tree op2,
    8434              :                        tree lookups, tsubst_flags_t complain)
    8435              : {
    8436      3021588 :   tree result;
    8437      3021588 :   tree orig_op1 = op1;
    8438      3021588 :   tree orig_op2 = op2;
    8439      3021588 :   tree overload = NULL_TREE;
    8440              : 
    8441      3021588 :   if (processing_template_decl)
    8442              :     {
    8443      2783600 :       if (type_dependent_expression_p (op1)
    8444      2783600 :           || type_dependent_expression_p (op2))
    8445              :         {
    8446      2523226 :           result = build_min_nt_loc (loc, COMPOUND_EXPR, op1, op2);
    8447      2523226 :           TREE_TYPE (result)
    8448      2523226 :             = build_dependent_operator_type (lookups, COMPOUND_EXPR, false);
    8449      2523226 :           return result;
    8450              :         }
    8451              :     }
    8452              : 
    8453       498362 :   result = build_new_op (loc, COMPOUND_EXPR, LOOKUP_NORMAL, op1, op2,
    8454              :                          NULL_TREE, lookups, &overload, complain);
    8455       498362 :   if (!result)
    8456       490107 :     result = cp_build_compound_expr (op1, op2, complain);
    8457              : 
    8458       498362 :   if (processing_template_decl && result != error_mark_node)
    8459              :     {
    8460       258553 :       if (overload != NULL_TREE)
    8461           52 :         return (build_min_non_dep_op_overload
    8462           52 :                 (COMPOUND_EXPR, result, overload, orig_op1, orig_op2));
    8463              : 
    8464       258501 :       return build_min_non_dep (COMPOUND_EXPR, result, orig_op1, orig_op2);
    8465              :     }
    8466              : 
    8467              :   return result;
    8468              : }
    8469              : 
    8470              : /* Like cp_build_compound_expr, but for the c-common bits.  */
    8471              : 
    8472              : tree
    8473        16005 : build_compound_expr (location_t /*loc*/, tree lhs, tree rhs)
    8474              : {
    8475        16005 :   return cp_build_compound_expr (lhs, rhs, tf_warning_or_error);
    8476              : }
    8477              : 
    8478              : /* Build a compound expression.  */
    8479              : 
    8480              : tree
    8481       638077 : cp_build_compound_expr (tree lhs, tree rhs, tsubst_flags_t complain)
    8482              : {
    8483       638077 :   lhs = convert_to_void (lhs, ICV_LEFT_OF_COMMA, complain);
    8484              : 
    8485       638077 :   if (lhs == error_mark_node || rhs == error_mark_node)
    8486              :     return error_mark_node;
    8487              : 
    8488       638074 :   if (TREE_CODE (lhs) == EXCESS_PRECISION_EXPR)
    8489            0 :     lhs = TREE_OPERAND (lhs, 0);
    8490       638074 :   tree eptype = NULL_TREE;
    8491       638074 :   if (TREE_CODE (rhs) == EXCESS_PRECISION_EXPR)
    8492              :     {
    8493            3 :       eptype = TREE_TYPE (rhs);
    8494            3 :       rhs = TREE_OPERAND (rhs, 0);
    8495              :     }
    8496              : 
    8497       638074 :   if (TREE_CODE (rhs) == TARGET_EXPR)
    8498              :     {
    8499              :       /* If the rhs is a TARGET_EXPR, then build the compound
    8500              :          expression inside the target_expr's initializer. This
    8501              :          helps the compiler to eliminate unnecessary temporaries.  */
    8502        29977 :       tree init = TARGET_EXPR_INITIAL (rhs);
    8503              : 
    8504        29977 :       init = build2 (COMPOUND_EXPR, TREE_TYPE (init), lhs, init);
    8505        29977 :       TARGET_EXPR_INITIAL (rhs) = init;
    8506              : 
    8507        29977 :       if (eptype)
    8508            0 :         rhs = build1 (EXCESS_PRECISION_EXPR, eptype, rhs);
    8509        29977 :       return rhs;
    8510              :     }
    8511              : 
    8512       608097 :   rhs = resolve_nondeduced_context (rhs, complain);
    8513              : 
    8514       608097 :   if (type_unknown_p (rhs))
    8515              :     {
    8516           33 :       if (complain & tf_error)
    8517           51 :         error_at (cp_expr_loc_or_input_loc (rhs),
    8518              :                   "no context to resolve type of %qE", rhs);
    8519           33 :       return error_mark_node;
    8520              :     }
    8521              : 
    8522       608064 :   tree ret = build2 (COMPOUND_EXPR, TREE_TYPE (rhs), lhs, rhs);
    8523       608064 :   if (eptype)
    8524            3 :     ret = build1 (EXCESS_PRECISION_EXPR, eptype, ret);
    8525              :   return ret;
    8526              : }
    8527              : 
    8528              : /* Issue a diagnostic message if casting from SRC_TYPE to DEST_TYPE
    8529              :    casts away constness.  CAST gives the type of cast.  Returns true
    8530              :    if the cast is ill-formed, false if it is well-formed.
    8531              : 
    8532              :    ??? This function warns for casting away any qualifier not just
    8533              :    const.  We would like to specify exactly what qualifiers are casted
    8534              :    away.
    8535              : */
    8536              : 
    8537              : static bool
    8538      1033764 : check_for_casting_away_constness (location_t loc, tree src_type,
    8539              :                                   tree dest_type, enum tree_code cast,
    8540              :                                   tsubst_flags_t complain)
    8541              : {
    8542              :   /* C-style casts are allowed to cast away constness.  With
    8543              :      WARN_CAST_QUAL, we still want to issue a warning.  */
    8544      1033764 :   if (cast == CAST_EXPR && !warn_cast_qual)
    8545              :     return false;
    8546              : 
    8547       714064 :   if (!casts_away_constness (src_type, dest_type, complain))
    8548              :     return false;
    8549              : 
    8550          392 :   switch (cast)
    8551              :     {
    8552          335 :     case CAST_EXPR:
    8553          335 :       if (complain & tf_warning)
    8554          335 :         warning_at (loc, OPT_Wcast_qual,
    8555              :                     "cast from type %qT to type %qT casts away qualifiers",
    8556              :                     src_type, dest_type);
    8557              :       return false;
    8558              : 
    8559           36 :     case STATIC_CAST_EXPR:
    8560           36 :       if (complain & tf_error)
    8561           24 :         error_at (loc, "%<static_cast%> from type %qT to type %qT casts "
    8562              :                   "away qualifiers",
    8563              :                   src_type, dest_type);
    8564              :       return true;
    8565              : 
    8566           21 :     case REINTERPRET_CAST_EXPR:
    8567           21 :       if (complain & tf_error)
    8568           15 :         error_at (loc, "%<reinterpret_cast%> from type %qT to type %qT "
    8569              :                   "casts away qualifiers",
    8570              :                   src_type, dest_type);
    8571              :       return true;
    8572              : 
    8573            0 :     default:
    8574            0 :       gcc_unreachable();
    8575              :     }
    8576              : }
    8577              : 
    8578              : /* Warns if the cast from expression EXPR to type TYPE is useless.  */
    8579              : void
    8580     54067397 : maybe_warn_about_useless_cast (location_t loc, tree type, tree expr,
    8581              :                                tsubst_flags_t complain)
    8582              : {
    8583     54067397 :   if (warn_useless_cast
    8584          152 :       && complain & tf_warning)
    8585              :     {
    8586          152 :       if (TYPE_REF_P (type)
    8587          152 :           ? ((TYPE_REF_IS_RVALUE (type)
    8588           86 :               ? xvalue_p (expr) : lvalue_p (expr))
    8589          172 :              && same_type_p (TREE_TYPE (expr), TREE_TYPE (type)))
    8590              :           /* Don't warn when converting a class object to a non-reference type,
    8591              :              because that's a common way to create a temporary.  */
    8592           66 :           : (!glvalue_p (expr) && same_type_p (TREE_TYPE (expr), type)))
    8593           96 :         warning_at (loc, OPT_Wuseless_cast,
    8594              :                     "useless cast to type %q#T", type);
    8595              :     }
    8596     54067397 : }
    8597              : 
    8598              : /* Warns if the cast ignores cv-qualifiers on TYPE.  */
    8599              : static void
    8600     54044813 : maybe_warn_about_cast_ignoring_quals (location_t loc, tree type,
    8601              :                                       tsubst_flags_t complain)
    8602              : {
    8603     54044813 :   if (warn_ignored_qualifiers
    8604       269012 :       && complain & tf_warning
    8605       268539 :       && !CLASS_TYPE_P (type)
    8606     54308407 :       && (cp_type_quals (type) & (TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE)))
    8607           36 :     warning_at (loc, OPT_Wignored_qualifiers,
    8608              :                 "type qualifiers ignored on cast result type");
    8609     54044813 : }
    8610              : 
    8611              : /* Convert EXPR (an expression with pointer-to-member type) to TYPE
    8612              :    (another pointer-to-member type in the same hierarchy) and return
    8613              :    the converted expression.  If ALLOW_INVERSE_P is permitted, a
    8614              :    pointer-to-derived may be converted to pointer-to-base; otherwise,
    8615              :    only the other direction is permitted.  If C_CAST_P is true, this
    8616              :    conversion is taking place as part of a C-style cast.  */
    8617              : 
    8618              : tree
    8619        27849 : convert_ptrmem (tree type, tree expr, bool allow_inverse_p,
    8620              :                 bool c_cast_p, tsubst_flags_t complain)
    8621              : {
    8622        27849 :   if (same_type_p (type, TREE_TYPE (expr)))
    8623              :     return expr;
    8624              : 
    8625        27849 :   if (TYPE_PTRDATAMEM_P (type))
    8626              :     {
    8627          382 :       tree obase = TYPE_PTRMEM_CLASS_TYPE (TREE_TYPE (expr));
    8628          382 :       tree nbase = TYPE_PTRMEM_CLASS_TYPE (type);
    8629          382 :       tree delta = (get_delta_difference
    8630          382 :                     (obase, nbase,
    8631              :                      allow_inverse_p, c_cast_p, complain));
    8632              : 
    8633          382 :       if (delta == error_mark_node)
    8634              :         return error_mark_node;
    8635              : 
    8636          376 :       if (!same_type_p (obase, nbase))
    8637              :         {
    8638          293 :           if (TREE_CODE (expr) == PTRMEM_CST)
    8639          157 :             expr = cplus_expand_constant (expr);
    8640              : 
    8641          293 :           tree cond = cp_build_binary_op (input_location, EQ_EXPR, expr,
    8642          293 :                                           build_int_cst (TREE_TYPE (expr), -1),
    8643              :                                           complain);
    8644          293 :           tree op1 = build_nop (ptrdiff_type_node, expr);
    8645          293 :           tree op2 = cp_build_binary_op (input_location, PLUS_EXPR, op1, delta,
    8646              :                                          complain);
    8647              : 
    8648          293 :           expr = fold_build3_loc (input_location,
    8649              :                                   COND_EXPR, ptrdiff_type_node, cond, op1, op2);
    8650              :         }
    8651              : 
    8652          376 :       return build_nop (type, expr);
    8653              :     }
    8654              :   else
    8655        27467 :     return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr,
    8656        27467 :                              allow_inverse_p, c_cast_p, complain);
    8657              : }
    8658              : 
    8659              : /* Perform a static_cast from EXPR to TYPE.  When C_CAST_P is true,
    8660              :    this static_cast is being attempted as one of the possible casts
    8661              :    allowed by a C-style cast.  (In that case, accessibility of base
    8662              :    classes is not considered, and it is OK to cast away
    8663              :    constness.)  Return the result of the cast.  *VALID_P is set to
    8664              :    indicate whether or not the cast was valid.  */
    8665              : 
    8666              : static tree
    8667     53333861 : build_static_cast_1 (location_t loc, tree type, tree expr, bool c_cast_p,
    8668              :                      bool *valid_p, tsubst_flags_t complain)
    8669              : {
    8670     53333861 :   tree intype;
    8671     53333861 :   tree result;
    8672     53333861 :   cp_lvalue_kind clk;
    8673              : 
    8674              :   /* Assume the cast is valid.  */
    8675     53333861 :   *valid_p = true;
    8676              : 
    8677     53333861 :   intype = unlowered_expr_type (expr);
    8678              : 
    8679              :   /* Save casted types in the function's used types hash table.  */
    8680     53333861 :   used_types_insert (type);
    8681              : 
    8682              :   /* A prvalue of non-class type is cv-unqualified.  */
    8683     53333861 :   if (!CLASS_TYPE_P (type))
    8684     49749676 :     type = cv_unqualified (type);
    8685              : 
    8686              :   /* [expr.static.cast]
    8687              : 
    8688              :      An lvalue of type "cv1 B", where B is a class type, can be cast
    8689              :      to type "reference to cv2 D", where D is a class derived (clause
    8690              :      _class.derived_) from B, if a valid standard conversion from
    8691              :      "pointer to D" to "pointer to B" exists (_conv.ptr_), cv2 is the
    8692              :      same cv-qualification as, or greater cv-qualification than, cv1,
    8693              :      and B is not a virtual base class of D.  */
    8694              :   /* We check this case before checking the validity of "TYPE t =
    8695              :      EXPR;" below because for this case:
    8696              : 
    8697              :        struct B {};
    8698              :        struct D : public B { D(const B&); };
    8699              :        extern B& b;
    8700              :        void f() { static_cast<const D&>(b); }
    8701              : 
    8702              :      we want to avoid constructing a new D.  The standard is not
    8703              :      completely clear about this issue, but our interpretation is
    8704              :      consistent with other compilers.  */
    8705     53333861 :   if (TYPE_REF_P (type)
    8706      6830448 :       && CLASS_TYPE_P (TREE_TYPE (type))
    8707      4699425 :       && CLASS_TYPE_P (intype)
    8708      4699408 :       && (TYPE_REF_IS_RVALUE (type) || lvalue_p (expr))
    8709      4678388 :       && DERIVED_FROM_P (intype, TREE_TYPE (type))
    8710      4648202 :       && can_convert (build_pointer_type (TYPE_MAIN_VARIANT (intype)),
    8711      4648202 :                       build_pointer_type (TYPE_MAIN_VARIANT
    8712              :                                           (TREE_TYPE (type))),
    8713              :                       complain)
    8714     57982063 :       && (c_cast_p
    8715      4648178 :           || at_least_as_qualified_p (TREE_TYPE (type), intype)))
    8716              :     {
    8717      4648202 :       tree base;
    8718              : 
    8719      4648202 :       if (processing_template_decl)
    8720              :         return expr;
    8721              : 
    8722              :       /* There is a standard conversion from "D*" to "B*" even if "B"
    8723              :          is ambiguous or inaccessible.  If this is really a
    8724              :          static_cast, then we check both for inaccessibility and
    8725              :          ambiguity.  However, if this is a static_cast being performed
    8726              :          because the user wrote a C-style cast, then accessibility is
    8727              :          not considered.  */
    8728      8856718 :       base = lookup_base (TREE_TYPE (type), intype,
    8729              :                           c_cast_p ? ba_unique : ba_check,
    8730              :                           NULL, complain);
    8731      4428371 :       expr = cp_build_addr_expr (expr, complain);
    8732              : 
    8733      4428371 :       if (sanitize_flags_p (SANITIZE_VPTR))
    8734              :         {
    8735          487 :           tree ubsan_check
    8736          487 :             = cp_ubsan_maybe_instrument_downcast (loc, type,
    8737              :                                                   intype, expr);
    8738          487 :           if (ubsan_check)
    8739      4428371 :             expr = ubsan_check;
    8740              :         }
    8741              : 
    8742              :       /* Convert from "B*" to "D*".  This function will check that "B"
    8743              :          is not a virtual base of "D".  Even if we don't have a guarantee
    8744              :          that expr is NULL, if the static_cast is to a reference type,
    8745              :          it is UB if it would be NULL, so omit the non-NULL check.  */
    8746      4428371 :       expr = build_base_path (MINUS_EXPR, expr, base,
    8747              :                               /*nonnull=*/flag_delete_null_pointer_checks,
    8748              :                               complain);
    8749              : 
    8750              :       /* Convert the pointer to a reference -- but then remember that
    8751              :          there are no expressions with reference type in C++.
    8752              : 
    8753              :          We call rvalue so that there's an actual tree code
    8754              :          (NON_LVALUE_EXPR) for the static_cast; otherwise, if the operand
    8755              :          is a variable with the same type, the conversion would get folded
    8756              :          away, leaving just the variable and causing lvalue_kind to give
    8757              :          the wrong answer.  */
    8758      4428371 :       expr = cp_fold_convert (type, expr);
    8759              : 
    8760              :       /* When -fsanitize=null, make sure to diagnose reference binding to
    8761              :          NULL even when the reference is converted to pointer later on.  */
    8762      4428371 :       if (sanitize_flags_p (SANITIZE_NULL)
    8763          493 :           && TREE_CODE (expr) == COND_EXPR
    8764            6 :           && TREE_OPERAND (expr, 2)
    8765            6 :           && TREE_CODE (TREE_OPERAND (expr, 2)) == INTEGER_CST
    8766      4428377 :           && TREE_TYPE (TREE_OPERAND (expr, 2)) == type)
    8767            6 :         ubsan_maybe_instrument_reference (&TREE_OPERAND (expr, 2));
    8768              : 
    8769      4428371 :       return convert_from_reference (rvalue (expr));
    8770              :     }
    8771              : 
    8772              :   /* "A glvalue of type cv1 T1 can be cast to type rvalue reference to
    8773              :      cv2 T2 if cv2 T2 is reference-compatible with cv1 T1 (8.5.3)."  */
    8774     48685659 :   if (TYPE_REF_P (type)
    8775      2182246 :       && TYPE_REF_IS_RVALUE (type)
    8776       903058 :       && (clk = real_lvalue_p (expr))
    8777       892213 :       && reference_compatible_p (TREE_TYPE (type), intype)
    8778     49577869 :       && (c_cast_p || at_least_as_qualified_p (TREE_TYPE (type), intype)))
    8779              :     {
    8780       892210 :       if (processing_template_decl)
    8781              :         return expr;
    8782       891742 :       if (clk == clk_ordinary)
    8783              :         {
    8784              :           /* Handle the (non-bit-field) lvalue case here by casting to
    8785              :              lvalue reference and then changing it to an rvalue reference.
    8786              :              Casting an xvalue to rvalue reference will be handled by the
    8787              :              main code path.  */
    8788       891739 :           tree lref = cp_build_reference_type (TREE_TYPE (type), false);
    8789       891739 :           result = (perform_direct_initialization_if_possible
    8790       891739 :                     (lref, expr, c_cast_p, complain));
    8791       891739 :           result = build1 (NON_LVALUE_EXPR, type, result);
    8792       891739 :           return convert_from_reference (result);
    8793              :         }
    8794              :       else
    8795              :         /* For a bit-field or packed field, bind to a temporary.  */
    8796            3 :         expr = rvalue (expr);
    8797              :     }
    8798              : 
    8799              :   /* Resolve overloaded address here rather than once in
    8800              :      implicit_conversion and again in the inverse code below.  */
    8801     47793452 :   if (TYPE_PTRMEMFUNC_P (type) && type_unknown_p (expr))
    8802              :     {
    8803           21 :       expr = instantiate_type (type, expr, complain);
    8804           21 :       intype = TREE_TYPE (expr);
    8805              :     }
    8806              : 
    8807              :   /* [expr.static.cast]
    8808              : 
    8809              :      Any expression can be explicitly converted to type cv void.  */
    8810     47793452 :   if (VOID_TYPE_P (type))
    8811              :     {
    8812       610365 :       if (TREE_CODE (expr) == EXCESS_PRECISION_EXPR)
    8813            0 :         expr = TREE_OPERAND (expr, 0);
    8814       610365 :       return convert_to_void (expr, ICV_CAST, complain);
    8815              :     }
    8816              : 
    8817              :   /* [class.abstract]
    8818              :      An abstract class shall not be used ... as the type of an explicit
    8819              :      conversion.  */
    8820     47183087 :   if (abstract_virtuals_error (ACU_CAST, type, complain))
    8821            6 :     return error_mark_node;
    8822              : 
    8823              :   /* [expr.static.cast]
    8824              : 
    8825              :      An expression e can be explicitly converted to a type T using a
    8826              :      static_cast of the form static_cast<T>(e) if the declaration T
    8827              :      t(e);" is well-formed, for some invented temporary variable
    8828              :      t.  */
    8829     47183081 :   result = perform_direct_initialization_if_possible (type, expr,
    8830              :                                                       c_cast_p, complain);
    8831              :   /* P1975 allows static_cast<Aggr>(42), as well as static_cast<T[5]>(42),
    8832              :      which initialize the first element of the aggregate.  We need to handle
    8833              :      the array case specifically.  */
    8834     47183081 :   if (result == NULL_TREE
    8835      4864688 :       && cxx_dialect >= cxx20
    8836      3536529 :       && TREE_CODE (type) == ARRAY_TYPE)
    8837              :     {
    8838              :       /* Create { EXPR } and perform direct-initialization from it.  */
    8839           15 :       tree e = build_constructor_single (init_list_type_node, NULL_TREE, expr);
    8840           15 :       CONSTRUCTOR_IS_DIRECT_INIT (e) = true;
    8841           15 :       CONSTRUCTOR_IS_PAREN_INIT (e) = true;
    8842           15 :       result = perform_direct_initialization_if_possible (type, e, c_cast_p,
    8843              :                                                           complain);
    8844              :     }
    8845      4864688 :   if (result)
    8846              :     {
    8847     42318408 :       if (processing_template_decl)
    8848              :         return expr;
    8849              : 
    8850     41652404 :       result = convert_from_reference (result);
    8851              : 
    8852              :       /* [expr.static.cast]
    8853              : 
    8854              :          If T is a reference type, the result is an lvalue; otherwise,
    8855              :          the result is an rvalue.  */
    8856     41652404 :       if (!TYPE_REF_P (type))
    8857              :         {
    8858     40362462 :           result = rvalue (result);
    8859              : 
    8860     40362462 :           if (result == expr && SCALAR_TYPE_P (type))
    8861              :             /* Leave some record of the cast.  */
    8862      2604257 :             result = build_nop (type, expr);
    8863              :         }
    8864     41652404 :       return result;
    8865              :     }
    8866              : 
    8867              :   /* [expr.static.cast]
    8868              : 
    8869              :      The inverse of any standard conversion sequence (clause _conv_),
    8870              :      other than the lvalue-to-rvalue (_conv.lval_), array-to-pointer
    8871              :      (_conv.array_), function-to-pointer (_conv.func_), and boolean
    8872              :      (_conv.bool_) conversions, can be performed explicitly using
    8873              :      static_cast subject to the restriction that the explicit
    8874              :      conversion does not cast away constness (_expr.const.cast_), and
    8875              :      the following additional rules for specific cases:  */
    8876              :   /* For reference, the conversions not excluded are: integral
    8877              :      promotions, floating-point promotion, integral conversions,
    8878              :      floating-point conversions, floating-integral conversions,
    8879              :      pointer conversions, and pointer to member conversions.  */
    8880              :   /* DR 128
    8881              : 
    8882              :      A value of integral _or enumeration_ type can be explicitly
    8883              :      converted to an enumeration type.  */
    8884              :   /* The effect of all that is that any conversion between any two
    8885              :      types which are integral, floating, or enumeration types can be
    8886              :      performed.  */
    8887      4864673 :   if ((INTEGRAL_OR_ENUMERATION_TYPE_P (type)
    8888      2615110 :        || SCALAR_FLOAT_TYPE_P (type))
    8889      2330038 :       && (INTEGRAL_OR_ENUMERATION_TYPE_P (intype)
    8890       195482 :           || SCALAR_FLOAT_TYPE_P (intype)))
    8891              :     {
    8892      2215019 :       if (processing_template_decl)
    8893              :         return expr;
    8894      2126655 :       if (TREE_CODE (expr) == EXCESS_PRECISION_EXPR)
    8895            0 :         expr = TREE_OPERAND (expr, 0);
    8896              :       /* [expr.static.cast]: "If the value is not a bit-field, the result
    8897              :          refers to the object or the specified base class subobject thereof;
    8898              :          otherwise, the lvalue-to-rvalue conversion is applied to the
    8899              :          bit-field and the resulting prvalue is used as the operand of the
    8900              :          static_cast."  There are no prvalue bit-fields; the l-to-r conversion
    8901              :          will give us an object of the underlying type of the bit-field.  */
    8902      2126655 :       expr = decay_conversion (expr, complain);
    8903      2126655 :       return ocp_convert (type, expr, CONV_C_CAST, LOOKUP_NORMAL, complain);
    8904              :     }
    8905              : 
    8906       901765 :   if (TYPE_PTR_P (type) && TYPE_PTR_P (intype)
    8907       897307 :       && CLASS_TYPE_P (TREE_TYPE (type))
    8908       219246 :       && CLASS_TYPE_P (TREE_TYPE (intype))
    8909      2698489 :       && can_convert (build_pointer_type (TYPE_MAIN_VARIANT
    8910              :                                           (TREE_TYPE (intype))),
    8911        48835 :                       build_pointer_type (TYPE_MAIN_VARIANT
    8912              :                                           (TREE_TYPE (type))),
    8913              :                       complain))
    8914              :     {
    8915        48496 :       tree base;
    8916              : 
    8917        48496 :       if (processing_template_decl)
    8918              :         return expr;
    8919              : 
    8920        48478 :       if (!c_cast_p
    8921        48478 :           && check_for_casting_away_constness (loc, intype, type,
    8922              :                                                STATIC_CAST_EXPR,
    8923              :                                                complain))
    8924            6 :         return error_mark_node;
    8925        96405 :       base = lookup_base (TREE_TYPE (type), TREE_TYPE (intype),
    8926              :                           c_cast_p ? ba_unique : ba_check,
    8927              :                           NULL, complain);
    8928        48472 :       expr = build_base_path (MINUS_EXPR, expr, base, /*nonnull=*/false,
    8929              :                               complain);
    8930              : 
    8931        48472 :       if (sanitize_flags_p (SANITIZE_VPTR))
    8932              :         {
    8933           43 :           tree ubsan_check
    8934           43 :             = cp_ubsan_maybe_instrument_downcast (loc, type,
    8935              :                                                   intype, expr);
    8936           43 :           if (ubsan_check)
    8937        48472 :             expr = ubsan_check;
    8938              :         }
    8939              : 
    8940        48472 :       return cp_fold_convert (type, expr);
    8941              :     }
    8942              : 
    8943           89 :   if ((TYPE_PTRDATAMEM_P (type) && TYPE_PTRDATAMEM_P (intype))
    8944      2601158 :       || (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype)))
    8945              :     {
    8946          232 :       tree c1;
    8947          232 :       tree c2;
    8948          232 :       tree t1;
    8949          232 :       tree t2;
    8950              : 
    8951          232 :       c1 = TYPE_PTRMEM_CLASS_TYPE (intype);
    8952          232 :       c2 = TYPE_PTRMEM_CLASS_TYPE (type);
    8953              : 
    8954          232 :       if (TYPE_PTRDATAMEM_P (type))
    8955              :         {
    8956           89 :           t1 = (build_ptrmem_type
    8957           89 :                 (c1,
    8958           89 :                  TYPE_MAIN_VARIANT (TYPE_PTRMEM_POINTED_TO_TYPE (intype))));
    8959           89 :           t2 = (build_ptrmem_type
    8960           89 :                 (c2,
    8961           89 :                  TYPE_MAIN_VARIANT (TYPE_PTRMEM_POINTED_TO_TYPE (type))));
    8962              :         }
    8963              :       else
    8964              :         {
    8965              :           t1 = intype;
    8966              :           t2 = type;
    8967              :         }
    8968          232 :       if (can_convert (t1, t2, complain) || can_convert (t2, t1, complain))
    8969              :         {
    8970          154 :           if (!c_cast_p
    8971          154 :               && check_for_casting_away_constness (loc, intype, type,
    8972              :                                                    STATIC_CAST_EXPR,
    8973              :                                                    complain))
    8974            9 :             return error_mark_node;
    8975          145 :           if (processing_template_decl)
    8976              :             return expr;
    8977          145 :           return convert_ptrmem (type, expr, /*allow_inverse_p=*/1,
    8978          145 :                                  c_cast_p, complain);
    8979              :         }
    8980              :     }
    8981              : 
    8982              :   /* [expr.static.cast]
    8983              : 
    8984              :      An rvalue of type "pointer to cv void" can be explicitly
    8985              :      converted to a pointer to object type.  A value of type pointer
    8986              :      to object converted to "pointer to cv void" and back to the
    8987              :      original pointer type will have its original value.  */
    8988      2601004 :   if (TYPE_PTR_P (intype)
    8989       961667 :       && VOID_TYPE_P (TREE_TYPE (intype))
    8990      3414565 :       && TYPE_PTROB_P (type))
    8991              :     {
    8992       781317 :       if (!c_cast_p
    8993       781317 :           && check_for_casting_away_constness (loc, intype, type,
    8994              :                                                STATIC_CAST_EXPR,
    8995              :                                                complain))
    8996           21 :         return error_mark_node;
    8997       781296 :       if (processing_template_decl)
    8998              :         return expr;
    8999       699291 :       return build_nop (type, expr);
    9000              :     }
    9001              : 
    9002      1819687 :   *valid_p = false;
    9003      1819687 :   return error_mark_node;
    9004              : }
    9005              : 
    9006              : /* Return an expression representing static_cast<TYPE>(EXPR).  */
    9007              : 
    9008              : tree
    9009     18873054 : build_static_cast (location_t loc, tree type, tree oexpr,
    9010              :                    tsubst_flags_t complain)
    9011              : {
    9012     18873054 :   tree expr = oexpr;
    9013     18873054 :   tree result;
    9014     18873054 :   bool valid_p;
    9015              : 
    9016     18873054 :   if (type == error_mark_node || expr == error_mark_node)
    9017              :     return error_mark_node;
    9018              : 
    9019     18873000 :   bool dependent = (dependent_type_p (type)
    9020     18873000 :                     || type_dependent_expression_p (expr));
    9021     13892090 :   if (dependent)
    9022              :     {
    9023      6037637 :     tmpl:
    9024      6037637 :       expr = build_min (STATIC_CAST_EXPR, type, oexpr);
    9025              :       /* We don't know if it will or will not have side effects.  */
    9026      6037637 :       TREE_SIDE_EFFECTS (expr) = 1;
    9027      6037637 :       result = convert_from_reference (expr);
    9028      6037637 :       protected_set_expr_location (result, loc);
    9029      6037637 :       return result;
    9030              :     }
    9031              : 
    9032              :   /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
    9033              :      Strip such NOP_EXPRs if VALUE is being used in non-lvalue context.  */
    9034     13892090 :   if (!TYPE_REF_P (type)
    9035      7062736 :       && TREE_CODE (expr) == NOP_EXPR
    9036     13997968 :       && TREE_TYPE (expr) == TREE_TYPE (TREE_OPERAND (expr, 0)))
    9037           48 :     expr = TREE_OPERAND (expr, 0);
    9038              : 
    9039     13892090 :   result = build_static_cast_1 (loc, type, expr, /*c_cast_p=*/false,
    9040              :                                 &valid_p, complain);
    9041     13892090 :   if (valid_p)
    9042              :     {
    9043     13891895 :       if (result != error_mark_node)
    9044              :         {
    9045     13891790 :           maybe_warn_about_useless_cast (loc, type, expr, complain);
    9046     13891790 :           maybe_warn_about_cast_ignoring_quals (loc, type, complain);
    9047              :         }
    9048     13891895 :       if (processing_template_decl)
    9049      1056727 :         goto tmpl;
    9050     12835168 :       protected_set_expr_location (result, loc);
    9051     12835168 :       return result;
    9052              :     }
    9053              : 
    9054          195 :   if (complain & tf_error)
    9055              :     {
    9056          162 :       auto_diagnostic_group d;
    9057          162 :       error_at (loc, "invalid %<static_cast%> from type %qT to type %qT",
    9058          162 :                 TREE_TYPE (expr), type);
    9059          162 :       if ((TYPE_PTR_P (type) || TYPE_REF_P (type))
    9060          120 :           && CLASS_TYPE_P (TREE_TYPE (type))
    9061          191 :             && !COMPLETE_TYPE_P (TREE_TYPE (type)))
    9062           17 :         inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (TREE_TYPE (type))),
    9063           17 :                 "class type %qT is incomplete", TREE_TYPE (type));
    9064          162 :       tree expr_type = TREE_TYPE (expr);
    9065          162 :       if (TYPE_PTR_P (expr_type))
    9066           35 :         expr_type = TREE_TYPE (expr_type);
    9067          162 :       if (CLASS_TYPE_P (expr_type) && !COMPLETE_TYPE_P (expr_type))
    9068           12 :         inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (expr_type)),
    9069              :                 "class type %qT is incomplete", expr_type);
    9070          162 :     }
    9071          195 :   return error_mark_node;
    9072              : }
    9073              : 
    9074              : /* EXPR is an expression with member function or pointer-to-member
    9075              :    function type.  TYPE is a pointer type.  Converting EXPR to TYPE is
    9076              :    not permitted by ISO C++, but we accept it in some modes.  If we
    9077              :    are not in one of those modes, issue a diagnostic.  Return the
    9078              :    converted expression.  */
    9079              : 
    9080              : tree
    9081          163 : convert_member_func_to_ptr (tree type, tree expr, tsubst_flags_t complain)
    9082              : {
    9083          163 :   tree intype;
    9084          163 :   tree decl;
    9085              : 
    9086          163 :   intype = TREE_TYPE (expr);
    9087          163 :   gcc_assert (TYPE_PTRMEMFUNC_P (intype)
    9088              :               || TREE_CODE (intype) == METHOD_TYPE);
    9089              : 
    9090          163 :   if (!(complain & tf_warning_or_error))
    9091            0 :     return error_mark_node;
    9092              : 
    9093          163 :   location_t loc = cp_expr_loc_or_input_loc (expr);
    9094              : 
    9095          163 :   if (pedantic || warn_pmf2ptr)
    9096          203 :     pedwarn (loc, pedantic ? OPT_Wpedantic : OPT_Wpmf_conversions,
    9097              :              "converting from %qH to %qI", intype, type);
    9098              : 
    9099          163 :   STRIP_ANY_LOCATION_WRAPPER (expr);
    9100              : 
    9101          163 :   if (TREE_CODE (intype) == METHOD_TYPE)
    9102           71 :     expr = build_addr_func (expr, complain);
    9103           92 :   else if (TREE_CODE (expr) == PTRMEM_CST)
    9104           74 :     expr = build_address (PTRMEM_CST_MEMBER (expr));
    9105              :   else
    9106              :     {
    9107           18 :       decl = maybe_dummy_object (TYPE_PTRMEM_CLASS_TYPE (intype), 0);
    9108           18 :       decl = build_address (decl);
    9109           18 :       expr = get_member_function_from_ptrfunc (&decl, expr, complain);
    9110              :     }
    9111              : 
    9112          163 :   if (expr == error_mark_node)
    9113              :     return error_mark_node;
    9114              : 
    9115          163 :   expr = build_nop (type, expr);
    9116          163 :   SET_EXPR_LOCATION (expr, loc);
    9117          163 :   return expr;
    9118              : }
    9119              : 
    9120              : /* Build a NOP_EXPR to TYPE, but mark it as a reinterpret_cast so that
    9121              :    constexpr evaluation knows to reject it.  */
    9122              : 
    9123              : static tree
    9124       129752 : build_nop_reinterpret (tree type, tree expr)
    9125              : {
    9126       129752 :   tree ret = build_nop (type, expr);
    9127       129752 :   if (ret != expr)
    9128       129752 :     REINTERPRET_CAST_P (ret) = true;
    9129       129752 :   return ret;
    9130              : }
    9131              : 
    9132              : /* Return a representation for a reinterpret_cast from EXPR to TYPE.
    9133              :    If C_CAST_P is true, this reinterpret cast is being done as part of
    9134              :    a C-style cast.  If VALID_P is non-NULL, *VALID_P is set to
    9135              :    indicate whether or not reinterpret_cast was valid.  */
    9136              : 
    9137              : static tree
    9138      2001452 : build_reinterpret_cast_1 (location_t loc, tree type, tree expr,
    9139              :                           bool c_cast_p, bool *valid_p,
    9140              :                           tsubst_flags_t complain)
    9141              : {
    9142      2001452 :   tree intype;
    9143              : 
    9144              :   /* Assume the cast is invalid.  */
    9145      2001452 :   if (valid_p)
    9146      1819548 :     *valid_p = true;
    9147              : 
    9148      2001452 :   if (type == error_mark_node || error_operand_p (expr))
    9149              :     return error_mark_node;
    9150              : 
    9151      2001452 :   intype = TREE_TYPE (expr);
    9152              : 
    9153              :   /* Save casted types in the function's used types hash table.  */
    9154      2001452 :   used_types_insert (type);
    9155              : 
    9156              :   /* A prvalue of non-class type is cv-unqualified.  */
    9157      2001452 :   if (!CLASS_TYPE_P (type))
    9158      2001443 :     type = cv_unqualified (type);
    9159              : 
    9160              :   /* [expr.reinterpret.cast]
    9161              :      A glvalue of type T1, designating an object x, can be cast to the type
    9162              :      "reference to T2" if an expression of type "pointer to T1" can be
    9163              :      explicitly converted to the type "pointer to T2" using a reinterpret_cast.
    9164              :      The result is that of *reinterpret_cast<T2 *>(p) where p is a pointer to x
    9165              :      of type "pointer to T1". No temporary is created, no copy is made, and no
    9166              :      constructors (11.4.4) or conversion functions (11.4.7) are called.  */
    9167      2001452 :   if (TYPE_REF_P (type))
    9168              :     {
    9169         9430 :       if (!glvalue_p (expr))
    9170              :         {
    9171            9 :           if (complain & tf_error)
    9172            9 :             error_at (loc, "invalid cast of a prvalue expression of type "
    9173              :                       "%qT to type %qT",
    9174              :                       intype, type);
    9175            9 :           return error_mark_node;
    9176              :         }
    9177              : 
    9178              :       /* Warn about a reinterpret_cast from "A*" to "B&" if "A" and
    9179              :          "B" are related class types; the reinterpret_cast does not
    9180              :          adjust the pointer.  */
    9181         9421 :       if (TYPE_PTR_P (intype)
    9182            3 :           && (complain & tf_warning)
    9183         9424 :           && (comptypes (TREE_TYPE (intype), TREE_TYPE (type),
    9184              :                          COMPARE_BASE | COMPARE_DERIVED)))
    9185            3 :         warning_at (loc, 0, "casting %qT to %qT does not dereference pointer",
    9186              :                     intype, type);
    9187              : 
    9188         9421 :       expr = cp_build_addr_expr (expr, complain);
    9189              : 
    9190         9421 :       if (warn_strict_aliasing > 2)
    9191           70 :         cp_strict_aliasing_warning (EXPR_LOCATION (expr), type, expr);
    9192              : 
    9193         9421 :       if (expr != error_mark_node)
    9194         9421 :         expr = build_reinterpret_cast_1
    9195         9421 :           (loc, build_pointer_type (TREE_TYPE (type)), expr, c_cast_p,
    9196              :            valid_p, complain);
    9197         9421 :       if (expr != error_mark_node)
    9198              :         /* cp_build_indirect_ref isn't right for rvalue refs.  */
    9199         9418 :         expr = convert_from_reference (fold_convert (type, expr));
    9200         9421 :       return expr;
    9201              :     }
    9202              : 
    9203              :   /* As a G++ extension, we consider conversions from member
    9204              :      functions, and pointers to member functions to
    9205              :      pointer-to-function and pointer-to-void types.  If
    9206              :      -Wno-pmf-conversions has not been specified,
    9207              :      convert_member_func_to_ptr will issue an error message.  */
    9208          249 :   if ((TYPE_PTRMEMFUNC_P (intype)
    9209      1991851 :        || TREE_CODE (intype) == METHOD_TYPE)
    9210          242 :       && TYPE_PTR_P (type)
    9211      1992185 :       && (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE
    9212          121 :           || VOID_TYPE_P (TREE_TYPE (type))))
    9213          154 :     return convert_member_func_to_ptr (type, expr, complain);
    9214              : 
    9215              :   /* If the cast is not to a reference type, the lvalue-to-rvalue,
    9216              :      array-to-pointer, and function-to-pointer conversions are
    9217              :      performed.  */
    9218      1991868 :   expr = decay_conversion (expr, complain);
    9219              : 
    9220              :   /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
    9221              :      Strip such NOP_EXPRs if VALUE is being used in non-lvalue context.  */
    9222      1991868 :   if (TREE_CODE (expr) == NOP_EXPR
    9223      1991868 :       && TREE_TYPE (expr) == TREE_TYPE (TREE_OPERAND (expr, 0)))
    9224          388 :     expr = TREE_OPERAND (expr, 0);
    9225              : 
    9226      1991868 :   if (error_operand_p (expr))
    9227           30 :     return error_mark_node;
    9228              : 
    9229      1991838 :   intype = TREE_TYPE (expr);
    9230              : 
    9231              :   /* [expr.reinterpret.cast]
    9232              :      A pointer can be converted to any integral type large enough to
    9233              :      hold it. ... A value of type std::nullptr_t can be converted to
    9234              :      an integral type; the conversion has the same meaning and
    9235              :      validity as a conversion of (void*)0 to the integral type.  */
    9236      1991838 :   if (CP_INTEGRAL_TYPE_P (type)
    9237       195099 :       && (TYPE_PTR_P (intype) || NULLPTR_TYPE_P (intype)))
    9238              :     {
    9239       193186 :       if (TYPE_PRECISION (type) < TYPE_PRECISION (intype))
    9240              :         {
    9241           21 :           if (complain & tf_error)
    9242           15 :             permerror (loc, "cast from %qH to %qI loses precision",
    9243              :                        intype, type);
    9244              :           else
    9245            6 :             return error_mark_node;
    9246              :         }
    9247       193180 :       if (NULLPTR_TYPE_P (intype))
    9248           98 :         return build_int_cst (type, 0);
    9249              :     }
    9250              :   /* [expr.reinterpret.cast]
    9251              :      A value of integral or enumeration type can be explicitly
    9252              :      converted to a pointer.  */
    9253      1798652 :   else if (TYPE_PTR_P (type) && INTEGRAL_OR_ENUMERATION_TYPE_P (intype))
    9254              :     /* OK */
    9255              :     ;
    9256      1765182 :   else if ((INTEGRAL_OR_ENUMERATION_TYPE_P (type)
    9257      1763254 :             || TYPE_PTR_OR_PTRMEM_P (type))
    9258      1895473 :            && same_type_p (type, intype))
    9259              :     /* DR 799 */
    9260          507 :     return rvalue (expr);
    9261      1764675 :   else if (TYPE_PTRFN_P (type) && TYPE_PTRFN_P (intype))
    9262              :     {
    9263        19537 :       if ((complain & tf_warning)
    9264        39074 :           && !cxx_safe_function_type_cast_p (TREE_TYPE (type),
    9265        19537 :                                              TREE_TYPE (intype)))
    9266          145 :         warning_at (loc, OPT_Wcast_function_type,
    9267              :                     "cast between incompatible function types"
    9268              :                     " from %qH to %qI", intype, type);
    9269        19537 :       return build_nop_reinterpret (type, expr);
    9270              :     }
    9271      1745138 :   else if (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype))
    9272              :     {
    9273           79 :       if ((complain & tf_warning)
    9274          158 :           && !cxx_safe_function_type_cast_p
    9275           79 :                 (TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE_RAW (type)),
    9276           79 :                  TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE_RAW (intype))))
    9277           52 :         warning_at (loc, OPT_Wcast_function_type,
    9278              :                     "cast between incompatible pointer to member types"
    9279              :                     " from %qH to %qI", intype, type);
    9280           79 :       return build_nop_reinterpret (type, expr);
    9281              :     }
    9282           21 :   else if ((TYPE_PTRDATAMEM_P (type) && TYPE_PTRDATAMEM_P (intype))
    9283      1745059 :            || (TYPE_PTROBV_P (type) && TYPE_PTROBV_P (intype)))
    9284              :     {
    9285       109881 :       if (!c_cast_p
    9286       109881 :           && check_for_casting_away_constness (loc, intype, type,
    9287              :                                                REINTERPRET_CAST_EXPR,
    9288              :                                                complain))
    9289           21 :         return error_mark_node;
    9290              :       /* Warn about possible alignment problems.  */
    9291       109860 :       if ((STRICT_ALIGNMENT || warn_cast_align == 2)
    9292           24 :           && (complain & tf_warning)
    9293           24 :           && !VOID_TYPE_P (type)
    9294           24 :           && TREE_CODE (TREE_TYPE (intype)) != FUNCTION_TYPE
    9295           24 :           && COMPLETE_TYPE_P (TREE_TYPE (type))
    9296           24 :           && COMPLETE_TYPE_P (TREE_TYPE (intype))
    9297       109908 :           && min_align_of_type (TREE_TYPE (type))
    9298           24 :              > min_align_of_type (TREE_TYPE (intype)))
    9299           18 :         warning_at (loc, OPT_Wcast_align, "cast from %qH to %qI "
    9300              :                     "increases required alignment of target type",
    9301              :                     intype, type);
    9302              : 
    9303       109860 :       if (warn_strict_aliasing <= 2)
    9304              :         /* strict_aliasing_warning STRIP_NOPs its expr.  */
    9305        98111 :         cp_strict_aliasing_warning (EXPR_LOCATION (expr), type, expr);
    9306              : 
    9307       109860 :       return build_nop_reinterpret (type, expr);
    9308              :     }
    9309          297 :   else if ((TYPE_PTRFN_P (type) && TYPE_PTROBV_P (intype))
    9310      1635338 :            || (TYPE_PTRFN_P (intype) && TYPE_PTROBV_P (type)))
    9311              :     {
    9312          276 :       if (complain & tf_warning)
    9313              :         /* C++11 5.2.10 p8 says that "Converting a function pointer to an
    9314              :            object pointer type or vice versa is conditionally-supported."  */
    9315          276 :         warning_at (loc, OPT_Wconditionally_supported,
    9316              :                     "casting between pointer-to-function and "
    9317              :                     "pointer-to-object is conditionally-supported");
    9318          276 :       return build_nop_reinterpret (type, expr);
    9319              :     }
    9320      1634902 :   else if (gnu_vector_type_p (type) && scalarish_type_p (intype))
    9321      1632939 :     return convert_to_vector (type, rvalue (expr));
    9322         1963 :   else if (gnu_vector_type_p (intype)
    9323         1963 :            && INTEGRAL_OR_ENUMERATION_TYPE_P (type))
    9324         1861 :     return convert_to_integer_nofold (type, expr);
    9325              :   else
    9326              :     {
    9327          102 :       if (valid_p)
    9328           84 :         *valid_p = false;
    9329          102 :       if (complain & tf_error)
    9330           93 :         error_at (loc, "invalid cast from type %qT to type %qT",
    9331              :                   intype, type);
    9332          102 :       return error_mark_node;
    9333              :     }
    9334              : 
    9335       226552 :   expr = cp_convert (type, expr, complain);
    9336       226552 :   if (TREE_CODE (expr) == NOP_EXPR)
    9337              :     /* Mark any nop_expr that created as a reintepret_cast.  */
    9338            0 :     REINTERPRET_CAST_P (expr) = true;
    9339              :   return expr;
    9340              : }
    9341              : 
    9342              : tree
    9343       769675 : build_reinterpret_cast (location_t loc, tree type, tree expr,
    9344              :                         tsubst_flags_t complain)
    9345              : {
    9346       769675 :   tree r;
    9347              : 
    9348       769675 :   if (type == error_mark_node || expr == error_mark_node)
    9349              :     return error_mark_node;
    9350              : 
    9351       769668 :   if (processing_template_decl)
    9352              :     {
    9353       597129 :       tree t = build_min (REINTERPRET_CAST_EXPR, type, expr);
    9354              : 
    9355       597129 :       if (!TREE_SIDE_EFFECTS (t)
    9356       597129 :           && type_dependent_expression_p (expr))
    9357              :         /* There might turn out to be side effects inside expr.  */
    9358       296980 :         TREE_SIDE_EFFECTS (t) = 1;
    9359       597129 :       r = convert_from_reference (t);
    9360       597129 :       protected_set_expr_location (r, loc);
    9361       597129 :       return r;
    9362              :     }
    9363              : 
    9364       172539 :   r = build_reinterpret_cast_1 (loc, type, expr, /*c_cast_p=*/false,
    9365              :                                 /*valid_p=*/NULL, complain);
    9366       172539 :   if (r != error_mark_node)
    9367              :     {
    9368       172476 :       maybe_warn_about_useless_cast (loc, type, expr, complain);
    9369       172476 :       maybe_warn_about_cast_ignoring_quals (loc, type, complain);
    9370              :     }
    9371       172539 :   protected_set_expr_location (r, loc);
    9372       172539 :   return r;
    9373              : }
    9374              : 
    9375              : /* Perform a const_cast from EXPR to TYPE.  If the cast is valid,
    9376              :    return an appropriate expression.  Otherwise, return
    9377              :    error_mark_node.  If the cast is not valid, and COMPLAIN is true,
    9378              :    then a diagnostic will be issued.  If VALID_P is non-NULL, we are
    9379              :    performing a C-style cast, its value upon return will indicate
    9380              :    whether or not the conversion succeeded.  */
    9381              : 
    9382              : static tree
    9383     39981045 : build_const_cast_1 (location_t loc, tree dst_type, tree expr,
    9384              :                     tsubst_flags_t complain, bool *valid_p)
    9385              : {
    9386     39981045 :   tree src_type;
    9387     39981045 :   tree reference_type;
    9388              : 
    9389              :   /* Callers are responsible for handling error_mark_node as a
    9390              :      destination type.  */
    9391     39981045 :   gcc_assert (dst_type != error_mark_node);
    9392              :   /* In a template, callers should be building syntactic
    9393              :      representations of casts, not using this machinery.  */
    9394     39981045 :   gcc_assert (!processing_template_decl);
    9395              : 
    9396              :   /* Assume the conversion is invalid.  */
    9397     39981045 :   if (valid_p)
    9398     39747336 :     *valid_p = false;
    9399              : 
    9400     39981045 :   if (!INDIRECT_TYPE_P (dst_type) && !TYPE_PTRDATAMEM_P (dst_type))
    9401              :     {
    9402     38758909 :       if (complain & tf_error)
    9403            9 :         error_at (loc, "invalid use of %<const_cast%> with type %qT, "
    9404              :                   "which is not a pointer, reference, "
    9405              :                   "nor a pointer-to-data-member type", dst_type);
    9406     38758909 :       return error_mark_node;
    9407              :     }
    9408              : 
    9409      1222136 :   if (TREE_CODE (TREE_TYPE (dst_type)) == FUNCTION_TYPE)
    9410              :     {
    9411         4129 :       if (complain & tf_error)
    9412            6 :         error_at (loc, "invalid use of %<const_cast%> with type %qT, "
    9413              :                   "which is a pointer or reference to a function type",
    9414              :                   dst_type);
    9415         4129 :        return error_mark_node;
    9416              :     }
    9417              : 
    9418              :   /* A prvalue of non-class type is cv-unqualified.  */
    9419      1218007 :   dst_type = cv_unqualified (dst_type);
    9420              : 
    9421              :   /* Save casted types in the function's used types hash table.  */
    9422      1218007 :   used_types_insert (dst_type);
    9423              : 
    9424      1218007 :   src_type = TREE_TYPE (expr);
    9425              :   /* Expressions do not really have reference types.  */
    9426      1218007 :   if (TYPE_REF_P (src_type))
    9427            0 :     src_type = TREE_TYPE (src_type);
    9428              : 
    9429              :   /* [expr.const.cast]
    9430              : 
    9431              :      For two object types T1 and T2, if a pointer to T1 can be explicitly
    9432              :      converted to the type "pointer to T2" using a const_cast, then the
    9433              :      following conversions can also be made:
    9434              : 
    9435              :      -- an lvalue of type T1 can be explicitly converted to an lvalue of
    9436              :      type T2 using the cast const_cast<T2&>;
    9437              : 
    9438              :      -- a glvalue of type T1 can be explicitly converted to an xvalue of
    9439              :      type T2 using the cast const_cast<T2&&>; and
    9440              : 
    9441              :      -- if T1 is a class type, a prvalue of type T1 can be explicitly
    9442              :      converted to an xvalue of type T2 using the cast const_cast<T2&&>.  */
    9443              : 
    9444      1218007 :   if (TYPE_REF_P (dst_type))
    9445              :     {
    9446       163380 :       reference_type = dst_type;
    9447       163380 :       if (!TYPE_REF_IS_RVALUE (dst_type)
    9448       163380 :           ? lvalue_p (expr)
    9449         1047 :           : obvalue_p (expr))
    9450              :         /* OK.  */;
    9451              :       else
    9452              :         {
    9453           35 :           if (complain & tf_error)
    9454            9 :             error_at (loc, "invalid %<const_cast%> of an rvalue of type %qT "
    9455              :                       "to type %qT",
    9456              :                       src_type, dst_type);
    9457           35 :           return error_mark_node;
    9458              :         }
    9459       163345 :       dst_type = build_pointer_type (TREE_TYPE (dst_type));
    9460       163345 :       src_type = build_pointer_type (src_type);
    9461              :     }
    9462              :   else
    9463              :     {
    9464      1054627 :       reference_type = NULL_TREE;
    9465              :       /* If the destination type is not a reference type, the
    9466              :          lvalue-to-rvalue, array-to-pointer, and function-to-pointer
    9467              :          conversions are performed.  */
    9468      1054627 :       src_type = type_decays_to (src_type);
    9469      1054627 :       if (src_type == error_mark_node)
    9470              :         return error_mark_node;
    9471              :     }
    9472              : 
    9473      1217972 :   if (TYPE_PTR_P (src_type) || TYPE_PTRDATAMEM_P (src_type))
    9474              :     {
    9475       810146 :       if (comp_ptr_ttypes_const (dst_type, src_type, bounds_none))
    9476              :         {
    9477       539196 :           if (valid_p)
    9478              :             {
    9479       305565 :               *valid_p = true;
    9480              :               /* This cast is actually a C-style cast.  Issue a warning if
    9481              :                  the user is making a potentially unsafe cast.  */
    9482       305565 :               check_for_casting_away_constness (loc, src_type, dst_type,
    9483              :                                                 CAST_EXPR, complain);
    9484              :               /* ??? comp_ptr_ttypes_const ignores TYPE_ALIGN.  */
    9485       305565 :               if ((STRICT_ALIGNMENT || warn_cast_align == 2)
    9486            3 :                   && (complain & tf_warning)
    9487       305571 :                   && min_align_of_type (TREE_TYPE (dst_type))
    9488            3 :                      > min_align_of_type (TREE_TYPE (src_type)))
    9489            3 :                 warning_at (loc, OPT_Wcast_align, "cast from %qH to %qI "
    9490              :                             "increases required alignment of target type",
    9491              :                             src_type, dst_type);
    9492              :             }
    9493       539196 :           if (reference_type)
    9494              :             {
    9495       162279 :               expr = cp_build_addr_expr (expr, complain);
    9496       162279 :               if (expr == error_mark_node)
    9497              :                 return error_mark_node;
    9498       162261 :               expr = build_nop (reference_type, expr);
    9499       162261 :               return convert_from_reference (expr);
    9500              :             }
    9501              :           else
    9502              :             {
    9503       376917 :               expr = decay_conversion (expr, complain);
    9504       376917 :               if (expr == error_mark_node)
    9505              :                 return error_mark_node;
    9506              : 
    9507              :               /* build_c_cast puts on a NOP_EXPR to make the result not an
    9508              :                  lvalue.  Strip such NOP_EXPRs if VALUE is being used in
    9509              :                  non-lvalue context.  */
    9510       376917 :               if (TREE_CODE (expr) == NOP_EXPR
    9511       376917 :                   && TREE_TYPE (expr) == TREE_TYPE (TREE_OPERAND (expr, 0)))
    9512            3 :                 expr = TREE_OPERAND (expr, 0);
    9513       376917 :               return build_nop (dst_type, expr);
    9514              :             }
    9515              :         }
    9516       270950 :       else if (valid_p
    9517       541852 :                && !at_least_as_qualified_p (TREE_TYPE (dst_type),
    9518       270902 :                                             TREE_TYPE (src_type)))
    9519        15042 :         check_for_casting_away_constness (loc, src_type, dst_type,
    9520              :                                           CAST_EXPR, complain);
    9521              :     }
    9522              : 
    9523       678776 :   if (complain & tf_error)
    9524           30 :     error_at (loc, "invalid %<const_cast%> from type %qT to type %qT",
    9525              :               src_type, dst_type);
    9526       678776 :   return error_mark_node;
    9527              : }
    9528              : 
    9529              : tree
    9530       701533 : build_const_cast (location_t loc, tree type, tree expr,
    9531              :                   tsubst_flags_t complain)
    9532              : {
    9533       701533 :   tree r;
    9534              : 
    9535       701533 :   if (type == error_mark_node || error_operand_p (expr))
    9536              :     return error_mark_node;
    9537              : 
    9538       701525 :   if (processing_template_decl)
    9539              :     {
    9540       467816 :       tree t = build_min (CONST_CAST_EXPR, type, expr);
    9541              : 
    9542       467816 :       if (!TREE_SIDE_EFFECTS (t)
    9543       467816 :           && type_dependent_expression_p (expr))
    9544              :         /* There might turn out to be side effects inside expr.  */
    9545       362316 :         TREE_SIDE_EFFECTS (t) = 1;
    9546       467816 :       r = convert_from_reference (t);
    9547       467816 :       protected_set_expr_location (r, loc);
    9548       467816 :       return r;
    9549              :     }
    9550              : 
    9551       233709 :   r = build_const_cast_1 (loc, type, expr, complain, /*valid_p=*/NULL);
    9552       233709 :   if (r != error_mark_node)
    9553              :     {
    9554       233631 :       maybe_warn_about_useless_cast (loc, type, expr, complain);
    9555       233631 :       maybe_warn_about_cast_ignoring_quals (loc, type, complain);
    9556              :     }
    9557       233709 :   protected_set_expr_location (r, loc);
    9558       233709 :   return r;
    9559              : }
    9560              : 
    9561              : /* Like cp_build_c_cast, but for the c-common bits.  */
    9562              : 
    9563              : tree
    9564            0 : build_c_cast (location_t loc, tree type, tree expr)
    9565              : {
    9566            0 :   return cp_build_c_cast (loc, type, expr, tf_warning_or_error);
    9567              : }
    9568              : 
    9569              : /* Like the "build_c_cast" used for c-common, but using cp_expr to
    9570              :    preserve location information even for tree nodes that don't
    9571              :    support it.  */
    9572              : 
    9573              : cp_expr
    9574     10298333 : build_c_cast (location_t loc, tree type, cp_expr expr)
    9575              : {
    9576     10298333 :   cp_expr result = cp_build_c_cast (loc, type, expr, tf_warning_or_error);
    9577     10298333 :   result.set_location (loc);
    9578     10298333 :   return result;
    9579              : }
    9580              : 
    9581              : /* Build an expression representing an explicit C-style cast to type
    9582              :    TYPE of expression EXPR.  */
    9583              : 
    9584              : tree
    9585     42436692 : cp_build_c_cast (location_t loc, tree type, tree expr,
    9586              :                  tsubst_flags_t complain)
    9587              : {
    9588     42436692 :   tree value = expr;
    9589     42436692 :   tree result;
    9590     42436692 :   bool valid_p;
    9591              : 
    9592     42436692 :   if (type == error_mark_node || error_operand_p (expr))
    9593              :     return error_mark_node;
    9594              : 
    9595     42436525 :   if (processing_template_decl)
    9596              :     {
    9597      2689180 :       tree t = build_min (CAST_EXPR, type,
    9598              :                           tree_cons (NULL_TREE, value, NULL_TREE));
    9599              :       /* We don't know if it will or will not have side effects.  */
    9600      2689180 :       TREE_SIDE_EFFECTS (t) = 1;
    9601      2689180 :       return convert_from_reference (t);
    9602              :     }
    9603              : 
    9604              :   /* Casts to a (pointer to a) specific ObjC class (or 'id' or
    9605              :      'Class') should always be retained, because this information aids
    9606              :      in method lookup.  */
    9607     39747345 :   if (objc_is_object_ptr (type)
    9608     39747345 :       && objc_is_object_ptr (TREE_TYPE (expr)))
    9609            0 :     return build_nop (type, expr);
    9610              : 
    9611              :   /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
    9612              :      Strip such NOP_EXPRs if VALUE is being used in non-lvalue context.  */
    9613     39747345 :   if (!TYPE_REF_P (type)
    9614     39745193 :       && TREE_CODE (value) == NOP_EXPR
    9615     40256776 :       && TREE_TYPE (value) == TREE_TYPE (TREE_OPERAND (value, 0)))
    9616       286943 :     value = TREE_OPERAND (value, 0);
    9617              : 
    9618     39747345 :   if (TREE_CODE (type) == ARRAY_TYPE)
    9619              :     {
    9620              :       /* Allow casting from T1* to T2[] because Cfront allows it.
    9621              :          NIHCL uses it. It is not valid ISO C++ however.  */
    9622            3 :       if (TYPE_PTR_P (TREE_TYPE (expr)))
    9623              :         {
    9624            0 :           if (complain & tf_error)
    9625            0 :             permerror (loc, "ISO C++ forbids casting to an array type %qT",
    9626              :                        type);
    9627              :           else
    9628            0 :             return error_mark_node;
    9629            0 :           type = build_pointer_type (TREE_TYPE (type));
    9630              :         }
    9631              :       else
    9632              :         {
    9633            3 :           if (complain & tf_error)
    9634            3 :             error_at (loc, "ISO C++ forbids casting to an array type %qT",
    9635              :                       type);
    9636            3 :           return error_mark_node;
    9637              :         }
    9638              :     }
    9639              : 
    9640     39747342 :   if (FUNC_OR_METHOD_TYPE_P (type))
    9641              :     {
    9642           15 :       if (complain & tf_error)
    9643           15 :         error_at (loc, "invalid cast to function type %qT", type);
    9644           15 :       return error_mark_node;
    9645              :     }
    9646              : 
    9647     39747327 :   if (TYPE_PTR_P (type)
    9648       986138 :       && TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE
    9649              :       /* Casting to an integer of smaller size is an error detected elsewhere.  */
    9650       406443 :       && TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (value))
    9651              :       /* Don't warn about converting any constant.  */
    9652     40099394 :       && !TREE_CONSTANT (value))
    9653           47 :     warning_at (loc, OPT_Wint_to_pointer_cast,
    9654              :                 "cast to pointer from integer of different size");
    9655              : 
    9656              :   /* A C-style cast can be a const_cast.  */
    9657     39747327 :   result = build_const_cast_1 (loc, type, value, complain & tf_warning,
    9658              :                                &valid_p);
    9659     39747327 :   if (valid_p)
    9660              :     {
    9661       305556 :       if (result != error_mark_node)
    9662              :         {
    9663       305547 :           maybe_warn_about_useless_cast (loc, type, value, complain);
    9664       305547 :           maybe_warn_about_cast_ignoring_quals (loc, type, complain);
    9665              :         }
    9666            9 :       else if (complain & tf_error)
    9667            9 :         build_const_cast_1 (loc, type, value, tf_error, &valid_p);
    9668       305556 :       return result;
    9669              :     }
    9670              : 
    9671              :   /* Or a static cast.  */
    9672     39441771 :   result = build_static_cast_1 (loc, type, value, /*c_cast_p=*/true,
    9673              :                                 &valid_p, complain);
    9674              :   /* Or a reinterpret_cast.  */
    9675     39441771 :   if (!valid_p)
    9676      1819492 :     result = build_reinterpret_cast_1 (loc, type, value, /*c_cast_p=*/true,
    9677              :                                        &valid_p, complain);
    9678              :   /* The static_cast or reinterpret_cast may be followed by a
    9679              :      const_cast.  */
    9680     39441771 :   if (valid_p
    9681              :       /* A valid cast may result in errors if, for example, a
    9682              :          conversion to an ambiguous base class is required.  */
    9683     39441771 :       && !error_operand_p (result))
    9684              :     {
    9685     39441369 :       tree result_type;
    9686              : 
    9687     39441369 :       maybe_warn_about_useless_cast (loc, type, value, complain);
    9688     39441369 :       maybe_warn_about_cast_ignoring_quals (loc, type, complain);
    9689              : 
    9690              :       /* Non-class rvalues always have cv-unqualified type.  */
    9691     39441369 :       if (!CLASS_TYPE_P (type))
    9692     36509881 :         type = TYPE_MAIN_VARIANT (type);
    9693     39441369 :       result_type = TREE_TYPE (result);
    9694     39441369 :       if (!CLASS_TYPE_P (result_type) && !TYPE_REF_P (type))
    9695     36508793 :         result_type = TYPE_MAIN_VARIANT (result_type);
    9696              :       /* If the type of RESULT does not match TYPE, perform a
    9697              :          const_cast to make it match.  If the static_cast or
    9698              :          reinterpret_cast succeeded, we will differ by at most
    9699              :          cv-qualification, so the follow-on const_cast is guaranteed
    9700              :          to succeed.  */
    9701     39441369 :       if (!same_type_p (non_reference (type), non_reference (result_type)))
    9702              :         {
    9703            0 :           result = build_const_cast_1 (loc, type, result, tf_none, &valid_p);
    9704            0 :           gcc_assert (valid_p);
    9705              :         }
    9706     39441369 :       return result;
    9707              :     }
    9708              : 
    9709          402 :   return error_mark_node;
    9710              : }
    9711              : 
    9712              : /* Warn when a value is moved to itself with std::move.  LHS is the target,
    9713              :    RHS may be the std::move call, and LOC is the location of the whole
    9714              :    assignment.  Return true if we warned.  */
    9715              : 
    9716              : bool
    9717     36571543 : maybe_warn_self_move (location_t loc, tree lhs, tree rhs)
    9718              : {
    9719     36571543 :   if (!warn_self_move)
    9720              :     return false;
    9721              : 
    9722              :   /* C++98 doesn't know move.  */
    9723       356282 :   if (cxx_dialect < cxx11)
    9724              :     return false;
    9725              : 
    9726       336459 :   if (processing_template_decl)
    9727              :     return false;
    9728              : 
    9729        25288 :   if (!REFERENCE_REF_P (rhs)
    9730       293732 :       || TREE_CODE (TREE_OPERAND (rhs, 0)) != CALL_EXPR)
    9731              :     return false;
    9732         4613 :   tree fn = TREE_OPERAND (rhs, 0);
    9733         4613 :   if (!is_std_move_p (fn))
    9734              :     return false;
    9735              : 
    9736              :   /* Just a little helper to strip * and various NOPs.  */
    9737         6387 :   auto extract_op = [] (tree &op) {
    9738         4258 :     STRIP_NOPS (op);
    9739         5437 :     while (INDIRECT_REF_P (op))
    9740         1179 :       op = TREE_OPERAND (op, 0);
    9741         4258 :     op = maybe_undo_parenthesized_ref (op);
    9742         4258 :     STRIP_ANY_LOCATION_WRAPPER (op);
    9743         4258 :   };
    9744              : 
    9745         2129 :   tree arg = CALL_EXPR_ARG (fn, 0);
    9746         2129 :   extract_op (arg);
    9747         2129 :   if (TREE_CODE (arg) == ADDR_EXPR)
    9748         1480 :     arg = TREE_OPERAND (arg, 0);
    9749         2129 :   tree type = TREE_TYPE (lhs);
    9750         2129 :   tree orig_lhs = lhs;
    9751         2129 :   extract_op (lhs);
    9752         2129 :   if (cp_tree_equal (lhs, arg)
    9753              :       /* Also warn in a member-initializer-list, as in : i(std::move(i)).  */
    9754         2129 :       || (TREE_CODE (lhs) == FIELD_DECL
    9755          634 :           && TREE_CODE (arg) == COMPONENT_REF
    9756          285 :           && cp_tree_equal (TREE_OPERAND (arg, 0), current_class_ref)
    9757            6 :           && TREE_OPERAND (arg, 1) == lhs))
    9758          117 :     if (warning_at (loc, OPT_Wself_move,
    9759              :                     "moving %qE of type %qT to itself", orig_lhs, type))
    9760              :       return true;
    9761              : 
    9762              :   return false;
    9763              : }
    9764              : 
    9765              : /* For use from the C common bits.  */
    9766              : tree
    9767         4766 : build_modify_expr (location_t location,
    9768              :                    tree lhs, tree /*lhs_origtype*/,
    9769              :                    enum tree_code modifycode,
    9770              :                    location_t /*rhs_location*/, tree rhs,
    9771              :                    tree /*rhs_origtype*/)
    9772              : {
    9773         4766 :   return cp_build_modify_expr (location, lhs, modifycode, rhs,
    9774         4766 :                                tf_warning_or_error);
    9775              : }
    9776              : 
    9777              : /* Build an assignment expression of lvalue LHS from value RHS.
    9778              :    MODIFYCODE is the code for a binary operator that we use
    9779              :    to combine the old value of LHS with RHS to get the new value.
    9780              :    Or else MODIFYCODE is NOP_EXPR meaning do a simple assignment.
    9781              : 
    9782              :    C++: If MODIFYCODE is INIT_EXPR, then leave references unbashed.  */
    9783              : 
    9784              : tree
    9785     45893840 : cp_build_modify_expr (location_t loc, tree lhs, enum tree_code modifycode,
    9786              :                       tree rhs, tsubst_flags_t complain)
    9787              : {
    9788     45893840 :   lhs = mark_lvalue_use_nonread (lhs);
    9789              : 
    9790     45893840 :   tree result = NULL_TREE;
    9791     45893840 :   tree newrhs = rhs;
    9792     45893840 :   tree lhstype = TREE_TYPE (lhs);
    9793     45893840 :   tree olhs = lhs;
    9794     45893840 :   tree olhstype = lhstype;
    9795     45893840 :   bool plain_assign = (modifycode == NOP_EXPR);
    9796     45893840 :   bool compound_side_effects_p = false;
    9797     45893840 :   tree preeval = NULL_TREE;
    9798              : 
    9799              :   /* Avoid duplicate error messages from operands that had errors.  */
    9800     45893840 :   if (error_operand_p (lhs) || error_operand_p (rhs))
    9801           19 :     return error_mark_node;
    9802              : 
    9803     45893903 :   while (TREE_CODE (lhs) == COMPOUND_EXPR)
    9804              :     {
    9805           82 :       if (TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0)))
    9806           70 :         compound_side_effects_p = true;
    9807           82 :       lhs = TREE_OPERAND (lhs, 1);
    9808              :     }
    9809              : 
    9810              :   /* Handle control structure constructs used as "lvalues".  Note that we
    9811              :      leave COMPOUND_EXPR on the LHS because it is sequenced after the RHS.  */
    9812     45893821 :   switch (TREE_CODE (lhs))
    9813              :     {
    9814              :       /* Handle --foo = 5; as these are valid constructs in C++.  */
    9815           27 :     case PREDECREMENT_EXPR:
    9816           27 :     case PREINCREMENT_EXPR:
    9817           27 :       if (compound_side_effects_p)
    9818            9 :         newrhs = rhs = stabilize_expr (rhs, &preeval);
    9819           27 :       lhs = genericize_compound_lvalue (lhs);
    9820          173 :     maybe_add_compound:
    9821              :       /* If we had (bar, --foo) = 5; or (bar, (baz, --foo)) = 5;
    9822              :          and looked through the COMPOUND_EXPRs, readd them now around
    9823              :          the resulting lhs.  */
    9824          173 :       if (TREE_CODE (olhs) == COMPOUND_EXPR)
    9825              :         {
    9826            9 :           lhs = build2 (COMPOUND_EXPR, lhstype, TREE_OPERAND (olhs, 0), lhs);
    9827            9 :           tree *ptr = &TREE_OPERAND (lhs, 1);
    9828            9 :           for (olhs = TREE_OPERAND (olhs, 1);
    9829           12 :                TREE_CODE (olhs) == COMPOUND_EXPR;
    9830            3 :                olhs = TREE_OPERAND (olhs, 1))
    9831              :             {
    9832            3 :               *ptr = build2 (COMPOUND_EXPR, lhstype,
    9833            3 :                              TREE_OPERAND (olhs, 0), *ptr);
    9834            3 :               ptr = &TREE_OPERAND (*ptr, 1);
    9835              :             }
    9836              :         }
    9837              :       break;
    9838              : 
    9839          146 :     case MODIFY_EXPR:
    9840          146 :       if (compound_side_effects_p)
    9841            0 :         newrhs = rhs = stabilize_expr (rhs, &preeval);
    9842          146 :       lhs = genericize_compound_lvalue (lhs);
    9843          146 :       goto maybe_add_compound;
    9844              : 
    9845            0 :     case MIN_EXPR:
    9846            0 :     case MAX_EXPR:
    9847              :       /* MIN_EXPR and MAX_EXPR are currently only permitted as lvalues,
    9848              :          when neither operand has side-effects.  */
    9849            0 :       if (!lvalue_or_else (lhs, lv_assign, complain))
    9850            0 :         return error_mark_node;
    9851              : 
    9852            0 :       gcc_assert (!TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0))
    9853              :                   && !TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 1)));
    9854              : 
    9855            0 :       lhs = build3 (COND_EXPR, TREE_TYPE (lhs),
    9856            0 :                     build2 (TREE_CODE (lhs) == MIN_EXPR ? LE_EXPR : GE_EXPR,
    9857              :                             boolean_type_node,
    9858            0 :                             TREE_OPERAND (lhs, 0),
    9859            0 :                             TREE_OPERAND (lhs, 1)),
    9860            0 :                     TREE_OPERAND (lhs, 0),
    9861            0 :                     TREE_OPERAND (lhs, 1));
    9862          212 :       gcc_fallthrough ();
    9863              : 
    9864              :       /* Handle (a ? b : c) used as an "lvalue".  */
    9865          212 :     case COND_EXPR:
    9866          212 :       {
    9867              :         /* Produce (a ? (b = rhs) : (c = rhs))
    9868              :            except that the RHS goes through a save-expr
    9869              :            so the code to compute it is only emitted once.  */
    9870          212 :         if (VOID_TYPE_P (TREE_TYPE (rhs)))
    9871              :           {
    9872           18 :             if (complain & tf_error)
    9873           24 :               error_at (cp_expr_loc_or_loc (rhs, loc),
    9874              :                         "void value not ignored as it ought to be");
    9875           18 :             return error_mark_node;
    9876              :           }
    9877              : 
    9878          194 :         rhs = stabilize_expr (rhs, &preeval);
    9879              : 
    9880              :         /* Check this here to avoid odd errors when trying to convert
    9881              :            a throw to the type of the COND_EXPR.  */
    9882          194 :         if (!lvalue_or_else (lhs, lv_assign, complain))
    9883            6 :           return error_mark_node;
    9884              : 
    9885          188 :         tree op1 = TREE_OPERAND (lhs, 1);
    9886          188 :         if (TREE_CODE (op1) != THROW_EXPR)
    9887          182 :           op1 = cp_build_modify_expr (loc, op1, modifycode, rhs, complain);
    9888              :         /* When sanitizing undefined behavior, even when rhs doesn't need
    9889              :            stabilization at this point, the sanitization might add extra
    9890              :            SAVE_EXPRs in there and so make sure there is no tree sharing
    9891              :            in the rhs, otherwise those SAVE_EXPRs will have initialization
    9892              :            only in one of the two branches.  */
    9893          188 :         if (sanitize_flags_p (SANITIZE_UNDEFINED
    9894              :                               | SANITIZE_UNDEFINED_NONDEFAULT))
    9895            3 :           rhs = unshare_expr (rhs);
    9896          188 :         tree op2 = TREE_OPERAND (lhs, 2);
    9897          188 :         if (TREE_CODE (op2) != THROW_EXPR)
    9898          182 :           op2 = cp_build_modify_expr (loc, op2, modifycode, rhs, complain);
    9899          188 :         tree cond = build_conditional_expr (input_location,
    9900          188 :                                             TREE_OPERAND (lhs, 0), op1, op2,
    9901              :                                             complain);
    9902              : 
    9903          188 :         if (cond == error_mark_node)
    9904              :           return cond;
    9905              :         /* If we had (e, (a ? b : c)) = d; or (e, (f, (a ? b : c))) = d;
    9906              :            and looked through the COMPOUND_EXPRs, readd them now around
    9907              :            the resulting cond before adding the preevaluated rhs.  */
    9908          185 :         if (TREE_CODE (olhs) == COMPOUND_EXPR)
    9909              :           {
    9910           18 :             cond = build2 (COMPOUND_EXPR, TREE_TYPE (cond),
    9911           18 :                            TREE_OPERAND (olhs, 0), cond);
    9912           18 :             tree *ptr = &TREE_OPERAND (cond, 1);
    9913           18 :             for (olhs = TREE_OPERAND (olhs, 1);
    9914           21 :                  TREE_CODE (olhs) == COMPOUND_EXPR;
    9915            3 :                  olhs = TREE_OPERAND (olhs, 1))
    9916              :               {
    9917            3 :                 *ptr = build2 (COMPOUND_EXPR, TREE_TYPE (cond),
    9918            3 :                                TREE_OPERAND (olhs, 0), *ptr);
    9919            3 :                 ptr = &TREE_OPERAND (*ptr, 1);
    9920              :               }
    9921              :           }
    9922              :         /* Make sure the code to compute the rhs comes out
    9923              :            before the split.  */
    9924          185 :         result = cond;
    9925          185 :         goto ret;
    9926              :       }
    9927              : 
    9928              :     default:
    9929              :       lhs = olhs;
    9930              :       break;
    9931              :     }
    9932              : 
    9933     45893609 :   if (modifycode == INIT_EXPR)
    9934              :     {
    9935      4628160 :       if (BRACE_ENCLOSED_INITIALIZER_P (rhs))
    9936              :         /* Do the default thing.  */;
    9937      4390013 :       else if (TREE_CODE (rhs) == CONSTRUCTOR)
    9938              :         {
    9939              :           /* Compound literal.  */
    9940           96 :           if (! same_type_p (TREE_TYPE (rhs), lhstype))
    9941              :             /* Call convert to generate an error; see PR 11063.  */
    9942            0 :             rhs = convert (lhstype, rhs);
    9943           96 :           result = cp_build_init_expr (lhs, rhs);
    9944           96 :           TREE_SIDE_EFFECTS (result) = 1;
    9945           96 :           goto ret;
    9946              :         }
    9947      4389917 :       else if (! MAYBE_CLASS_TYPE_P (lhstype))
    9948              :         /* Do the default thing.  */;
    9949              :       else
    9950              :         {
    9951        39922 :           releasing_vec rhs_vec = make_tree_vector_single (rhs);
    9952        39922 :           result = build_special_member_call (lhs, complete_ctor_identifier,
    9953              :                                               &rhs_vec, lhstype, LOOKUP_NORMAL,
    9954              :                                               complain);
    9955        39922 :           if (result == NULL_TREE)
    9956            0 :             return error_mark_node;
    9957        39922 :           goto ret;
    9958        39922 :         }
    9959              :     }
    9960              :   else
    9961              :     {
    9962     41265449 :       lhs = require_complete_type (lhs, complain);
    9963     41265449 :       if (lhs == error_mark_node)
    9964              :         return error_mark_node;
    9965              : 
    9966     41265379 :       if (modifycode == NOP_EXPR)
    9967              :         {
    9968     36523599 :           maybe_warn_self_move (loc, lhs, rhs);
    9969              : 
    9970     36523599 :           if (c_dialect_objc ())
    9971              :             {
    9972            0 :               result = objc_maybe_build_modify_expr (lhs, rhs);
    9973            0 :               if (result)
    9974            0 :                 goto ret;
    9975              :             }
    9976              : 
    9977              :           /* `operator=' is not an inheritable operator.  */
    9978     36523599 :           if (! MAYBE_CLASS_TYPE_P (lhstype))
    9979              :             /* Do the default thing.  */;
    9980              :           else
    9981              :             {
    9982      6324973 :               result = build_new_op (input_location, MODIFY_EXPR,
    9983              :                                      LOOKUP_NORMAL, lhs, rhs,
    9984              :                                      make_node (NOP_EXPR), NULL_TREE,
    9985              :                                      /*overload=*/NULL, complain);
    9986      6324973 :               if (result == NULL_TREE)
    9987            0 :                 return error_mark_node;
    9988      6324973 :               goto ret;
    9989              :             }
    9990              :           lhstype = olhstype;
    9991              :         }
    9992              :       else
    9993              :         {
    9994      4741780 :           tree init = NULL_TREE;
    9995              : 
    9996              :           /* A binary op has been requested.  Combine the old LHS
    9997              :              value with the RHS producing the value we should actually
    9998              :              store into the LHS.  */
    9999      4741780 :           gcc_assert (!((TYPE_REF_P (lhstype)
   10000              :                          && MAYBE_CLASS_TYPE_P (TREE_TYPE (lhstype)))
   10001              :                         || MAYBE_CLASS_TYPE_P (lhstype)));
   10002              : 
   10003              :           /* Preevaluate the RHS to make sure its evaluation is complete
   10004              :              before the lvalue-to-rvalue conversion of the LHS:
   10005              : 
   10006              :              [expr.ass] With respect to an indeterminately-sequenced
   10007              :              function call, the operation of a compound assignment is a
   10008              :              single evaluation. [ Note: Therefore, a function call shall
   10009              :              not intervene between the lvalue-to-rvalue conversion and the
   10010              :              side effect associated with any single compound assignment
   10011              :              operator. -- end note ]  */
   10012      4741780 :           lhs = cp_stabilize_reference (lhs);
   10013      4741780 :           rhs = decay_conversion (rhs, complain);
   10014      4741780 :           if (rhs == error_mark_node)
   10015          123 :             return error_mark_node;
   10016              : 
   10017      4741777 :           {
   10018      4741777 :             auto_diagnostic_group d;
   10019      4741777 :             rhs = stabilize_expr (rhs, &init);
   10020      4741777 :             bool clear_decl_read = false;
   10021      4741777 :             tree stripped_lhs = tree_strip_any_location_wrapper (lhs);
   10022      1497517 :             if ((VAR_P (stripped_lhs) || TREE_CODE (stripped_lhs) == PARM_DECL)
   10023      3934956 :                 && !DECL_READ_P (stripped_lhs)
   10024       941204 :                 && (VAR_P (stripped_lhs) ? warn_unused_but_set_variable
   10025              :                                          : warn_unused_but_set_parameter) > 2
   10026         6760 :                 && !CLASS_TYPE_P (TREE_TYPE (lhs))
   10027      4748537 :                 && !CLASS_TYPE_P (TREE_TYPE (rhs)))
   10028              :               {
   10029         6760 :                 mark_exp_read (rhs);
   10030         6760 :                 if (!DECL_READ_P (stripped_lhs))
   10031      4741777 :                   clear_decl_read = true;
   10032              :               }
   10033      4741777 :             newrhs = cp_build_binary_op (loc, modifycode, lhs, rhs, complain);
   10034      4741777 :             if (clear_decl_read)
   10035         6760 :               DECL_READ_P (stripped_lhs) = 0;
   10036      4741777 :             if (newrhs == error_mark_node)
   10037              :               {
   10038          120 :                 if (complain & tf_error)
   10039           24 :                   inform (loc, "  in evaluation of %<%Q(%#T, %#T)%>",
   10040           24 :                           modifycode, TREE_TYPE (lhs), TREE_TYPE (rhs));
   10041          120 :                 return error_mark_node;
   10042              :               }
   10043      4741777 :           }
   10044              : 
   10045      4741657 :           if (init)
   10046       431380 :             newrhs = build2 (COMPOUND_EXPR, TREE_TYPE (newrhs), init, newrhs);
   10047              : 
   10048              :           /* Now it looks like a plain assignment.  */
   10049      4741657 :           modifycode = NOP_EXPR;
   10050      4741657 :           if (c_dialect_objc ())
   10051              :             {
   10052            0 :               result = objc_maybe_build_modify_expr (lhs, newrhs);
   10053            0 :               if (result)
   10054            0 :                 goto ret;
   10055              :             }
   10056              :         }
   10057     34940283 :       gcc_assert (!TYPE_REF_P (lhstype));
   10058     34940283 :       gcc_assert (!TYPE_REF_P (TREE_TYPE (newrhs)));
   10059              :     }
   10060              : 
   10061              :   /* The left-hand side must be an lvalue.  */
   10062     39528425 :   if (!lvalue_or_else (lhs, lv_assign, complain))
   10063          200 :     return error_mark_node;
   10064              : 
   10065              :   /* Warn about modifying something that is `const'.  Don't warn if
   10066              :      this is initialization.  */
   10067     39528225 :   if (modifycode != INIT_EXPR
   10068     39528225 :       && (TREE_READONLY (lhs) || CP_TYPE_CONST_P (lhstype)
   10069              :           /* Functions are not modifiable, even though they are
   10070              :              lvalues.  */
   10071     34905578 :           || FUNC_OR_METHOD_TYPE_P (TREE_TYPE (lhs))
   10072              :           /* If it's an aggregate and any field is const, then it is
   10073              :              effectively const.  */
   10074     34905530 :           || (CLASS_TYPE_P (lhstype)
   10075            0 :               && C_TYPE_FIELDS_READONLY (lhstype))))
   10076              :     {
   10077        34553 :       if (complain & tf_error)
   10078           85 :         cxx_readonly_error (loc, lhs, lv_assign);
   10079        34553 :       return error_mark_node;
   10080              :     }
   10081              : 
   10082              :   /* If storing into a structure or union member, it may have been given a
   10083              :      lowered bitfield type.  We need to convert to the declared type first,
   10084              :      so retrieve it now.  */
   10085              : 
   10086     39493672 :   olhstype = unlowered_expr_type (lhs);
   10087              : 
   10088              :   /* Convert new value to destination type.  */
   10089              : 
   10090     39493672 :   if (TREE_CODE (lhstype) == ARRAY_TYPE)
   10091              :     {
   10092          195 :       int from_array;
   10093              : 
   10094          195 :       if (BRACE_ENCLOSED_INITIALIZER_P (newrhs))
   10095              :         {
   10096           12 :           if (modifycode != INIT_EXPR)
   10097              :             {
   10098           12 :               if (complain & tf_error)
   10099           12 :                 error_at (loc,
   10100              :                           "assigning to an array from an initializer list");
   10101           12 :               return error_mark_node;
   10102              :             }
   10103            0 :           if (check_array_initializer (lhs, lhstype, newrhs))
   10104            0 :             return error_mark_node;
   10105            0 :           newrhs = digest_init (lhstype, newrhs, complain);
   10106            0 :           if (newrhs == error_mark_node)
   10107              :             return error_mark_node;
   10108              :         }
   10109              : 
   10110              :       /* C++11 8.5/17: "If the destination type is an array of characters,
   10111              :          an array of char16_t, an array of char32_t, or an array of wchar_t,
   10112              :          and the initializer is a string literal...".  */
   10113          183 :       else if ((TREE_CODE (tree_strip_any_location_wrapper (newrhs))
   10114              :                 == STRING_CST)
   10115           43 :                && char_type_p (TREE_TYPE (TYPE_MAIN_VARIANT (lhstype)))
   10116          226 :                && modifycode == INIT_EXPR)
   10117              :         {
   10118           28 :           newrhs = digest_init (lhstype, newrhs, complain);
   10119           28 :           if (newrhs == error_mark_node)
   10120              :             return error_mark_node;
   10121              :         }
   10122              : 
   10123          155 :       else if (!same_or_base_type_p (TYPE_MAIN_VARIANT (lhstype),
   10124              :                                      TYPE_MAIN_VARIANT (TREE_TYPE (newrhs))))
   10125              :         {
   10126           22 :           if (complain & tf_error)
   10127           12 :             error_at (loc, "incompatible types in assignment of %qT to %qT",
   10128           12 :                       TREE_TYPE (rhs), lhstype);
   10129           22 :           return error_mark_node;
   10130              :         }
   10131              : 
   10132              :       /* Allow array assignment in compiler-generated code.  */
   10133          133 :       else if (DECL_P (lhs) && DECL_ARTIFICIAL (lhs))
   10134              :         /* OK, used by coroutines (co-await-initlist1.C).  */;
   10135          127 :       else if (!current_function_decl
   10136          127 :                || !DECL_DEFAULTED_FN (current_function_decl))
   10137              :         {
   10138              :           /* This routine is used for both initialization and assignment.
   10139              :              Make sure the diagnostic message differentiates the context.  */
   10140           80 :           if (complain & tf_error)
   10141              :             {
   10142           30 :               if (modifycode == INIT_EXPR)
   10143            9 :                 error_at (loc, "array used as initializer");
   10144              :               else
   10145           21 :                 error_at (loc, "invalid array assignment");
   10146              :             }
   10147           80 :           return error_mark_node;
   10148              :         }
   10149              : 
   10150          128 :       from_array = TREE_CODE (TREE_TYPE (newrhs)) == ARRAY_TYPE
   10151           81 :                    ? 1 + (modifycode != INIT_EXPR) : 0;
   10152           81 :       result = build_vec_init (lhs, NULL_TREE, newrhs,
   10153              :                                /*explicit_value_init_p=*/false,
   10154              :                                from_array, complain);
   10155           81 :       goto ret;
   10156              :     }
   10157              : 
   10158     39493477 :   if (modifycode == INIT_EXPR)
   10159              :     /* Calls with INIT_EXPR are all direct-initialization, so don't set
   10160              :        LOOKUP_ONLYCONVERTING.  */
   10161      4588083 :     newrhs = convert_for_initialization (lhs, olhstype, newrhs, LOOKUP_NORMAL,
   10162              :                                          ICR_INIT, NULL_TREE, 0,
   10163              :                                          complain | tf_no_cleanup);
   10164              :   else
   10165     34905394 :     newrhs = convert_for_assignment (olhstype, newrhs, ICR_ASSIGN,
   10166              :                                      NULL_TREE, 0, complain, LOOKUP_IMPLICIT);
   10167              : 
   10168     39493477 :   if (!same_type_p (lhstype, olhstype))
   10169       762111 :     newrhs = cp_convert_and_check (lhstype, newrhs, complain);
   10170              : 
   10171     39493477 :   if (modifycode != INIT_EXPR)
   10172              :     {
   10173     34905394 :       if (TREE_CODE (newrhs) == CALL_EXPR
   10174     34905394 :           && TYPE_NEEDS_CONSTRUCTING (lhstype))
   10175            0 :         newrhs = build_cplus_new (lhstype, newrhs, complain);
   10176              : 
   10177              :       /* Can't initialize directly from a TARGET_EXPR, since that would
   10178              :          cause the lhs to be constructed twice, and possibly result in
   10179              :          accidental self-initialization.  So we force the TARGET_EXPR to be
   10180              :          expanded without a target.  */
   10181     34905394 :       if (TREE_CODE (newrhs) == TARGET_EXPR)
   10182           84 :         newrhs = build2 (COMPOUND_EXPR, TREE_TYPE (newrhs), newrhs,
   10183           84 :                          TARGET_EXPR_SLOT (newrhs));
   10184              :     }
   10185              : 
   10186     39493477 :   if (newrhs == error_mark_node)
   10187              :     return error_mark_node;
   10188              : 
   10189     39492877 :   if (c_dialect_objc () && flag_objc_gc)
   10190              :     {
   10191            0 :       result = objc_generate_write_barrier (lhs, modifycode, newrhs);
   10192              : 
   10193            0 :       if (result)
   10194            0 :         goto ret;
   10195              :     }
   10196              : 
   10197     44080911 :   result = build2_loc (loc, modifycode == NOP_EXPR ? MODIFY_EXPR : INIT_EXPR,
   10198              :                        lhstype, lhs, newrhs);
   10199     39492877 :   if (modifycode == INIT_EXPR)
   10200      4588034 :     set_target_expr_eliding (newrhs);
   10201              : 
   10202     39492877 :   TREE_SIDE_EFFECTS (result) = 1;
   10203     39492877 :   if (!plain_assign)
   10204      9329661 :     suppress_warning (result, OPT_Wparentheses);
   10205              : 
   10206     30163216 :  ret:
   10207     45858134 :   if (preeval)
   10208           39 :     result = build2 (COMPOUND_EXPR, TREE_TYPE (result), preeval, result);
   10209              :   return result;
   10210              : }
   10211              : 
   10212              : cp_expr
   10213     76569323 : build_x_modify_expr (location_t loc, tree lhs, enum tree_code modifycode,
   10214              :                      tree rhs, tree lookups, tsubst_flags_t complain)
   10215              : {
   10216     76569323 :   tree orig_lhs = lhs;
   10217     76569323 :   tree orig_rhs = rhs;
   10218     76569323 :   tree overload = NULL_TREE;
   10219              : 
   10220     76569323 :   if (lhs == error_mark_node || rhs == error_mark_node)
   10221         2125 :     return cp_expr (error_mark_node, loc);
   10222              : 
   10223     76567198 :   tree op = build_min (modifycode, void_type_node, NULL_TREE, NULL_TREE);
   10224              : 
   10225     76567198 :   if (processing_template_decl)
   10226              :     {
   10227     47248396 :       if (type_dependent_expression_p (lhs)
   10228     47248396 :           || type_dependent_expression_p (rhs))
   10229              :         {
   10230     35336771 :           tree rval = build_min_nt_loc (loc, MODOP_EXPR, lhs, op, rhs);
   10231     35336771 :           if (modifycode != NOP_EXPR)
   10232      5951514 :             TREE_TYPE (rval)
   10233     11903028 :               = build_dependent_operator_type (lookups, modifycode, true);
   10234     35336771 :           return rval;
   10235              :         }
   10236              :     }
   10237              : 
   10238     41230427 :   tree rval;
   10239     41230427 :   if (modifycode == NOP_EXPR)
   10240     33584189 :     rval = cp_build_modify_expr (loc, lhs, modifycode, rhs, complain);
   10241              :   else
   10242      7646238 :     rval = build_new_op (loc, MODIFY_EXPR, LOOKUP_NORMAL,
   10243              :                          lhs, rhs, op, lookups, &overload, complain);
   10244     41230427 :   if (rval == error_mark_node)
   10245         4121 :     return error_mark_node;
   10246     41226306 :   if (processing_template_decl)
   10247              :     {
   10248     11911604 :       if (overload != NULL_TREE)
   10249      1874193 :         return (build_min_non_dep_op_overload
   10250      1874193 :                 (MODIFY_EXPR, rval, overload, orig_lhs, orig_rhs));
   10251              : 
   10252     10037411 :       return (build_min_non_dep
   10253     10037411 :               (MODOP_EXPR, rval, orig_lhs, op, orig_rhs));
   10254              :     }
   10255     29314702 :   return rval;
   10256              : }
   10257              : 
   10258              : /* Helper function for get_delta_difference which assumes FROM is a base
   10259              :    class of TO.  Returns a delta for the conversion of pointer-to-member
   10260              :    of FROM to pointer-to-member of TO.  If the conversion is invalid and
   10261              :    tf_error is not set in COMPLAIN returns error_mark_node, otherwise
   10262              :    returns zero.  If FROM is not a base class of TO, returns NULL_TREE.
   10263              :    If C_CAST_P is true, this conversion is taking place as part of a
   10264              :    C-style cast.  */
   10265              : 
   10266              : static tree
   10267        27912 : get_delta_difference_1 (tree from, tree to, bool c_cast_p,
   10268              :                         tsubst_flags_t complain)
   10269              : {
   10270        27912 :   tree binfo;
   10271        27912 :   base_kind kind;
   10272              : 
   10273        55574 :   binfo = lookup_base (to, from, c_cast_p ? ba_unique : ba_check,
   10274              :                        &kind, complain);
   10275              : 
   10276        27912 :   if (binfo == error_mark_node)
   10277              :     {
   10278           51 :       if (!(complain & tf_error))
   10279              :         return error_mark_node;
   10280              : 
   10281           51 :       inform (input_location, "   in pointer to member function conversion");
   10282           51 :       return size_zero_node;
   10283              :     }
   10284        27861 :   else if (binfo)
   10285              :     {
   10286        27713 :       if (kind != bk_via_virtual)
   10287        27620 :         return BINFO_OFFSET (binfo);
   10288              :       else
   10289              :         /* FROM is a virtual base class of TO.  Issue an error or warning
   10290              :            depending on whether or not this is a reinterpret cast.  */
   10291              :         {
   10292           93 :           if (!(complain & tf_error))
   10293              :             return error_mark_node;
   10294              : 
   10295           78 :           error ("pointer to member conversion via virtual base %qT",
   10296           78 :                  BINFO_TYPE (binfo_from_vbase (binfo)));
   10297              : 
   10298           78 :           return size_zero_node;
   10299              :         }
   10300              :       }
   10301              :   else
   10302              :     return NULL_TREE;
   10303              : }
   10304              : 
   10305              : /* Get difference in deltas for different pointer to member function
   10306              :    types.  If the conversion is invalid and tf_error is not set in
   10307              :    COMPLAIN, returns error_mark_node, otherwise returns an integer
   10308              :    constant of type PTRDIFF_TYPE_NODE and its value is zero if the
   10309              :    conversion is invalid.  If ALLOW_INVERSE_P is true, then allow reverse
   10310              :    conversions as well.  If C_CAST_P is true this conversion is taking
   10311              :    place as part of a C-style cast.
   10312              : 
   10313              :    Note that the naming of FROM and TO is kind of backwards; the return
   10314              :    value is what we add to a TO in order to get a FROM.  They are named
   10315              :    this way because we call this function to find out how to convert from
   10316              :    a pointer to member of FROM to a pointer to member of TO.  */
   10317              : 
   10318              : static tree
   10319        86957 : get_delta_difference (tree from, tree to,
   10320              :                       bool allow_inverse_p,
   10321              :                       bool c_cast_p, tsubst_flags_t complain)
   10322              : {
   10323        86957 :   auto_diagnostic_group d;
   10324        86957 :   tree result;
   10325              : 
   10326        86957 :   if (same_type_ignoring_top_level_qualifiers_p (from, to))
   10327              :     /* Pointer to member of incomplete class is permitted*/
   10328        59193 :     result = size_zero_node;
   10329              :   else
   10330        27764 :     result = get_delta_difference_1 (from, to, c_cast_p, complain);
   10331              : 
   10332        86957 :   if (result == error_mark_node)
   10333              :     return error_mark_node;
   10334              : 
   10335        86942 :   if (!result)
   10336              :   {
   10337          148 :     if (!allow_inverse_p)
   10338              :       {
   10339            0 :         if (!(complain & tf_error))
   10340              :           return error_mark_node;
   10341              : 
   10342            0 :         error_not_base_type (from, to);
   10343            0 :         inform (input_location, "   in pointer to member conversion");
   10344            0 :         result = size_zero_node;
   10345              :       }
   10346              :     else
   10347              :       {
   10348          148 :         result = get_delta_difference_1 (to, from, c_cast_p, complain);
   10349              : 
   10350          148 :         if (result == error_mark_node)
   10351              :           return error_mark_node;
   10352              : 
   10353          148 :         if (result)
   10354          148 :           result = size_diffop_loc (input_location,
   10355              :                                     size_zero_node, result);
   10356              :         else
   10357              :           {
   10358            0 :             if (!(complain & tf_error))
   10359              :               return error_mark_node;
   10360              : 
   10361            0 :             error_not_base_type (from, to);
   10362            0 :             inform (input_location, "   in pointer to member conversion");
   10363            0 :             result = size_zero_node;
   10364              :           }
   10365              :       }
   10366              :   }
   10367              : 
   10368        86942 :   return convert_to_integer (ptrdiff_type_node, result);
   10369        86957 : }
   10370              : 
   10371              : /* Return a constructor for the pointer-to-member-function TYPE using
   10372              :    the other components as specified.  */
   10373              : 
   10374              : tree
   10375        59467 : build_ptrmemfunc1 (tree type, tree delta, tree pfn)
   10376              : {
   10377        59467 :   tree u = NULL_TREE;
   10378        59467 :   tree delta_field;
   10379        59467 :   tree pfn_field;
   10380        59467 :   vec<constructor_elt, va_gc> *v;
   10381              : 
   10382              :   /* Pull the FIELD_DECLs out of the type.  */
   10383        59467 :   pfn_field = TYPE_FIELDS (type);
   10384        59467 :   delta_field = DECL_CHAIN (pfn_field);
   10385              : 
   10386              :   /* Make sure DELTA has the type we want.  */
   10387        59467 :   delta = convert_and_check (input_location, delta_type_node, delta);
   10388              : 
   10389              :   /* Convert to the correct target type if necessary.  */
   10390        59467 :   pfn = fold_convert (TREE_TYPE (pfn_field), pfn);
   10391              : 
   10392              :   /* Finish creating the initializer.  */
   10393        59467 :   vec_alloc (v, 2);
   10394        59467 :   CONSTRUCTOR_APPEND_ELT(v, pfn_field, pfn);
   10395        59467 :   CONSTRUCTOR_APPEND_ELT(v, delta_field, delta);
   10396        59467 :   u = build_constructor (type, v);
   10397        59467 :   TREE_CONSTANT (u) = TREE_CONSTANT (pfn) & TREE_CONSTANT (delta);
   10398        59467 :   TREE_STATIC (u) = (TREE_CONSTANT (u)
   10399        59353 :                      && (initializer_constant_valid_p (pfn, TREE_TYPE (pfn))
   10400              :                          != NULL_TREE)
   10401       118820 :                      && (initializer_constant_valid_p (delta, TREE_TYPE (delta))
   10402              :                          != NULL_TREE));
   10403        59467 :   return u;
   10404              : }
   10405              : 
   10406              : /* Build a constructor for a pointer to member function.  It can be
   10407              :    used to initialize global variables, local variable, or used
   10408              :    as a value in expressions.  TYPE is the POINTER to METHOD_TYPE we
   10409              :    want to be.
   10410              : 
   10411              :    If FORCE is nonzero, then force this conversion, even if
   10412              :    we would rather not do it.  Usually set when using an explicit
   10413              :    cast.  A C-style cast is being processed iff C_CAST_P is true.
   10414              : 
   10415              :    Return error_mark_node, if something goes wrong.  */
   10416              : 
   10417              : tree
   10418        29180 : build_ptrmemfunc (tree type, tree pfn, int force, bool c_cast_p,
   10419              :                   tsubst_flags_t complain)
   10420              : {
   10421        29180 :   tree fn;
   10422        29180 :   tree pfn_type;
   10423        29180 :   tree to_type;
   10424              : 
   10425        29180 :   if (error_operand_p (pfn))
   10426            0 :     return error_mark_node;
   10427              : 
   10428        29180 :   pfn_type = TREE_TYPE (pfn);
   10429        29180 :   to_type = build_ptrmemfunc_type (type);
   10430              : 
   10431              :   /* Handle multiple conversions of pointer to member functions.  */
   10432        29180 :   if (TYPE_PTRMEMFUNC_P (pfn_type))
   10433              :     {
   10434        27467 :       tree delta = NULL_TREE;
   10435        27467 :       tree npfn = NULL_TREE;
   10436        27467 :       tree n;
   10437              : 
   10438        27467 :       if (!force
   10439        27467 :           && !can_convert_arg (to_type, TREE_TYPE (pfn), pfn,
   10440              :                                LOOKUP_NORMAL, complain))
   10441              :         {
   10442            0 :           if (complain & tf_error)
   10443            0 :             error ("invalid conversion to type %qT from type %qT",
   10444              :                    to_type, pfn_type);
   10445              :           else
   10446            0 :             return error_mark_node;
   10447              :         }
   10448              : 
   10449        27467 :       n = get_delta_difference (TYPE_PTRMEMFUNC_OBJECT_TYPE (pfn_type),
   10450        27467 :                                 TYPE_PTRMEMFUNC_OBJECT_TYPE (to_type),
   10451              :                                 force,
   10452              :                                 c_cast_p, complain);
   10453        27467 :       if (n == error_mark_node)
   10454              :         return error_mark_node;
   10455              : 
   10456        27458 :       STRIP_ANY_LOCATION_WRAPPER (pfn);
   10457              : 
   10458              :       /* We don't have to do any conversion to convert a
   10459              :          pointer-to-member to its own type.  But, we don't want to
   10460              :          just return a PTRMEM_CST if there's an explicit cast; that
   10461              :          cast should make the expression an invalid template argument.  */
   10462        27458 :       if (TREE_CODE (pfn) != PTRMEM_CST
   10463        27458 :           && same_type_p (to_type, pfn_type))
   10464              :         return pfn;
   10465              : 
   10466        27458 :       if (TREE_SIDE_EFFECTS (pfn))
   10467           14 :         pfn = save_expr (pfn);
   10468              : 
   10469              :       /* Obtain the function pointer and the current DELTA.  */
   10470        27458 :       if (TREE_CODE (pfn) == PTRMEM_CST)
   10471        27364 :         expand_ptrmemfunc_cst (pfn, &delta, &npfn);
   10472              :       else
   10473              :         {
   10474           94 :           npfn = build_ptrmemfunc_access_expr (pfn, pfn_identifier);
   10475           94 :           delta = build_ptrmemfunc_access_expr (pfn, delta_identifier);
   10476              :         }
   10477              : 
   10478              :       /* Just adjust the DELTA field.  */
   10479        27458 :       gcc_assert  (same_type_ignoring_top_level_qualifiers_p
   10480              :                    (TREE_TYPE (delta), ptrdiff_type_node));
   10481        27458 :       if (!integer_zerop (n))
   10482              :         {
   10483           50 :           if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_delta)
   10484              :             n = cp_build_binary_op (input_location,
   10485              :                                     LSHIFT_EXPR, n, integer_one_node,
   10486              :                                     complain);
   10487           50 :           delta = cp_build_binary_op (input_location,
   10488              :                                       PLUS_EXPR, delta, n, complain);
   10489              :         }
   10490        27458 :       return build_ptrmemfunc1 (to_type, delta, npfn);
   10491              :     }
   10492              : 
   10493              :   /* Handle null pointer to member function conversions.  */
   10494         1713 :   if (null_ptr_cst_p (pfn))
   10495              :     {
   10496          635 :       pfn = cp_build_c_cast (input_location,
   10497          635 :                              TYPE_PTRMEMFUNC_FN_TYPE_RAW (to_type),
   10498              :                              pfn, complain);
   10499          635 :       return build_ptrmemfunc1 (to_type,
   10500              :                                 integer_zero_node,
   10501          635 :                                 pfn);
   10502              :     }
   10503              : 
   10504         1078 :   if (type_unknown_p (pfn))
   10505            0 :     return instantiate_type (type, pfn, complain);
   10506              : 
   10507         1078 :   fn = TREE_OPERAND (pfn, 0);
   10508         1078 :   gcc_assert (TREE_CODE (fn) == FUNCTION_DECL
   10509              :               /* In a template, we will have preserved the
   10510              :                  OFFSET_REF.  */
   10511              :               || (processing_template_decl && TREE_CODE (fn) == OFFSET_REF));
   10512         1078 :   return make_ptrmem_cst (to_type, fn);
   10513              : }
   10514              : 
   10515              : /* Return the DELTA, IDX, PFN, and DELTA2 values for the PTRMEM_CST
   10516              :    given by CST.
   10517              : 
   10518              :    ??? There is no consistency as to the types returned for the above
   10519              :    values.  Some code acts as if it were a sizetype and some as if it were
   10520              :    integer_type_node.  */
   10521              : 
   10522              : void
   10523        59108 : expand_ptrmemfunc_cst (tree cst, tree *delta, tree *pfn)
   10524              : {
   10525        59108 :   tree type = TREE_TYPE (cst);
   10526        59108 :   tree fn = PTRMEM_CST_MEMBER (cst);
   10527        59108 :   tree ptr_class, fn_class;
   10528              : 
   10529        59108 :   gcc_assert (TREE_CODE (fn) == FUNCTION_DECL);
   10530              : 
   10531              :   /* The class that the function belongs to.  */
   10532        59108 :   fn_class = DECL_CONTEXT (fn);
   10533              : 
   10534              :   /* The class that we're creating a pointer to member of.  */
   10535        59108 :   ptr_class = TYPE_PTRMEMFUNC_OBJECT_TYPE (type);
   10536              : 
   10537              :   /* First, calculate the adjustment to the function's class.  */
   10538        59108 :   *delta = get_delta_difference (fn_class, ptr_class, /*force=*/0,
   10539              :                                  /*c_cast_p=*/0, tf_warning_or_error);
   10540              : 
   10541        59108 :   if (!DECL_VIRTUAL_P (fn))
   10542              :     {
   10543        57999 :       tree t = build_addr_func (fn, tf_warning_or_error);
   10544        57999 :       if (TREE_CODE (t) == ADDR_EXPR)
   10545        57999 :         SET_EXPR_LOCATION (t, PTRMEM_CST_LOCATION (cst));
   10546        57999 :       *pfn = convert (TYPE_PTRMEMFUNC_FN_TYPE (type), t);
   10547              :     }
   10548              :   else
   10549              :     {
   10550              :       /* If we're dealing with a virtual function, we have to adjust 'this'
   10551              :          again, to point to the base which provides the vtable entry for
   10552              :          fn; the call will do the opposite adjustment.  */
   10553         1109 :       tree orig_class = DECL_CONTEXT (fn);
   10554         1109 :       tree binfo = binfo_or_else (orig_class, fn_class);
   10555         1109 :       *delta = fold_build2 (PLUS_EXPR, TREE_TYPE (*delta),
   10556              :                             *delta, BINFO_OFFSET (binfo));
   10557              : 
   10558              :       /* We set PFN to the vtable offset at which the function can be
   10559              :          found, plus one (unless ptrmemfunc_vbit_in_delta, in which
   10560              :          case delta is shifted left, and then incremented).  */
   10561         1109 :       *pfn = DECL_VINDEX (fn);
   10562         1109 :       *pfn = fold_build2 (MULT_EXPR, integer_type_node, *pfn,
   10563              :                           TYPE_SIZE_UNIT (vtable_entry_type));
   10564              : 
   10565         1109 :       switch (TARGET_PTRMEMFUNC_VBIT_LOCATION)
   10566              :         {
   10567         1109 :         case ptrmemfunc_vbit_in_pfn:
   10568         1109 :           *pfn = fold_build2 (PLUS_EXPR, integer_type_node, *pfn,
   10569              :                               integer_one_node);
   10570         1109 :           break;
   10571              : 
   10572              :         case ptrmemfunc_vbit_in_delta:
   10573              :           *delta = fold_build2 (LSHIFT_EXPR, TREE_TYPE (*delta),
   10574              :                                 *delta, integer_one_node);
   10575              :           *delta = fold_build2 (PLUS_EXPR, TREE_TYPE (*delta),
   10576              :                                 *delta, integer_one_node);
   10577              :           break;
   10578              : 
   10579              :         default:
   10580              :           gcc_unreachable ();
   10581              :         }
   10582              : 
   10583         1109 :       *pfn = fold_convert (TYPE_PTRMEMFUNC_FN_TYPE (type), *pfn);
   10584              :     }
   10585        59108 : }
   10586              : 
   10587              : /* Return an expression for PFN from the pointer-to-member function
   10588              :    given by T.  */
   10589              : 
   10590              : static tree
   10591        83461 : pfn_from_ptrmemfunc (tree t)
   10592              : {
   10593        83461 :   if (TREE_CODE (t) == PTRMEM_CST)
   10594              :     {
   10595          185 :       tree delta;
   10596          185 :       tree pfn;
   10597              : 
   10598          185 :       expand_ptrmemfunc_cst (t, &delta, &pfn);
   10599          185 :       if (pfn)
   10600          185 :         return pfn;
   10601              :     }
   10602              : 
   10603        83276 :   return build_ptrmemfunc_access_expr (t, pfn_identifier);
   10604              : }
   10605              : 
   10606              : /* Return an expression for DELTA from the pointer-to-member function
   10607              :    given by T.  */
   10608              : 
   10609              : static tree
   10610        83461 : delta_from_ptrmemfunc (tree t)
   10611              : {
   10612        83461 :   if (TREE_CODE (t) == PTRMEM_CST)
   10613              :     {
   10614          185 :       tree delta;
   10615          185 :       tree pfn;
   10616              : 
   10617          185 :       expand_ptrmemfunc_cst (t, &delta, &pfn);
   10618          185 :       if (delta)
   10619          185 :         return delta;
   10620              :     }
   10621              : 
   10622        83276 :   return build_ptrmemfunc_access_expr (t, delta_identifier);
   10623              : }
   10624              : 
   10625              : /* Convert value RHS to type TYPE as preparation for an assignment to
   10626              :    an lvalue of type TYPE.  ERRTYPE indicates what kind of error the
   10627              :    implicit conversion is.  If FNDECL is non-NULL, we are doing the
   10628              :    conversion in order to pass the PARMNUMth argument of FNDECL.
   10629              :    If FNDECL is NULL, we are doing the conversion in function pointer
   10630              :    argument passing, conversion in initialization, etc. */
   10631              : 
   10632              : static tree
   10633    193808436 : convert_for_assignment (tree type, tree rhs,
   10634              :                         impl_conv_rhs errtype, tree fndecl, int parmnum,
   10635              :                         tsubst_flags_t complain, int flags)
   10636              : {
   10637    193808436 :   tree rhstype;
   10638    193808436 :   enum tree_code coder;
   10639              : 
   10640    193808436 :   location_t rhs_loc = cp_expr_loc_or_input_loc (rhs);
   10641    193808436 :   bool has_loc = EXPR_LOCATION (rhs) != UNKNOWN_LOCATION;
   10642              :   /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue,
   10643              :      but preserve location wrappers.  */
   10644    193808436 :   if (TREE_CODE (rhs) == NON_LVALUE_EXPR
   10645    193808436 :       && !location_wrapper_p (rhs))
   10646         8386 :     rhs = TREE_OPERAND (rhs, 0);
   10647              : 
   10648              :   /* Handle [dcl.init.list] direct-list-initialization from
   10649              :      single element of enumeration with a fixed underlying type.  */
   10650    193808436 :   if (is_direct_enum_init (type, rhs))
   10651              :     {
   10652           20 :       tree elt = CONSTRUCTOR_ELT (rhs, 0)->value;
   10653           20 :       if (check_narrowing (ENUM_UNDERLYING_TYPE (type), elt, complain))
   10654              :         {
   10655           11 :           warning_sentinel w (warn_useless_cast);
   10656           11 :           warning_sentinel w2 (warn_ignored_qualifiers);
   10657           11 :           rhs = cp_build_c_cast (rhs_loc, type, elt, complain);
   10658           11 :         }
   10659              :       else
   10660            9 :         rhs = error_mark_node;
   10661              :     }
   10662              : 
   10663    193808436 :   rhstype = TREE_TYPE (rhs);
   10664    193808436 :   coder = TREE_CODE (rhstype);
   10665              : 
   10666      1340637 :   if (VECTOR_TYPE_P (type) && coder == VECTOR_TYPE
   10667    195148967 :       && vector_types_convertible_p (type, rhstype, true))
   10668              :     {
   10669      1340522 :       rhs = mark_rvalue_use (rhs);
   10670      1340522 :       return convert (type, rhs);
   10671              :     }
   10672              : 
   10673    192467914 :   if (rhs == error_mark_node || rhstype == error_mark_node)
   10674              :     return error_mark_node;
   10675    192467905 :   if (TREE_CODE (rhs) == TREE_LIST && TREE_VALUE (rhs) == error_mark_node)
   10676              :     return error_mark_node;
   10677              : 
   10678              :   /* The RHS of an assignment cannot have void type.  */
   10679    192467905 :   if (coder == VOID_TYPE)
   10680              :     {
   10681           48 :       if (complain & tf_error)
   10682           30 :         error_at (rhs_loc, "void value not ignored as it ought to be");
   10683           48 :       return error_mark_node;
   10684              :     }
   10685              : 
   10686    192467857 :   if (c_dialect_objc ())
   10687              :     {
   10688            0 :       int parmno;
   10689            0 :       tree selector;
   10690            0 :       tree rname = fndecl;
   10691              : 
   10692            0 :       switch (errtype)
   10693              :         {
   10694              :           case ICR_ASSIGN:
   10695              :             parmno = -1;
   10696              :             break;
   10697            0 :           case ICR_INIT:
   10698            0 :             parmno = -2;
   10699            0 :             break;
   10700            0 :           default:
   10701            0 :             selector = objc_message_selector ();
   10702            0 :             parmno = parmnum;
   10703            0 :             if (selector && parmno > 1)
   10704              :               {
   10705            0 :                 rname = selector;
   10706            0 :                 parmno -= 1;
   10707              :               }
   10708              :         }
   10709              : 
   10710            0 :       if (objc_compare_types (type, rhstype, parmno, rname))
   10711              :         {
   10712            0 :           rhs = mark_rvalue_use (rhs);
   10713            0 :           return convert (type, rhs);
   10714              :         }
   10715              :     }
   10716              : 
   10717              :   /* [expr.ass]
   10718              : 
   10719              :      The expression is implicitly converted (clause _conv_) to the
   10720              :      cv-unqualified type of the left operand.
   10721              : 
   10722              :      We allow bad conversions here because by the time we get to this point
   10723              :      we are committed to doing the conversion.  If we end up doing a bad
   10724              :      conversion, convert_like will complain.  */
   10725    192467857 :   if (!can_convert_arg_bad (type, rhstype, rhs, flags, complain))
   10726              :     {
   10727              :       /* When -Wno-pmf-conversions is use, we just silently allow
   10728              :          conversions from pointers-to-members to plain pointers.  If
   10729              :          the conversion doesn't work, cp_convert will complain.  */
   10730         1498 :       if (!warn_pmf2ptr
   10731            9 :           && TYPE_PTR_P (type)
   10732         1507 :           && TYPE_PTRMEMFUNC_P (rhstype))
   10733            9 :         rhs = cp_convert (strip_top_quals (type), rhs, complain);
   10734              :       else
   10735              :         {
   10736         1489 :           if (complain & tf_error)
   10737              :             {
   10738         1280 :               auto_diagnostic_group d;
   10739              : 
   10740              :               /* If the right-hand side has unknown type, then it is an
   10741              :                  overloaded function.  Call instantiate_type to get error
   10742              :                  messages.  */
   10743         1280 :               if (rhstype == unknown_type_node)
   10744              :                 {
   10745          197 :                   tree r = instantiate_type (type, rhs, tf_warning_or_error);
   10746              :                   /* -fpermissive might allow this; recurse.  */
   10747          197 :                   if (!seen_error ())
   10748           15 :                     return convert_for_assignment (type, r, errtype, fndecl,
   10749              :                                                    parmnum, complain, flags);
   10750              :                 }
   10751         1083 :               else if (fndecl)
   10752           92 :                 complain_about_bad_argument (rhs_loc,
   10753              :                                              rhstype, type,
   10754              :                                              fndecl, parmnum);
   10755              :               else
   10756              :                 {
   10757          991 :                   range_label_for_type_mismatch label (rhstype, type);
   10758          991 :                   gcc_rich_location richloc
   10759              :                     (rhs_loc,
   10760              :                      has_loc ? &label : NULL,
   10761          991 :                      has_loc ? highlight_colors::percent_h : NULL);
   10762              : 
   10763          991 :                   switch (errtype)
   10764              :                     {
   10765            0 :                     case ICR_DEFAULT_ARGUMENT:
   10766            0 :                       error_at (&richloc,
   10767              :                                 "cannot convert %qH to %qI in default argument",
   10768              :                                 rhstype, type);
   10769            0 :                       break;
   10770            6 :                     case ICR_ARGPASS:
   10771            6 :                       error_at (&richloc,
   10772              :                                 "cannot convert %qH to %qI in argument passing",
   10773              :                                 rhstype, type);
   10774            6 :                       break;
   10775            0 :                     case ICR_CONVERTING:
   10776            0 :                       error_at (&richloc, "cannot convert %qH to %qI",
   10777              :                                 rhstype, type);
   10778            0 :                       break;
   10779          553 :                     case ICR_INIT:
   10780          553 :                       error_at (&richloc,
   10781              :                                 "cannot convert %qH to %qI in initialization",
   10782              :                                 rhstype, type);
   10783          553 :                       break;
   10784           18 :                     case ICR_RETURN:
   10785           18 :                       error_at (&richloc, "cannot convert %qH to %qI in return",
   10786              :                                 rhstype, type);
   10787           18 :                       break;
   10788          414 :                     case ICR_ASSIGN:
   10789          414 :                       error_at (&richloc,
   10790              :                                 "cannot convert %qH to %qI in assignment",
   10791              :                                 rhstype, type);
   10792          414 :                       break;
   10793            0 :                     default:
   10794            0 :                       gcc_unreachable();
   10795              :                   }
   10796          991 :                 }
   10797              : 
   10798              :               /* See if we can be more helpful.  */
   10799         1265 :               maybe_show_nonconverting_candidate (type, rhstype, rhs, flags);
   10800              : 
   10801         1265 :               if (TYPE_PTR_P (rhstype)
   10802          412 :                   && TYPE_PTR_P (type)
   10803          397 :                   && CLASS_TYPE_P (TREE_TYPE (rhstype))
   10804          279 :                   && CLASS_TYPE_P (TREE_TYPE (type))
   10805         1328 :                   && !COMPLETE_TYPE_P (TREE_TYPE (rhstype)))
   10806            3 :                 inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL
   10807              :                                               (TREE_TYPE (rhstype))),
   10808            3 :                         "class type %qT is incomplete", TREE_TYPE (rhstype));
   10809         1280 :             }
   10810         1474 :           return error_mark_node;
   10811              :         }
   10812              :     }
   10813    192466368 :   if (warn_suggest_attribute_format)
   10814              :     {
   10815         2383 :       const enum tree_code codel = TREE_CODE (type);
   10816         2383 :       if ((codel == POINTER_TYPE || codel == REFERENCE_TYPE)
   10817          596 :           && coder == codel
   10818          508 :           && check_missing_format_attribute (type, rhstype)
   10819         2401 :           && (complain & tf_warning))
   10820           18 :         switch (errtype)
   10821              :           {
   10822            0 :             case ICR_ARGPASS:
   10823            0 :             case ICR_DEFAULT_ARGUMENT:
   10824            0 :               if (fndecl)
   10825            0 :                 warning (OPT_Wsuggest_attribute_format,
   10826              :                          "parameter %qP of %qD might be a candidate "
   10827              :                          "for a format attribute", parmnum, fndecl);
   10828              :               else
   10829            0 :                 warning (OPT_Wsuggest_attribute_format,
   10830              :                          "parameter might be a candidate "
   10831              :                          "for a format attribute");
   10832              :               break;
   10833            0 :             case ICR_CONVERTING:
   10834            0 :               warning (OPT_Wsuggest_attribute_format,
   10835              :                        "target of conversion might be a candidate "
   10836              :                        "for a format attribute");
   10837            0 :               break;
   10838            6 :             case ICR_INIT:
   10839            6 :               warning (OPT_Wsuggest_attribute_format,
   10840              :                        "target of initialization might be a candidate "
   10841              :                        "for a format attribute");
   10842            6 :               break;
   10843            6 :             case ICR_RETURN:
   10844            6 :               warning (OPT_Wsuggest_attribute_format,
   10845              :                        "return type might be a candidate "
   10846              :                        "for a format attribute");
   10847            6 :               break;
   10848            6 :             case ICR_ASSIGN:
   10849            6 :               warning (OPT_Wsuggest_attribute_format,
   10850              :                        "left-hand side of assignment might be a candidate "
   10851              :                        "for a format attribute");
   10852            6 :               break;
   10853            0 :             default:
   10854            0 :               gcc_unreachable();
   10855              :           }
   10856              :     }
   10857              : 
   10858    192466368 :   if (TREE_CODE (type) == BOOLEAN_TYPE)
   10859     42023849 :     maybe_warn_unparenthesized_assignment (rhs, /*nested_p=*/true, complain);
   10860              : 
   10861    192466368 :   if (complain & tf_warning)
   10862    189733793 :     warn_for_address_of_packed_member (type, rhs);
   10863              : 
   10864    192466368 :   return perform_implicit_conversion_flags (strip_top_quals (type), rhs,
   10865    192466368 :                                             complain, flags);
   10866              : }
   10867              : 
   10868              : /* Convert RHS to be of type TYPE.
   10869              :    If EXP is nonzero, it is the target of the initialization.
   10870              :    ERRTYPE indicates what kind of error the implicit conversion is.
   10871              : 
   10872              :    Two major differences between the behavior of
   10873              :    `convert_for_assignment' and `convert_for_initialization'
   10874              :    are that references are bashed in the former, while
   10875              :    copied in the latter, and aggregates are assigned in
   10876              :    the former (operator=) while initialized in the
   10877              :    latter (X(X&)).
   10878              : 
   10879              :    If using constructor make sure no conversion operator exists, if one does
   10880              :    exist, an ambiguity exists.  */
   10881              : 
   10882              : tree
   10883    178398520 : convert_for_initialization (tree exp, tree type, tree rhs, int flags,
   10884              :                             impl_conv_rhs errtype, tree fndecl, int parmnum,
   10885              :                             tsubst_flags_t complain)
   10886              : {
   10887    178398520 :   enum tree_code codel = TREE_CODE (type);
   10888    178398520 :   tree rhstype;
   10889    178398520 :   enum tree_code coder;
   10890              : 
   10891              :   /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
   10892              :      Strip such NOP_EXPRs, since RHS is used in non-lvalue context.  */
   10893    178398520 :   if (TREE_CODE (rhs) == NOP_EXPR
   10894      6194303 :       && TREE_TYPE (rhs) == TREE_TYPE (TREE_OPERAND (rhs, 0))
   10895    178871864 :       && codel != REFERENCE_TYPE)
   10896       473344 :     rhs = TREE_OPERAND (rhs, 0);
   10897              : 
   10898    178398520 :   if (type == error_mark_node
   10899    178398477 :       || rhs == error_mark_node
   10900    356796936 :       || (TREE_CODE (rhs) == TREE_LIST && TREE_VALUE (rhs) == error_mark_node))
   10901              :     return error_mark_node;
   10902              : 
   10903    178398416 :   if (MAYBE_CLASS_TYPE_P (non_reference (type)))
   10904              :     ;
   10905    161434236 :   else if ((TREE_CODE (TREE_TYPE (rhs)) == ARRAY_TYPE
   10906      2027148 :             && TREE_CODE (type) != ARRAY_TYPE
   10907      2027148 :             && (!TYPE_REF_P (type)
   10908          668 :                 || TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE))
   10909    159407753 :            || (TREE_CODE (TREE_TYPE (rhs)) == FUNCTION_TYPE
   10910        24188 :                && !TYPE_REFFN_P (type))
   10911    320818661 :            || TREE_CODE (TREE_TYPE (rhs)) == METHOD_TYPE)
   10912      2049817 :     rhs = decay_conversion (rhs, complain);
   10913              : 
   10914    178398416 :   rhstype = TREE_TYPE (rhs);
   10915    178398416 :   coder = TREE_CODE (rhstype);
   10916              : 
   10917    178398416 :   if (coder == ERROR_MARK)
   10918            9 :     return error_mark_node;
   10919              : 
   10920              :   /* We accept references to incomplete types, so we can
   10921              :      return here before checking if RHS is of complete type.  */
   10922              : 
   10923    178398407 :   if (codel == REFERENCE_TYPE)
   10924              :     {
   10925      7307311 :       auto_diagnostic_group d;
   10926              :       /* This should eventually happen in convert_arguments.  */
   10927      7307311 :       int savew = 0, savee = 0;
   10928              : 
   10929      7307311 :       if (fndecl)
   10930       334964 :         savew = warningcount + werrorcount, savee = errorcount;
   10931      7307311 :       rhs = initialize_reference (type, rhs, flags, complain);
   10932              : 
   10933      7307311 :       if (fndecl
   10934      7307311 :           && (warningcount + werrorcount > savew || errorcount > savee))
   10935           36 :         inform (get_fndecl_argument_location (fndecl, parmnum),
   10936              :                 "in passing argument %P of %qD", parmnum, fndecl);
   10937      7307311 :       return rhs;
   10938      7307311 :     }
   10939              : 
   10940    171091096 :   if (exp != 0)
   10941      4588083 :     exp = require_complete_type (exp, complain);
   10942    171091096 :   if (exp == error_mark_node)
   10943              :     return error_mark_node;
   10944              : 
   10945    171091096 :   type = complete_type (type);
   10946              : 
   10947    171091096 :   if (DIRECT_INIT_EXPR_P (type, rhs))
   10948              :     /* Don't try to do copy-initialization if we already have
   10949              :        direct-initialization.  */
   10950              :     return rhs;
   10951              : 
   10952    171090102 :   if (MAYBE_CLASS_TYPE_P (type))
   10953     12187075 :     return perform_implicit_conversion_flags (type, rhs, complain, flags);
   10954              : 
   10955    158903027 :   return convert_for_assignment (type, rhs, errtype, fndecl, parmnum,
   10956    158903027 :                                  complain, flags);
   10957              : }
   10958              : 
   10959              : /* If RETVAL is the address of, or a reference to, a local variable or
   10960              :    temporary give an appropriate warning and return true.  */
   10961              : 
   10962              : static bool
   10963     47866772 : maybe_warn_about_returning_address_of_local (tree retval, location_t loc)
   10964              : {
   10965     47867558 :   tree valtype = TREE_TYPE (DECL_RESULT (current_function_decl));
   10966     47867558 :   tree whats_returned = fold_for_warn (retval);
   10967     47867558 :   if (!loc)
   10968     47867558 :     loc = cp_expr_loc_or_input_loc (retval);
   10969              : 
   10970     58469568 :   for (;;)
   10971              :     {
   10972     58469568 :       if (TREE_CODE (whats_returned) == COMPOUND_EXPR)
   10973       736523 :         whats_returned = TREE_OPERAND (whats_returned, 1);
   10974     57733045 :       else if (CONVERT_EXPR_P (whats_returned)
   10975     47900185 :                || TREE_CODE (whats_returned) == NON_LVALUE_EXPR)
   10976      9865487 :         whats_returned = TREE_OPERAND (whats_returned, 0);
   10977              :       else
   10978              :         break;
   10979              :     }
   10980              : 
   10981     47867558 :   if (TREE_CODE (whats_returned) == TARGET_EXPR
   10982     47867558 :       && is_std_init_list (TREE_TYPE (whats_returned)))
   10983              :     {
   10984           16 :       tree init = TARGET_EXPR_INITIAL (whats_returned);
   10985           16 :       if (TREE_CODE (init) == CONSTRUCTOR)
   10986              :         /* Pull out the array address.  */
   10987            7 :         whats_returned = CONSTRUCTOR_ELT (init, 0)->value;
   10988            9 :       else if (TREE_CODE (init) == INDIRECT_REF)
   10989              :         /* The source of a trivial copy looks like *(T*)&var.  */
   10990            6 :         whats_returned = TREE_OPERAND (init, 0);
   10991              :       else
   10992              :         return false;
   10993           13 :       STRIP_NOPS (whats_returned);
   10994              :     }
   10995              : 
   10996              :   /* As a special case, we handle a call to std::move or std::forward.  */
   10997     47867555 :   if (TREE_CODE (whats_returned) == CALL_EXPR
   10998     47867555 :       && (is_std_move_p (whats_returned)
   10999     11190588 :           || is_std_forward_p (whats_returned)))
   11000              :     {
   11001          774 :       tree arg = CALL_EXPR_ARG (whats_returned, 0);
   11002          774 :       return maybe_warn_about_returning_address_of_local (arg, loc);
   11003              :     }
   11004              : 
   11005     47866781 :   if (TREE_CODE (whats_returned) != ADDR_EXPR)
   11006              :     return false;
   11007       980546 :   whats_returned = TREE_OPERAND (whats_returned, 0);
   11008              : 
   11009       980546 :   while (TREE_CODE (whats_returned) == COMPONENT_REF
   11010      1930514 :          || TREE_CODE (whats_returned) == ARRAY_REF)
   11011       949968 :     whats_returned = TREE_OPERAND (whats_returned, 0);
   11012              : 
   11013       980546 :   if (TREE_CODE (whats_returned) == AGGR_INIT_EXPR
   11014       980546 :       || TREE_CODE (whats_returned) == TARGET_EXPR)
   11015              :     {
   11016           50 :       if (TYPE_REF_P (valtype))
   11017              :         /* P2748 made this an error in C++26.  */
   11018           72 :         emit_diagnostic ((cxx_dialect >= cxx26
   11019              :                           ? diagnostics::kind::permerror
   11020              :                           : diagnostics::kind::warning),
   11021           41 :                          loc, OPT_Wreturn_local_addr,
   11022              :                          "returning reference to temporary");
   11023            9 :       else if (TYPE_PTR_P (valtype))
   11024            3 :         warning_at (loc, OPT_Wreturn_local_addr,
   11025              :                     "returning pointer to temporary");
   11026            6 :       else if (is_std_init_list (valtype))
   11027            6 :         warning_at (loc, OPT_Winit_list_lifetime,
   11028              :                     "returning temporary %<initializer_list%> does not extend "
   11029              :                     "the lifetime of the underlying array");
   11030           50 :       return true;
   11031              :     }
   11032              : 
   11033       980496 :   STRIP_ANY_LOCATION_WRAPPER (whats_returned);
   11034              : 
   11035       980496 :   if (DECL_P (whats_returned)
   11036       120832 :       && DECL_NAME (whats_returned)
   11037       120832 :       && DECL_FUNCTION_SCOPE_P (whats_returned)
   11038        11910 :       && !is_capture_proxy (whats_returned)
   11039       992385 :       && !(TREE_STATIC (whats_returned)
   11040          146 :            || TREE_PUBLIC (whats_returned)))
   11041              :     {
   11042          106 :       if (DECL_DECOMPOSITION_P (whats_returned)
   11043           39 :           && !DECL_DECOMP_IS_BASE (whats_returned)
   11044          185 :           && DECL_HAS_VALUE_EXPR_P (whats_returned))
   11045              :         {
   11046              :           /* When returning address of a structured binding, if the structured
   11047              :              binding is not a reference, continue normally, if it is a
   11048              :              reference, recurse on the initializer of the structured
   11049              :              binding.  */
   11050           39 :           tree base = DECL_DECOMP_BASE (whats_returned);
   11051           39 :           if (TYPE_REF_P (TREE_TYPE (base)))
   11052              :             {
   11053           15 :               if (tree init = DECL_INITIAL (base))
   11054              :                 return maybe_warn_about_returning_address_of_local (init, loc);
   11055              :               else
   11056              :                 return false;
   11057              :             }
   11058              :         }
   11059          131 :       bool w = false;
   11060          131 :       auto_diagnostic_group d;
   11061          131 :       if (TYPE_REF_P (valtype))
   11062           81 :         w = warning_at (loc, OPT_Wreturn_local_addr,
   11063              :                         "reference to local variable %qD returned",
   11064              :                         whats_returned);
   11065           50 :       else if (is_std_init_list (valtype))
   11066            3 :         w = warning_at (loc, OPT_Winit_list_lifetime,
   11067              :                         "returning local %<initializer_list%> variable %qD "
   11068              :                         "does not extend the lifetime of the underlying array",
   11069              :                         whats_returned);
   11070           47 :       else if (POINTER_TYPE_P (valtype)
   11071           41 :                && TREE_CODE (whats_returned) == LABEL_DECL)
   11072            6 :         w = warning_at (loc, OPT_Wreturn_local_addr,
   11073              :                         "address of label %qD returned",
   11074              :                         whats_returned);
   11075           41 :       else if (POINTER_TYPE_P (valtype))
   11076           35 :         w = warning_at (loc, OPT_Wreturn_local_addr,
   11077              :                         "address of local variable %qD returned",
   11078              :                         whats_returned);
   11079          125 :       if (w)
   11080          103 :         inform (DECL_SOURCE_LOCATION (whats_returned),
   11081              :                 "declared here");
   11082          131 :       return true;
   11083          131 :     }
   11084              : 
   11085              :   return false;
   11086              : }
   11087              : 
   11088              : /* Returns true if DECL is in the std namespace.  */
   11089              : 
   11090              : bool
   11091    156472152 : decl_in_std_namespace_p (tree decl)
   11092              : {
   11093    186353744 :   while (decl)
   11094              :     {
   11095    185359260 :       decl = decl_namespace_context (decl);
   11096    185359260 :       if (DECL_NAMESPACE_STD_P (decl))
   11097              :         return true;
   11098              :       /* Allow inline namespaces inside of std namespace, e.g. with
   11099              :          --enable-symvers=gnu-versioned-namespace std::forward would be
   11100              :          actually std::_8::forward.  */
   11101     90094260 :       if (!DECL_NAMESPACE_INLINE_P (decl))
   11102              :         return false;
   11103     29881592 :       decl = CP_DECL_CONTEXT (decl);
   11104              :     }
   11105              :   return false;
   11106              : }
   11107              : 
   11108              : /* Returns true if FN, a CALL_EXPR, is a call to std::forward.  */
   11109              : 
   11110              : static bool
   11111     11190588 : is_std_forward_p (tree fn)
   11112              : {
   11113              :   /* std::forward only takes one argument.  */
   11114     11190588 :   if (call_expr_nargs (fn) != 1)
   11115              :     return false;
   11116              : 
   11117      4890597 :   tree fndecl = cp_get_callee_fndecl_nofold (fn);
   11118      4890597 :   if (!decl_in_std_namespace_p (fndecl))
   11119              :     return false;
   11120              : 
   11121      1859854 :   tree name = DECL_NAME (fndecl);
   11122      1859854 :   return name && id_equal (name, "forward");
   11123              : }
   11124              : 
   11125              : /* Returns true if FN, a CALL_EXPR, is a call to std::move.  */
   11126              : 
   11127              : static bool
   11128     11198257 : is_std_move_p (tree fn)
   11129              : {
   11130              :   /* std::move only takes one argument.  */
   11131     11198257 :   if (call_expr_nargs (fn) != 1)
   11132              :     return false;
   11133              : 
   11134      4897455 :   tree fndecl = cp_get_callee_fndecl_nofold (fn);
   11135      4897455 :   if (!decl_in_std_namespace_p (fndecl))
   11136              :     return false;
   11137              : 
   11138      1866226 :   tree name = DECL_NAME (fndecl);
   11139      1866226 :   return name && id_equal (name, "move");
   11140              : }
   11141              : 
   11142              : /* Returns true if RETVAL is a good candidate for the NRVO as per
   11143              :    [class.copy.elision].  FUNCTYPE is the type the function is declared
   11144              :    to return.  */
   11145              : 
   11146              : static bool
   11147     60346768 : can_do_nrvo_p (tree retval, tree functype)
   11148              : {
   11149     60346768 :   if (functype == error_mark_node)
   11150              :     return false;
   11151     60346722 :   if (retval)
   11152     58607794 :     STRIP_ANY_LOCATION_WRAPPER (retval);
   11153     60346722 :   tree result = DECL_RESULT (current_function_decl);
   11154     60346722 :   return (retval != NULL_TREE
   11155     58607794 :           && !processing_template_decl
   11156              :           /* Must be a local, automatic variable.  */
   11157     49559173 :           && VAR_P (retval)
   11158      4490025 :           && DECL_CONTEXT (retval) == current_function_decl
   11159      3395151 :           && !TREE_STATIC (retval)
   11160              :           /* And not a lambda or anonymous union proxy.  */
   11161      3392359 :           && !DECL_HAS_VALUE_EXPR_P (retval)
   11162      3392113 :           && (DECL_ALIGN (retval) <= DECL_ALIGN (result))
   11163              :           /* The cv-unqualified type of the returned value must be the
   11164              :              same as the cv-unqualified return type of the
   11165              :              function.  */
   11166      3391999 :           && same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (retval)),
   11167              :                           TYPE_MAIN_VARIANT (functype))
   11168              :           /* And the returned value must be non-volatile.  */
   11169     63716954 :           && !TYPE_VOLATILE (TREE_TYPE (retval)));
   11170              : }
   11171              : 
   11172              : /* True if we would like to perform NRVO, i.e. can_do_nrvo_p is true and we
   11173              :    would otherwise return in memory.  */
   11174              : 
   11175              : static bool
   11176     60346406 : want_nrvo_p (tree retval, tree functype)
   11177              : {
   11178     60346406 :   return (can_do_nrvo_p (retval, functype)
   11179     60346406 :           && aggregate_value_p (functype, current_function_decl));
   11180              : }
   11181              : 
   11182              : /* Like can_do_nrvo_p, but we check if we're trying to move a class
   11183              :    prvalue.  */
   11184              : 
   11185              : static bool
   11186         1783 : can_elide_copy_prvalue_p (tree retval, tree functype)
   11187              : {
   11188         1783 :   if (functype == error_mark_node)
   11189              :     return false;
   11190         1783 :   if (retval)
   11191         1783 :     STRIP_ANY_LOCATION_WRAPPER (retval);
   11192         1783 :   return (retval != NULL_TREE
   11193         1783 :           && !glvalue_p (retval)
   11194          135 :           && same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (retval)),
   11195              :                           TYPE_MAIN_VARIANT (functype))
   11196         1891 :           && !TYPE_VOLATILE (TREE_TYPE (retval)));
   11197              : }
   11198              : 
   11199              : /* If we should treat RETVAL, an expression being returned, as if it were
   11200              :    designated by an rvalue, returns it adjusted accordingly; otherwise, returns
   11201              :    NULL_TREE.  See [class.copy.elision].  RETURN_P is true if this is a return
   11202              :    context (rather than throw).  */
   11203              : 
   11204              : tree
   11205     12837287 : treat_lvalue_as_rvalue_p (tree expr, bool return_p)
   11206              : {
   11207     12837287 :   if (cxx_dialect == cxx98)
   11208              :     return NULL_TREE;
   11209              : 
   11210     12828779 :   tree retval = expr;
   11211     12828779 :   STRIP_ANY_LOCATION_WRAPPER (retval);
   11212     12828779 :   if (REFERENCE_REF_P (retval))
   11213       506123 :     retval = TREE_OPERAND (retval, 0);
   11214              : 
   11215              :   /* An implicitly movable entity is a variable of automatic storage duration
   11216              :      that is either a non-volatile object or (C++20) an rvalue reference to a
   11217              :      non-volatile object type.  */
   11218     12828779 :   if (!(((VAR_P (retval) && !DECL_HAS_VALUE_EXPR_P (retval))
   11219     11636667 :          || TREE_CODE (retval) == PARM_DECL)
   11220      1829418 :         && !TREE_STATIC (retval)
   11221      1751295 :         && !CP_TYPE_VOLATILE_P (non_reference (TREE_TYPE (retval)))
   11222      1751290 :         && (TREE_CODE (TREE_TYPE (retval)) != REFERENCE_TYPE
   11223       106405 :             || (cxx_dialect >= cxx20
   11224       105863 :                 && TYPE_REF_IS_RVALUE (TREE_TYPE (retval))))))
   11225     11183321 :     return NULL_TREE;
   11226              : 
   11227              :   /* If the expression in a return or co_return statement is a (possibly
   11228              :      parenthesized) id-expression that names an implicitly movable entity
   11229              :      declared in the body or parameter-declaration-clause of the innermost
   11230              :      enclosing function or lambda-expression, */
   11231      1645458 :   if (return_p)
   11232              :     {
   11233      1636376 :       if (DECL_CONTEXT (retval) != current_function_decl)
   11234              :         return NULL_TREE;
   11235      1636310 :       expr = move (expr);
   11236      1636310 :       if (expr == error_mark_node)
   11237              :         return NULL_TREE;
   11238      1636308 :       return set_implicit_rvalue_p (expr);
   11239              :     }
   11240              : 
   11241              :   /* if the id-expression (possibly parenthesized) is the operand of
   11242              :      a throw-expression, and names an implicitly movable entity that belongs
   11243              :      to a scope that does not contain the compound-statement of the innermost
   11244              :      lambda-expression, try-block, or function-try-block (if any) whose
   11245              :      compound-statement or ctor-initializer contains the throw-expression.  */
   11246              : 
   11247              :   /* C++20 added move on throw of parms.  */
   11248         9082 :   if (TREE_CODE (retval) == PARM_DECL && cxx_dialect < cxx20)
   11249              :     return NULL_TREE;
   11250              : 
   11251              :   /* We don't check for lambda-expression here, because we should not get past
   11252              :      the DECL_HAS_VALUE_EXPR_P check above.  */
   11253         9069 :   for (cp_binding_level *b = current_binding_level;
   11254         9163 :        b->kind != sk_namespace; b = b->level_chain)
   11255              :     {
   11256         9161 :       for (tree decl = b->names; decl; decl = TREE_CHAIN (decl))
   11257          101 :         if (decl == retval)
   11258           89 :           return set_implicit_rvalue_p (move (expr));
   11259         9060 :       if (b->kind == sk_try)
   11260              :         return NULL_TREE;
   11261              :     }
   11262              : 
   11263           14 :   return set_implicit_rvalue_p (move (expr));
   11264              : }
   11265              : 
   11266              : /* Warn about dubious usage of std::move (in a return statement, if RETURN_P
   11267              :    is true).  EXPR is the std::move expression; TYPE is the type of the object
   11268              :    being initialized.  */
   11269              : 
   11270              : void
   11271    187526132 : maybe_warn_pessimizing_move (tree expr, tree type, bool return_p)
   11272              : {
   11273    187526132 :   if (!(warn_pessimizing_move || warn_redundant_move))
   11274              :     return;
   11275              : 
   11276      4510072 :   const location_t loc = cp_expr_loc_or_input_loc (expr);
   11277              : 
   11278              :   /* C++98 doesn't know move.  */
   11279      4510072 :   if (cxx_dialect < cxx11)
   11280              :     return;
   11281              : 
   11282              :   /* Wait until instantiation time, since we can't gauge if we should do
   11283              :      the NRVO until then.  */
   11284      4447641 :   if (processing_template_decl)
   11285              :     return;
   11286              : 
   11287              :   /* This is only interesting for class types.  */
   11288      4362577 :   if (!CLASS_TYPE_P (type))
   11289              :     return;
   11290              : 
   11291       104522 :   bool wrapped_p = false;
   11292              :   /* A a = std::move (A());  */
   11293       104522 :   if (TREE_CODE (expr) == TREE_LIST)
   11294              :     {
   11295         8586 :       if (list_length (expr) == 1)
   11296              :         {
   11297         5849 :           expr = TREE_VALUE (expr);
   11298         5849 :           wrapped_p = true;
   11299              :         }
   11300              :       else
   11301              :         return;
   11302              :     }
   11303              :   /* A a = {std::move (A())};
   11304              :      A a{std::move (A())};  */
   11305        95936 :   else if (TREE_CODE (expr) == CONSTRUCTOR)
   11306              :     {
   11307         6936 :       if (CONSTRUCTOR_NELTS (expr) == 1)
   11308              :         {
   11309          781 :           expr = CONSTRUCTOR_ELT (expr, 0)->value;
   11310          781 :           wrapped_p = true;
   11311              :         }
   11312              :       else
   11313              :         return;
   11314              :     }
   11315              : 
   11316              :   /* First, check if this is a call to std::move.  */
   11317         6943 :   if (!REFERENCE_REF_P (expr)
   11318       100637 :       || TREE_CODE (TREE_OPERAND (expr, 0)) != CALL_EXPR)
   11319              :     return;
   11320         3025 :   tree fn = TREE_OPERAND (expr, 0);
   11321         3025 :   if (!is_std_move_p (fn))
   11322              :     return;
   11323         2422 :   tree arg = CALL_EXPR_ARG (fn, 0);
   11324         2422 :   if (TREE_CODE (arg) != NOP_EXPR)
   11325              :     return;
   11326              :   /* If we're looking at *std::move<T&> ((T &) &arg), do the pessimizing N/RVO
   11327              :      and implicitly-movable warnings.  */
   11328         2422 :   if (TREE_CODE (TREE_OPERAND (arg, 0)) == ADDR_EXPR)
   11329              :     {
   11330         1783 :       arg = TREE_OPERAND (arg, 0);
   11331         1783 :       arg = TREE_OPERAND (arg, 0);
   11332         1783 :       arg = convert_from_reference (arg);
   11333         1783 :       if (can_elide_copy_prvalue_p (arg, type))
   11334              :         {
   11335          108 :           auto_diagnostic_group d;
   11336          108 :           if (warning_at (loc, OPT_Wpessimizing_move,
   11337              :                           "moving a temporary object prevents copy elision"))
   11338          108 :             inform (loc, "remove %<std::move%> call");
   11339          108 :         }
   11340              :       /* The rest of the warnings is only relevant for when we are returning
   11341              :          from a function.  */
   11342         1783 :       if (!return_p)
   11343              :         return;
   11344              : 
   11345          362 :       tree moved;
   11346              :       /* Warn if we could do copy elision were it not for the move.  */
   11347          362 :       if (can_do_nrvo_p (arg, type))
   11348              :         {
   11349           48 :           auto_diagnostic_group d;
   11350           48 :           if (!warning_suppressed_p (expr, OPT_Wpessimizing_move)
   11351           48 :               && warning_at (loc, OPT_Wpessimizing_move,
   11352              :                              "moving a local object in a return statement "
   11353              :                              "prevents copy elision"))
   11354           42 :             inform (loc, "remove %<std::move%> call");
   11355           48 :         }
   11356              :       /* Warn if the move is redundant.  It is redundant when we would
   11357              :          do maybe-rvalue overload resolution even without std::move.  */
   11358          314 :       else if (warn_redundant_move
   11359              :                /* This doesn't apply for return {std::move (t)};.  */
   11360          212 :                && !wrapped_p
   11361          209 :                && !warning_suppressed_p (expr, OPT_Wredundant_move)
   11362          410 :                && (moved = treat_lvalue_as_rvalue_p (arg, /*return*/true)))
   11363              :         {
   11364              :           /* Make sure that overload resolution would actually succeed
   11365              :              if we removed the std::move call.  */
   11366           54 :           tree t = convert_for_initialization (NULL_TREE, type,
   11367              :                                                moved,
   11368              :                                                (LOOKUP_NORMAL
   11369              :                                                 | LOOKUP_ONLYCONVERTING),
   11370              :                                                ICR_RETURN, NULL_TREE, 0,
   11371              :                                                tf_none);
   11372              :           /* If this worked, implicit rvalue would work, so the call to
   11373              :              std::move is redundant.  */
   11374           54 :           if (t != error_mark_node)
   11375              :             {
   11376           54 :               auto_diagnostic_group d;
   11377           54 :               if (warning_at (loc, OPT_Wredundant_move,
   11378              :                               "redundant move in return statement"))
   11379           54 :                 inform (loc, "remove %<std::move%> call");
   11380           54 :             }
   11381              :         }
   11382              :      }
   11383              :   /* Also try to warn about redundant std::move in code such as
   11384              :       T f (const T& t)
   11385              :       {
   11386              :         return std::move(t);
   11387              :       }
   11388              :     for which EXPR will be something like
   11389              :       *std::move<const T&> ((const struct T &) (const struct T *) t)
   11390              :      and where the std::move does nothing if T does not have a T(const T&&)
   11391              :      constructor, because the argument is const.  It will not use T(T&&)
   11392              :      because that would mean losing the const.  */
   11393          639 :   else if (warn_redundant_move
   11394          509 :            && !warning_suppressed_p (expr, OPT_Wredundant_move)
   11395           64 :            && TYPE_REF_P (TREE_TYPE (arg))
   11396          703 :            && CP_TYPE_CONST_P (TREE_TYPE (TREE_TYPE (arg))))
   11397              :     {
   11398           18 :       tree rtype = TREE_TYPE (TREE_TYPE (arg));
   11399           18 :       if (!same_type_ignoring_top_level_qualifiers_p (rtype, type))
   11400            9 :         return;
   11401              :       /* Check for the unlikely case there's T(const T&&) (we don't care if
   11402              :          it's deleted).  */
   11403           54 :       for (tree fn : ovl_range (CLASSTYPE_CONSTRUCTORS (rtype)))
   11404           30 :         if (move_fn_p (fn))
   11405              :           {
   11406           15 :             tree t = TREE_VALUE (FUNCTION_FIRST_USER_PARMTYPE (fn));
   11407           15 :             if (UNLIKELY (CP_TYPE_CONST_P (TREE_TYPE (t))))
   11408            6 :               return;
   11409              :           }
   11410            9 :       auto_diagnostic_group d;
   11411           18 :       if (return_p
   11412            9 :           ? warning_at (loc, OPT_Wredundant_move,
   11413              :                         "redundant move in return statement")
   11414            9 :           : warning_at (loc, OPT_Wredundant_move,
   11415              :                         "redundant move in initialization"))
   11416            9 :         inform (loc, "remove %<std::move%> call");
   11417            9 :     }
   11418              : }
   11419              : 
   11420              : /* Check that returning RETVAL from the current function is valid.
   11421              :    Return an expression explicitly showing all conversions required to
   11422              :    change RETVAL into the function return type, and to assign it to
   11423              :    the DECL_RESULT for the function.  Set *NO_WARNING to true if
   11424              :    code reaches end of non-void function warning shouldn't be issued
   11425              :    on this RETURN_EXPR.  Set *DANGLING to true if code returns the
   11426              :    address of a local variable.  */
   11427              : 
   11428              : tree
   11429    130587481 : check_return_expr (tree retval, bool *no_warning, bool *dangling)
   11430              : {
   11431    130587481 :   tree result;
   11432              :   /* The type actually returned by the function.  */
   11433    130587481 :   tree valtype;
   11434              :   /* The type the function is declared to return, or void if
   11435              :      the declared type is incomplete.  */
   11436    130587481 :   tree functype;
   11437    130587481 :   int fn_returns_value_p;
   11438    130587481 :   location_t loc = cp_expr_loc_or_input_loc (retval);
   11439              : 
   11440    130587481 :   *no_warning = false;
   11441    130587481 :   *dangling = false;
   11442              : 
   11443              :   /* A `volatile' function is one that isn't supposed to return, ever.
   11444              :      (This is a G++ extension, used to get better code for functions
   11445              :      that call the `volatile' function.)  */
   11446    130587481 :   if (TREE_THIS_VOLATILE (current_function_decl))
   11447           12 :     warning (0, "function declared %<noreturn%> has a %<return%> statement");
   11448              : 
   11449              :   /* Check for various simple errors.  */
   11450    261174962 :   if (DECL_DESTRUCTOR_P (current_function_decl))
   11451              :     {
   11452         2177 :       if (retval)
   11453            3 :         error_at (loc, "returning a value from a destructor");
   11454              : 
   11455         2177 :       if (targetm.cxx.cdtor_returns_this () && !processing_template_decl)
   11456            0 :         retval = current_class_ptr;
   11457              :       else
   11458              :         return NULL_TREE;
   11459              :     }
   11460    130585304 :   else if (DECL_CONSTRUCTOR_P (current_function_decl))
   11461              :     {
   11462        50902 :       if (in_function_try_handler)
   11463              :         /* If a return statement appears in a handler of the
   11464              :            function-try-block of a constructor, the program is ill-formed.  */
   11465            0 :         error ("cannot return from a handler of a function-try-block of a constructor");
   11466        50902 :       else if (retval)
   11467              :         /* You can't return a value from a constructor.  */
   11468            3 :         error_at (loc, "returning a value from a constructor");
   11469              : 
   11470        50902 :       if (targetm.cxx.cdtor_returns_this () && !processing_template_decl)
   11471            0 :         retval = current_class_ptr;
   11472              :       else
   11473              :         return NULL_TREE;
   11474              :     }
   11475              : 
   11476    130534402 :   const tree saved_retval = retval;
   11477              : 
   11478    130534402 :   if (processing_template_decl)
   11479              :     {
   11480     79691175 :       current_function_returns_value = 1;
   11481              : 
   11482     79691175 :       if (check_for_bare_parameter_packs (retval))
   11483           14 :         return error_mark_node;
   11484              : 
   11485              :       /* If one of the types might be void, we can't tell whether we're
   11486              :          returning a value.  */
   11487     79691161 :       if ((WILDCARD_TYPE_P (TREE_TYPE (DECL_RESULT (current_function_decl)))
   11488     33657826 :            && !FNDECL_USED_AUTO (current_function_decl))
   11489     46033344 :           || (retval != NULL_TREE
   11490     44927369 :               && (TREE_TYPE (retval) == NULL_TREE
   11491     31003775 :                   || WILDCARD_TYPE_P (TREE_TYPE (retval)))))
   11492     54131511 :         goto dependent;
   11493              :     }
   11494              : 
   11495     76402877 :   functype = TREE_TYPE (TREE_TYPE (current_function_decl));
   11496              : 
   11497              :   /* Deduce auto return type from a return statement.  */
   11498     76402877 :   if (FNDECL_USED_AUTO (current_function_decl))
   11499              :     {
   11500      2734368 :       tree pattern = DECL_SAVED_AUTO_RETURN_TYPE (current_function_decl);
   11501      2734368 :       tree auto_node;
   11502      2734368 :       tree type;
   11503              : 
   11504      2734368 :       if (!retval && !is_auto (pattern))
   11505              :         {
   11506              :           /* Give a helpful error message.  */
   11507            3 :           auto_diagnostic_group d;
   11508            3 :           error ("return-statement with no value, in function returning %qT",
   11509              :                  pattern);
   11510            3 :           inform (input_location, "only plain %<auto%> return type can be "
   11511              :                   "deduced to %<void%>");
   11512            3 :           type = error_mark_node;
   11513            3 :         }
   11514      2734365 :       else if (retval && BRACE_ENCLOSED_INITIALIZER_P (retval))
   11515              :         {
   11516            6 :           error ("returning initializer list");
   11517            6 :           type = error_mark_node;
   11518              :         }
   11519              :       else
   11520              :         {
   11521      2734359 :           if (!retval)
   11522        18446 :             retval = void_node;
   11523      2734359 :           auto_node = type_uses_auto (pattern);
   11524      2734359 :           type = do_auto_deduction (pattern, retval, auto_node,
   11525              :                                     tf_warning_or_error, adc_return_type);
   11526              :         }
   11527              : 
   11528      2734368 :       if (type == error_mark_node)
   11529              :         /* Leave it.  */;
   11530      2734154 :       else if (functype == pattern)
   11531      1575243 :         apply_deduced_return_type (current_function_decl, type);
   11532      1158911 :       else if (!same_type_p (type, functype))
   11533              :         {
   11534           24 :           if (LAMBDA_FUNCTION_P (current_function_decl))
   11535            6 :             error_at (loc, "inconsistent types %qT and %qT deduced for "
   11536              :                       "lambda return type", functype, type);
   11537              :           else
   11538           12 :             error_at (loc, "inconsistent deduction for auto return type: "
   11539              :                       "%qT and then %qT", functype, type);
   11540              :         }
   11541              :       functype = type;
   11542              :     }
   11543              : 
   11544     76402877 :   result = DECL_RESULT (current_function_decl);
   11545     76402877 :   valtype = TREE_TYPE (result);
   11546     76402877 :   gcc_assert (valtype != NULL_TREE);
   11547     76402877 :   fn_returns_value_p = !VOID_TYPE_P (valtype);
   11548              : 
   11549              :   /* Check for a return statement with no return value in a function
   11550              :      that's supposed to return a value.  */
   11551     76402877 :   if (!retval && fn_returns_value_p)
   11552              :     {
   11553           33 :       if (functype != error_mark_node)
   11554           30 :         permerror (input_location, "return-statement with no value, in "
   11555              :                    "function returning %qT", valtype);
   11556              :       /* Remember that this function did return.  */
   11557           33 :       current_function_returns_value = 1;
   11558              :       /* But suppress NRV  .*/
   11559           33 :       current_function_return_value = error_mark_node;
   11560              :       /* And signal caller that TREE_NO_WARNING should be set on the
   11561              :          RETURN_EXPR to avoid control reaches end of non-void function
   11562              :          warnings in tree-cfg.cc.  */
   11563           33 :       *no_warning = true;
   11564              :     }
   11565              :   /* Check for a return statement with a value in a function that
   11566              :      isn't supposed to return a value.  */
   11567     76402844 :   else if (retval && !fn_returns_value_p)
   11568              :     {
   11569       659790 :       if (VOID_TYPE_P (TREE_TYPE (retval)))
   11570              :         /* You can return a `void' value from a function of `void'
   11571              :            type.  In that case, we have to evaluate the expression for
   11572              :            its side-effects.  */
   11573       659755 :         finish_expr_stmt (retval);
   11574           35 :       else if (retval != error_mark_node)
   11575           32 :         permerror (loc, "return-statement with a value, in function "
   11576              :                    "returning %qT", valtype);
   11577       659790 :       current_function_returns_null = 1;
   11578              : 
   11579              :       /* There's really no value to return, after all.  */
   11580       659790 :       return NULL_TREE;
   11581              :     }
   11582     75743054 :   else if (!retval)
   11583              :     /* Remember that this function can sometimes return without a
   11584              :        value.  */
   11585      1738913 :     current_function_returns_null = 1;
   11586              :   else
   11587              :     /* Remember that this function did return a value.  */
   11588     74004141 :     current_function_returns_value = 1;
   11589              : 
   11590              :   /* Check for erroneous operands -- but after giving ourselves a
   11591              :      chance to provide an error about returning a value from a void
   11592              :      function.  */
   11593     75743087 :   if (error_operand_p (retval))
   11594              :     {
   11595          990 :       current_function_return_value = error_mark_node;
   11596          990 :       return error_mark_node;
   11597              :     }
   11598              : 
   11599              :   /* Only operator new(...) throw(), can return NULL [expr.new/13].  */
   11600    151484194 :   if (IDENTIFIER_NEW_OP_P (DECL_NAME (current_function_decl))
   11601        29792 :       && !TYPE_NOTHROW_P (TREE_TYPE (current_function_decl))
   11602         2298 :       && ! flag_check_new
   11603     75744386 :       && retval && null_ptr_cst_p (retval))
   11604           24 :     warning (0, "%<operator new%> must not return NULL unless it is "
   11605              :              "declared %<throw()%> (or %<-fcheck-new%> is in effect)");
   11606              : 
   11607              :   /* Effective C++ rule 15.  See also start_function.  */
   11608     75742097 :   if (warn_ecpp
   11609           42 :       && DECL_NAME (current_function_decl) == assign_op_identifier
   11610     75742127 :       && !type_dependent_expression_p (retval))
   11611              :     {
   11612           27 :       bool warn = true;
   11613              : 
   11614              :       /* The function return type must be a reference to the current
   11615              :         class.  */
   11616           27 :       if (TYPE_REF_P (valtype)
   11617           45 :           && same_type_ignoring_top_level_qualifiers_p
   11618           18 :               (TREE_TYPE (valtype), TREE_TYPE (current_class_ref)))
   11619              :         {
   11620              :           /* Returning '*this' is obviously OK.  */
   11621           18 :           if (retval == current_class_ref)
   11622              :             warn = false;
   11623              :           /* If we are calling a function whose return type is the same of
   11624              :              the current class reference, it is ok.  */
   11625            6 :           else if (INDIRECT_REF_P (retval)
   11626            6 :                    && TREE_CODE (TREE_OPERAND (retval, 0)) == CALL_EXPR)
   11627              :             warn = false;
   11628              :         }
   11629              : 
   11630              :       if (warn)
   11631            9 :         warning_at (loc, OPT_Weffc__,
   11632              :                     "%<operator=%> should return a reference to %<*this%>");
   11633              :     }
   11634              : 
   11635     75742097 :   if (dependent_type_p (functype)
   11636     75742097 :       || type_dependent_expression_p (retval))
   11637              :     {
   11638     69527202 :     dependent:
   11639              :       /* We should not have changed the return value.  */
   11640     69527202 :       gcc_assert (retval == saved_retval);
   11641              :       /* We don't know if this is an lvalue or rvalue use, but
   11642              :          either way we can mark it as read.  */
   11643     69527202 :       mark_exp_read (retval);
   11644     69527202 :       return retval;
   11645              :     }
   11646              : 
   11647              :   /* The fabled Named Return Value optimization, as per [class.copy]/15:
   11648              : 
   11649              :      [...]      For  a function with a class return type, if the expression
   11650              :      in the return statement is the name of a local  object,  and  the  cv-
   11651              :      unqualified  type  of  the  local  object  is the same as the function
   11652              :      return type, an implementation is permitted to omit creating the  tem-
   11653              :      porary  object  to  hold  the function return value [...]
   11654              : 
   11655              :      So, if this is a value-returning function that always returns the same
   11656              :      local variable, remember it.
   11657              : 
   11658              :      We choose the first suitable variable even if the function sometimes
   11659              :      returns something else, but only if the variable is out of scope at the
   11660              :      other return sites, or else we run the risk of clobbering the variable we
   11661              :      chose if the other returned expression uses the chosen variable somehow.
   11662              : 
   11663              :      We don't currently do this if the first return is a non-variable, as it
   11664              :      would be complicated to determine whether an NRV selected later was in
   11665              :      scope at the point of the earlier return.  We also don't currently support
   11666              :      multiple variables with non-overlapping scopes (53637).
   11667              : 
   11668              :      See finish_function and finalize_nrv for the rest of this optimization.  */
   11669     60346406 :   tree bare_retval = NULL_TREE;
   11670     60346406 :   if (retval)
   11671              :     {
   11672     58607475 :       retval = maybe_undo_parenthesized_ref (retval);
   11673     58607475 :       bare_retval = tree_strip_any_location_wrapper (retval);
   11674              :     }
   11675              : 
   11676     60346406 :   bool named_return_value_okay_p = want_nrvo_p (bare_retval, functype);
   11677     60346406 :   if (fn_returns_value_p && flag_elide_constructors
   11678     58607452 :       && current_function_return_value != bare_retval)
   11679              :     {
   11680     58569561 :       if (named_return_value_okay_p
   11681       292490 :           && current_function_return_value == NULL_TREE)
   11682       253749 :         current_function_return_value = bare_retval;
   11683     58315812 :       else if (current_function_return_value
   11684     12443324 :                && VAR_P (current_function_return_value)
   11685          200 :                && DECL_NAME (current_function_return_value)
   11686     58316012 :                && !decl_in_scope_p (current_function_return_value))
   11687              :         {
   11688              :           /* The earlier NRV is out of scope at this point, so it's safe to
   11689          130 :              leave it alone; the current return can't refer to it.  */;
   11690          130 :           if (named_return_value_okay_p
   11691          130 :               && !warning_suppressed_p (current_function_decl, OPT_Wnrvo))
   11692              :             {
   11693           11 :               warning (OPT_Wnrvo, "not eliding copy on return from %qD",
   11694              :                        bare_retval);
   11695           11 :               suppress_warning (current_function_decl, OPT_Wnrvo);
   11696              :             }
   11697              :         }
   11698              :       else
   11699              :         {
   11700     58315682 :           if ((named_return_value_okay_p
   11701     58276954 :                || (current_function_return_value
   11702     12404466 :                    && current_function_return_value != error_mark_node))
   11703     58315730 :               && !warning_suppressed_p (current_function_decl, OPT_Wnrvo))
   11704              :             {
   11705        38713 :               warning (OPT_Wnrvo, "not eliding copy on return in %qD",
   11706              :                        current_function_decl);
   11707        38713 :               suppress_warning (current_function_decl, OPT_Wnrvo);
   11708              :             }
   11709     58315682 :           current_function_return_value = error_mark_node;
   11710              :         }
   11711              :     }
   11712              : 
   11713              :   /* We don't need to do any conversions when there's nothing being
   11714              :      returned.  */
   11715     60346406 :   if (!retval)
   11716              :     return NULL_TREE;
   11717              : 
   11718     58607475 :   if (!named_return_value_okay_p)
   11719     58277094 :     maybe_warn_pessimizing_move (retval, functype, /*return_p*/true);
   11720              : 
   11721              :   /* Do any required conversions.  */
   11722    117214950 :   if (bare_retval == result || DECL_CONSTRUCTOR_P (current_function_decl))
   11723              :     /* No conversions are required.  */
   11724              :     ;
   11725              :   else
   11726              :     {
   11727     58607475 :       int flags = LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING;
   11728              : 
   11729              :       /* The functype's return type will have been set to void, if it
   11730              :          was an incomplete type.  Just treat this as 'return;' */
   11731     58607475 :       if (VOID_TYPE_P (functype))
   11732            6 :         return error_mark_node;
   11733              : 
   11734              :       /* Under C++11 [12.8/32 class.copy], a returned lvalue is sometimes
   11735              :          treated as an rvalue for the purposes of overload resolution to
   11736              :          favor move constructors over copy constructors.
   11737              : 
   11738              :          Note that these conditions are similar to, but not as strict as,
   11739              :          the conditions for the named return value optimization.  */
   11740     58607469 :       bool converted = false;
   11741     58607469 :       tree moved;
   11742              :       /* Until C++23, this was only interesting for class type, but in C++23,
   11743              :          we should do the below when we're converting from/to a class/reference
   11744              :          (a non-scalar type).  */
   11745     58607469 :         if ((cxx_dialect < cxx23
   11746     10359533 :              ? CLASS_TYPE_P (functype)
   11747      6435699 :              : !SCALAR_TYPE_P (functype) || !SCALAR_TYPE_P (TREE_TYPE (retval)))
   11748     70908440 :             && (moved = treat_lvalue_as_rvalue_p (retval, /*return*/true)))
   11749              :           /* In C++20 and earlier we treat the return value as an rvalue
   11750              :              that can bind to lvalue refs.  In C++23, such an expression is just
   11751              :              an xvalue (see reference_binding).  */
   11752              :           retval = moved;
   11753              : 
   11754              :       /* The call in a (lambda) thunk needs no conversions.  */
   11755     58607469 :       if (TREE_CODE (retval) == CALL_EXPR
   11756     58607469 :           && call_from_lambda_thunk_p (retval))
   11757              :         converted = true;
   11758              : 
   11759              :       /* Don't check copy-initialization for NRV in a coroutine ramp; we
   11760              :          implement this case as NRV, but it's specified as directly
   11761              :          initializing the return value from get_return_object().  */
   11762     58607469 :       if (DECL_RAMP_P (current_function_decl) && named_return_value_okay_p)
   11763              :         converted = true;
   11764              : 
   11765              :       /* First convert the value to the function's return type, then
   11766              :          to the type of return value's location to handle the
   11767              :          case that functype is smaller than the valtype.  */
   11768     58607220 :       if (!converted)
   11769     58544673 :         retval = convert_for_initialization
   11770     58544673 :           (NULL_TREE, functype, retval, flags, ICR_RETURN, NULL_TREE, 0,
   11771              :            tf_warning_or_error);
   11772     58607469 :       retval = convert (valtype, retval);
   11773              : 
   11774              :       /* If the conversion failed, treat this just like `return;'.  */
   11775     58607469 :       if (retval == error_mark_node)
   11776              :         {
   11777              :           /* And suppress NRV.  */
   11778          194 :           current_function_return_value = error_mark_node;
   11779          194 :           return retval;
   11780              :         }
   11781              :       /* We can't initialize a register from a AGGR_INIT_EXPR.  */
   11782     58607275 :       else if (! cfun->returns_struct
   11783     56211585 :                && TREE_CODE (retval) == TARGET_EXPR
   11784     66947651 :                && TREE_CODE (TARGET_EXPR_INITIAL (retval)) == AGGR_INIT_EXPR)
   11785      1691894 :         retval = build2 (COMPOUND_EXPR, TREE_TYPE (retval), retval,
   11786      1691894 :                          TARGET_EXPR_SLOT (retval));
   11787     56915381 :       else if (!processing_template_decl
   11788     47866772 :                && maybe_warn_about_returning_address_of_local (retval, loc)
   11789     56915562 :                && INDIRECT_TYPE_P (valtype))
   11790          166 :         *dangling = true;
   11791              :     }
   11792              : 
   11793     58607275 :   if (check_out_of_consteval_use (retval))
   11794              :     {
   11795            6 :       current_function_return_value = error_mark_node;
   11796            6 :       return error_mark_node;
   11797              :     }
   11798              : 
   11799              :   /* A naive attempt to reduce the number of -Wdangling-reference false
   11800              :      positives: if we know that this function can return a variable with
   11801              :      static storage duration rather than one of its parameters, suppress
   11802              :      the warning.  */
   11803     58607269 :   if (warn_dangling_reference
   11804       393273 :       && TYPE_REF_P (functype)
   11805        26223 :       && bare_retval
   11806        26223 :       && VAR_P (bare_retval)
   11807           50 :       && TREE_STATIC (bare_retval))
   11808           50 :     suppress_warning (current_function_decl, OPT_Wdangling_reference);
   11809              : 
   11810     58607269 :   if (processing_template_decl)
   11811              :     return saved_retval;
   11812              : 
   11813              :   /* Actually copy the value returned into the appropriate location.  */
   11814     49558661 :   if (retval && retval != result)
   11815     49558661 :     retval = cp_build_init_expr (result, retval);
   11816              : 
   11817     49558661 :   if (current_function_return_value == bare_retval)
   11818       291634 :     INIT_EXPR_NRV_P (retval) = true;
   11819              : 
   11820     49558661 :   if (tree set = maybe_set_retval_sentinel ())
   11821       171292 :     retval = build2 (COMPOUND_EXPR, void_type_node, retval, set);
   11822              : 
   11823              :   return retval;
   11824              : }
   11825              : 
   11826              : 
   11827              : /* Returns nonzero if the pointer-type FROM can be converted to the
   11828              :    pointer-type TO via a qualification conversion.  If CONSTP is -1,
   11829              :    then we return nonzero if the pointers are similar, and the
   11830              :    cv-qualification signature of FROM is a proper subset of that of TO.
   11831              : 
   11832              :    If CONSTP is positive, then all outer pointers have been
   11833              :    const-qualified.  */
   11834              : 
   11835              : static bool
   11836    255570832 : comp_ptr_ttypes_real (tree to, tree from, int constp)
   11837              : {
   11838    255570832 :   bool to_more_cv_qualified = false;
   11839    255570832 :   bool is_opaque_pointer = false;
   11840              : 
   11841       980091 :   for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from))
   11842              :     {
   11843    256550923 :       if (TREE_CODE (to) != TREE_CODE (from))
   11844              :         return false;
   11845              : 
   11846    165908863 :       if (TREE_CODE (from) == OFFSET_TYPE
   11847    165908863 :           && !same_type_p (TYPE_OFFSET_BASETYPE (from),
   11848              :                            TYPE_OFFSET_BASETYPE (to)))
   11849              :         return false;
   11850              : 
   11851              :       /* Const and volatile mean something different for function and
   11852              :          array types, so the usual checks are not appropriate.  We'll
   11853              :          check the array type elements in further iterations.  */
   11854    165908863 :       if (!FUNC_OR_METHOD_TYPE_P (to) && TREE_CODE (to) != ARRAY_TYPE)
   11855              :         {
   11856    165679199 :           if (!at_least_as_qualified_p (to, from))
   11857              :             return false;
   11858              : 
   11859    147849014 :           if (!at_least_as_qualified_p (from, to))
   11860              :             {
   11861    102332305 :               if (constp == 0)
   11862              :                 return false;
   11863              :               to_more_cv_qualified = true;
   11864              :             }
   11865              : 
   11866    147848751 :           if (constp > 0)
   11867    147844713 :             constp &= TYPE_READONLY (to);
   11868              :         }
   11869              : 
   11870    148078415 :       if (VECTOR_TYPE_P (to))
   11871         7120 :         is_opaque_pointer = vector_targets_convertible_p (to, from);
   11872              : 
   11873              :       /* P0388R4 allows a conversion from int[N] to int[] but not the
   11874              :          other way round.  When both arrays have bounds but they do
   11875              :          not match, then no conversion is possible.  */
   11876    148078415 :       if (TREE_CODE (to) == ARRAY_TYPE
   11877    148078415 :           && !comp_array_types (to, from, bounds_first, /*strict=*/false))
   11878              :         return false;
   11879              : 
   11880    148077862 :       if (!TYPE_PTR_P (to)
   11881              :           && !TYPE_PTRDATAMEM_P (to)
   11882              :           /* CWG 330 says we need to look through arrays.  */
   11883              :           && TREE_CODE (to) != ARRAY_TYPE)
   11884    147097771 :         return ((constp >= 0 || to_more_cv_qualified)
   11885    147097771 :                 && (is_opaque_pointer
   11886    147097241 :                     || same_type_ignoring_top_level_qualifiers_p (to, from)));
   11887              :     }
   11888              : }
   11889              : 
   11890              : /* When comparing, say, char ** to char const **, this function takes
   11891              :    the 'char *' and 'char const *'.  Do not pass non-pointer/reference
   11892              :    types to this function.  */
   11893              : 
   11894              : int
   11895    255570204 : comp_ptr_ttypes (tree to, tree from)
   11896              : {
   11897    255570204 :   return comp_ptr_ttypes_real (to, from, 1);
   11898              : }
   11899              : 
   11900              : /* Returns true iff FNTYPE is a non-class type that involves
   11901              :    error_mark_node.  We can get FUNCTION_TYPE with buried error_mark_node
   11902              :    if a parameter type is ill-formed.  */
   11903              : 
   11904              : bool
   11905       801638 : error_type_p (const_tree type)
   11906              : {
   11907       840795 :   tree t;
   11908              : 
   11909       840795 :   switch (TREE_CODE (type))
   11910              :     {
   11911              :     case ERROR_MARK:
   11912              :       return true;
   11913              : 
   11914        39068 :     case POINTER_TYPE:
   11915        39068 :     case REFERENCE_TYPE:
   11916        39068 :     case OFFSET_TYPE:
   11917        39068 :       return error_type_p (TREE_TYPE (type));
   11918              : 
   11919         2622 :     case FUNCTION_TYPE:
   11920         2622 :     case METHOD_TYPE:
   11921         2622 :       if (error_type_p (TREE_TYPE (type)))
   11922              :         return true;
   11923         6978 :       for (t = TYPE_ARG_TYPES (type); t; t = TREE_CHAIN (t))
   11924         4362 :         if (error_type_p (TREE_VALUE (t)))
   11925              :           return true;
   11926              :       return false;
   11927              : 
   11928       205573 :     case RECORD_TYPE:
   11929       205573 :       if (TYPE_PTRMEMFUNC_P (type))
   11930           89 :         return error_type_p (TYPE_PTRMEMFUNC_FN_TYPE (type));
   11931              :       return false;
   11932              : 
   11933              :     default:
   11934              :       return false;
   11935              :     }
   11936              : }
   11937              : 
   11938              : /* Returns true if to and from are (possibly multi-level) pointers to the same
   11939              :    type or inheritance-related types, regardless of cv-quals.  */
   11940              : 
   11941              : bool
   11942    181668444 : ptr_reasonably_similar (const_tree to, const_tree from)
   11943              : {
   11944         1207 :   for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from))
   11945              :     {
   11946              :       /* Any target type is similar enough to void.  */
   11947    181669651 :       if (VOID_TYPE_P (to))
   11948          997 :         return !error_type_p (from);
   11949    181668654 :       if (VOID_TYPE_P (from))
   11950       791779 :         return !error_type_p (to);
   11951              : 
   11952    180876875 :       if (TREE_CODE (to) != TREE_CODE (from))
   11953              :         return false;
   11954              : 
   11955     90853811 :       if (TREE_CODE (from) == OFFSET_TYPE
   11956     90853811 :           && comptypes (TYPE_OFFSET_BASETYPE (to),
   11957            3 :                         TYPE_OFFSET_BASETYPE (from),
   11958              :                         COMPARE_BASE | COMPARE_DERIVED))
   11959            3 :         continue;
   11960              : 
   11961     90853805 :       if (VECTOR_TYPE_P (to)
   11962     90853805 :           && vector_types_convertible_p (to, from, false))
   11963              :         return true;
   11964              : 
   11965     90853721 :       if (TREE_CODE (to) == INTEGER_TYPE
   11966     90853721 :           && TYPE_PRECISION (to) == TYPE_PRECISION (from))
   11967              :         return true;
   11968              : 
   11969     90682158 :       if (TREE_CODE (to) == FUNCTION_TYPE)
   11970          939 :         return !error_type_p (to) && !error_type_p (from);
   11971              : 
   11972     90681219 :       if (!TYPE_PTR_P (to))
   11973              :         {
   11974              :           /* When either type is incomplete avoid DERIVED_FROM_P,
   11975              :              which may call complete_type (c++/57942).  */
   11976     90680015 :           bool b = !COMPLETE_TYPE_P (to) || !COMPLETE_TYPE_P (from);
   11977              :           return comptypes
   11978     90680015 :             (TYPE_MAIN_VARIANT (to), TYPE_MAIN_VARIANT (from),
   11979     90680015 :              b ? COMPARE_STRICT : COMPARE_BASE | COMPARE_DERIVED);
   11980              :         }
   11981         1207 :     }
   11982              : }
   11983              : 
   11984              : /* Return true if TO and FROM (both of which are POINTER_TYPEs or
   11985              :    pointer-to-member types) are the same, ignoring cv-qualification at
   11986              :    all levels.  CB says how we should behave when comparing array bounds.  */
   11987              : 
   11988              : bool
   11989      1343037 : comp_ptr_ttypes_const (tree to, tree from, compare_bounds_t cb)
   11990              : {
   11991      1343037 :   bool is_opaque_pointer = false;
   11992              : 
   11993      1344932 :   for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from))
   11994              :     {
   11995      2687969 :       if (TREE_CODE (to) != TREE_CODE (from))
   11996              :         return false;
   11997              : 
   11998      2291101 :       if (TREE_CODE (from) == OFFSET_TYPE
   11999      2290097 :           && same_type_p (TYPE_OFFSET_BASETYPE (from),
   12000              :                           TYPE_OFFSET_BASETYPE (to)))
   12001         1004 :           continue;
   12002              : 
   12003      2289093 :       if (VECTOR_TYPE_P (to))
   12004         8669 :         is_opaque_pointer = vector_targets_convertible_p (to, from);
   12005              : 
   12006      2289093 :       if (TREE_CODE (to) == ARRAY_TYPE
   12007              :           /* Ignore cv-qualification, but if we see e.g. int[3] and int[4],
   12008              :              we must fail.  */
   12009      2289093 :           && !comp_array_types (to, from, cb, /*strict=*/false))
   12010              :         return false;
   12011              : 
   12012              :       /* CWG 330 says we need to look through arrays.  */
   12013      2287693 :       if (!TYPE_PTR_P (to) && TREE_CODE (to) != ARRAY_TYPE)
   12014       943765 :         return (is_opaque_pointer
   12015       943765 :                 || same_type_ignoring_top_level_qualifiers_p (to, from));
   12016              :     }
   12017              : }
   12018              : 
   12019              : /* Returns the type qualifiers for this type, including the qualifiers on the
   12020              :    elements for an array type.  */
   12021              : 
   12022              : int
   12023  71803214829 : cp_type_quals (const_tree type)
   12024              : {
   12025  71803214829 :   int quals;
   12026              :   /* This CONST_CAST is okay because strip_array_types returns its
   12027              :      argument unmodified and we assign it to a const_tree.  */
   12028  71803214829 :   type = strip_array_types (const_cast<tree> (type));
   12029  71803214829 :   if (type == error_mark_node
   12030              :       /* Quals on a FUNCTION_TYPE are memfn quals.  */
   12031  71747101312 :       || TREE_CODE (type) == FUNCTION_TYPE)
   12032              :     return TYPE_UNQUALIFIED;
   12033  71676832828 :   quals = TYPE_QUALS (type);
   12034              :   /* METHOD and REFERENCE_TYPEs should never have quals.  */
   12035  71676832828 :   gcc_assert ((TREE_CODE (type) != METHOD_TYPE
   12036              :                && !TYPE_REF_P (type))
   12037              :               || ((quals & (TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE))
   12038              :                   == TYPE_UNQUALIFIED));
   12039              :   return quals;
   12040              : }
   12041              : 
   12042              : /* Returns the function-ref-qualifier for TYPE */
   12043              : 
   12044              : cp_ref_qualifier
   12045   3974301297 : type_memfn_rqual (const_tree type)
   12046              : {
   12047   3974301297 :   gcc_assert (FUNC_OR_METHOD_TYPE_P (type));
   12048              : 
   12049   3974301297 :   if (!FUNCTION_REF_QUALIFIED (type))
   12050              :     return REF_QUAL_NONE;
   12051     30736899 :   else if (FUNCTION_RVALUE_QUALIFIED (type))
   12052              :     return REF_QUAL_RVALUE;
   12053              :   else
   12054     15250111 :     return REF_QUAL_LVALUE;
   12055              : }
   12056              : 
   12057              : /* Returns the function-cv-quals for TYPE, which must be a FUNCTION_TYPE or
   12058              :    METHOD_TYPE.  */
   12059              : 
   12060              : int
   12061   1111414087 : type_memfn_quals (const_tree type)
   12062              : {
   12063   1111414087 :   if (TREE_CODE (type) == FUNCTION_TYPE)
   12064    115944024 :     return TYPE_QUALS (type);
   12065    995470063 :   else if (TREE_CODE (type) == METHOD_TYPE)
   12066    995470063 :     return cp_type_quals (class_of_this_parm (type));
   12067              :   else
   12068            0 :     gcc_unreachable ();
   12069              : }
   12070              : 
   12071              : /* Returns the FUNCTION_TYPE TYPE with its function-cv-quals changed to
   12072              :    MEMFN_QUALS and its ref-qualifier to RQUAL. */
   12073              : 
   12074              : tree
   12075     79809122 : apply_memfn_quals (tree type, cp_cv_quals memfn_quals, cp_ref_qualifier rqual)
   12076              : {
   12077              :   /* Could handle METHOD_TYPE here if necessary.  */
   12078     79809122 :   gcc_assert (TREE_CODE (type) == FUNCTION_TYPE);
   12079     79809122 :   if (TYPE_QUALS (type) == memfn_quals
   12080     79809122 :       && type_memfn_rqual (type) == rqual)
   12081              :     return type;
   12082              : 
   12083              :   /* This should really have a different TYPE_MAIN_VARIANT, but that gets
   12084              :      complex.  */
   12085      1256841 :   tree result = build_qualified_type (type, memfn_quals);
   12086      1256841 :   return build_ref_qualified_type (result, rqual);
   12087              : }
   12088              : 
   12089              : /* Returns nonzero if TYPE is const or volatile.  */
   12090              : 
   12091              : bool
   12092   1412050295 : cv_qualified_p (const_tree type)
   12093              : {
   12094   1412050295 :   int quals = cp_type_quals (type);
   12095   1412050295 :   return (quals & (TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE)) != 0;
   12096              : }
   12097              : 
   12098              : /* Returns nonzero if the TYPE contains a mutable member.  */
   12099              : 
   12100              : bool
   12101    977780725 : cp_has_mutable_p (const_tree type)
   12102              : {
   12103              :   /* This CONST_CAST is okay because strip_array_types returns its
   12104              :      argument unmodified and we assign it to a const_tree.  */
   12105    977780725 :   type = strip_array_types (const_cast<tree> (type));
   12106              : 
   12107    977780725 :   return CLASS_TYPE_P (type) && CLASSTYPE_HAS_MUTABLE (type);
   12108              : }
   12109              : 
   12110              : /* Set TREE_READONLY and TREE_VOLATILE on DECL as indicated by the
   12111              :    TYPE_QUALS.  For a VAR_DECL, this may be an optimistic
   12112              :    approximation.  In particular, consider:
   12113              : 
   12114              :      int f();
   12115              :      struct S { int i; };
   12116              :      const S s = { f(); }
   12117              : 
   12118              :    Here, we will make "s" as TREE_READONLY (because it is declared
   12119              :    "const") -- only to reverse ourselves upon seeing that the
   12120              :    initializer is non-constant.  */
   12121              : 
   12122              : void
   12123   1057741785 : cp_apply_type_quals_to_decl (int type_quals, tree decl)
   12124              : {
   12125   1057741785 :   tree type = TREE_TYPE (decl);
   12126              : 
   12127   1057741785 :   if (type == error_mark_node)
   12128              :     return;
   12129              : 
   12130   1057741124 :   if (TREE_CODE (decl) == TYPE_DECL)
   12131              :     return;
   12132              : 
   12133    928445230 :   gcc_assert (!(TREE_CODE (type) == FUNCTION_TYPE
   12134              :                 && type_quals != TYPE_UNQUALIFIED));
   12135              : 
   12136              :   /* Avoid setting TREE_READONLY incorrectly.  */
   12137              :   /* We used to check TYPE_NEEDS_CONSTRUCTING here, but now a constexpr
   12138              :      constructor can produce constant init, so rely on cp_finish_decl to
   12139              :      clear TREE_READONLY if the variable has non-constant init.  */
   12140              : 
   12141              :   /* If the type has (or might have) a mutable component, that component
   12142              :      might be modified.  */
   12143    928445230 :   if (TYPE_HAS_MUTABLE_P (type) || !COMPLETE_TYPE_P (type))
   12144     87040977 :     type_quals &= ~TYPE_QUAL_CONST;
   12145              : 
   12146    928445230 :   c_apply_type_quals_to_decl (type_quals, decl);
   12147              : }
   12148              : 
   12149              : /* Subroutine of casts_away_constness.  Make T1 and T2 point at
   12150              :    exemplar types such that casting T1 to T2 is casting away constness
   12151              :    if and only if there is no implicit conversion from T1 to T2.  */
   12152              : 
   12153              : static void
   12154      1428425 : casts_away_constness_r (tree *t1, tree *t2, tsubst_flags_t complain)
   12155              : {
   12156      1428425 :   int quals1;
   12157      1428425 :   int quals2;
   12158              : 
   12159              :   /* [expr.const.cast]
   12160              : 
   12161              :      For multi-level pointer to members and multi-level mixed pointers
   12162              :      and pointers to members (conv.qual), the "member" aspect of a
   12163              :      pointer to member level is ignored when determining if a const
   12164              :      cv-qualifier has been cast away.  */
   12165              :   /* [expr.const.cast]
   12166              : 
   12167              :      For  two  pointer types:
   12168              : 
   12169              :             X1 is T1cv1,1 * ... cv1,N *   where T1 is not a pointer type
   12170              :             X2 is T2cv2,1 * ... cv2,M *   where T2 is not a pointer type
   12171              :             K is min(N,M)
   12172              : 
   12173              :      casting from X1 to X2 casts away constness if, for a non-pointer
   12174              :      type T there does not exist an implicit conversion (clause
   12175              :      _conv_) from:
   12176              : 
   12177              :             Tcv1,(N-K+1) * cv1,(N-K+2) * ... cv1,N *
   12178              : 
   12179              :      to
   12180              : 
   12181              :             Tcv2,(M-K+1) * cv2,(M-K+2) * ... cv2,M *.  */
   12182      1428425 :   if ((!TYPE_PTR_P (*t1) && !TYPE_PTRDATAMEM_P (*t1))
   12183       714563 :       || (!TYPE_PTR_P (*t2) && !TYPE_PTRDATAMEM_P (*t2)))
   12184              :     {
   12185       714040 :       *t1 = cp_build_qualified_type (void_type_node,
   12186              :                                      cp_type_quals (*t1));
   12187       714040 :       *t2 = cp_build_qualified_type (void_type_node,
   12188              :                                      cp_type_quals (*t2));
   12189       714040 :       return;
   12190              :     }
   12191              : 
   12192       714385 :   quals1 = cp_type_quals (*t1);
   12193       714385 :   quals2 = cp_type_quals (*t2);
   12194              : 
   12195       714385 :   if (TYPE_PTRDATAMEM_P (*t1))
   12196            0 :     *t1 = TYPE_PTRMEM_POINTED_TO_TYPE (*t1);
   12197              :   else
   12198       714385 :     *t1 = TREE_TYPE (*t1);
   12199       714385 :   if (TYPE_PTRDATAMEM_P (*t2))
   12200            0 :     *t2 = TYPE_PTRMEM_POINTED_TO_TYPE (*t2);
   12201              :   else
   12202       714385 :     *t2 = TREE_TYPE (*t2);
   12203              : 
   12204       714385 :   casts_away_constness_r (t1, t2, complain);
   12205       714385 :   *t1 = build_pointer_type (*t1);
   12206       714385 :   *t2 = build_pointer_type (*t2);
   12207       714385 :   *t1 = cp_build_qualified_type (*t1, quals1);
   12208       714385 :   *t2 = cp_build_qualified_type (*t2, quals2);
   12209              : }
   12210              : 
   12211              : /* Returns nonzero if casting from TYPE1 to TYPE2 casts away
   12212              :    constness.
   12213              : 
   12214              :    ??? This function returns non-zero if casting away qualifiers not
   12215              :    just const.  We would like to return to the caller exactly which
   12216              :    qualifiers are casted away to give more accurate diagnostics.
   12217              : */
   12218              : 
   12219              : static bool
   12220       714112 : casts_away_constness (tree t1, tree t2, tsubst_flags_t complain)
   12221              : {
   12222       714112 :   if (TYPE_REF_P (t2))
   12223              :     {
   12224              :       /* [expr.const.cast]
   12225              : 
   12226              :          Casting from an lvalue of type T1 to an lvalue of type T2
   12227              :          using a reference cast casts away constness if a cast from an
   12228              :          rvalue of type "pointer to T1" to the type "pointer to T2"
   12229              :          casts away constness.  */
   12230            0 :       t1 = (TYPE_REF_P (t1) ? TREE_TYPE (t1) : t1);
   12231            0 :       return casts_away_constness (build_pointer_type (t1),
   12232            0 :                                    build_pointer_type (TREE_TYPE (t2)),
   12233            0 :                                    complain);
   12234              :     }
   12235              : 
   12236       714112 :   if (TYPE_PTRDATAMEM_P (t1) && TYPE_PTRDATAMEM_P (t2))
   12237              :     /* [expr.const.cast]
   12238              : 
   12239              :        Casting from an rvalue of type "pointer to data member of X
   12240              :        of type T1" to the type "pointer to data member of Y of type
   12241              :        T2" casts away constness if a cast from an rvalue of type
   12242              :        "pointer to T1" to the type "pointer to T2" casts away
   12243              :        constness.  */
   12244           48 :     return casts_away_constness
   12245           48 :       (build_pointer_type (TYPE_PTRMEM_POINTED_TO_TYPE (t1)),
   12246           48 :        build_pointer_type (TYPE_PTRMEM_POINTED_TO_TYPE (t2)),
   12247           48 :        complain);
   12248              : 
   12249              :   /* Casting away constness is only something that makes sense for
   12250              :      pointer or reference types.  */
   12251       714064 :   if (!TYPE_PTR_P (t1) || !TYPE_PTR_P (t2))
   12252              :     return false;
   12253              : 
   12254              :   /* Top-level qualifiers don't matter.  */
   12255       714040 :   t1 = TYPE_MAIN_VARIANT (t1);
   12256       714040 :   t2 = TYPE_MAIN_VARIANT (t2);
   12257       714040 :   casts_away_constness_r (&t1, &t2, complain);
   12258       714040 :   if (!can_convert (t2, t1, complain))
   12259              :     return true;
   12260              : 
   12261              :   return false;
   12262              : }
   12263              : 
   12264              : /* If T is a REFERENCE_TYPE return the type to which T refers.
   12265              :    Otherwise, return T itself.  */
   12266              : 
   12267              : tree
   12268   5123473562 : non_reference (tree t)
   12269              : {
   12270   5123473562 :   if (t && TYPE_REF_P (t))
   12271    499476802 :     t = TREE_TYPE (t);
   12272   5123473562 :   return t;
   12273              : }
   12274              : 
   12275              : 
   12276              : /* Return nonzero if REF is an lvalue valid for this language;
   12277              :    otherwise, print an error message and return zero.  USE says
   12278              :    how the lvalue is being used and so selects the error message.  */
   12279              : 
   12280              : int
   12281     49270003 : lvalue_or_else (tree ref, enum lvalue_use use, tsubst_flags_t complain)
   12282              : {
   12283     49270003 :   cp_lvalue_kind kind = lvalue_kind (ref);
   12284              : 
   12285     49270003 :   if (kind == clk_none)
   12286              :     {
   12287          129 :       if (complain & tf_error)
   12288          121 :         lvalue_error (cp_expr_loc_or_input_loc (ref), use);
   12289          129 :       return 0;
   12290              :     }
   12291     49269874 :   else if (kind & (clk_rvalueref|clk_class))
   12292              :     {
   12293          140 :       if (!(complain & tf_error))
   12294              :         return 0;
   12295              :       /* Make this a permerror because we used to accept it.  */
   12296           18 :       permerror (cp_expr_loc_or_input_loc (ref),
   12297              :                  "using rvalue as lvalue");
   12298              :     }
   12299              :   return 1;
   12300              : }
   12301              : 
   12302              : /* Return true if a user-defined literal operator is a raw operator.  */
   12303              : 
   12304              : bool
   12305       111322 : check_raw_literal_operator (const_tree decl)
   12306              : {
   12307       111322 :   tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl));
   12308       111322 :   tree argtype;
   12309       111322 :   int arity;
   12310       111322 :   bool maybe_raw_p = false;
   12311              : 
   12312              :   /* Count the number and type of arguments and check for ellipsis.  */
   12313       111322 :   for (argtype = argtypes, arity = 0;
   12314       167000 :        argtype && argtype != void_list_node;
   12315        55678 :        ++arity, argtype = TREE_CHAIN (argtype))
   12316              :     {
   12317        55678 :       tree t = TREE_VALUE (argtype);
   12318              : 
   12319        55678 :       if (same_type_p (t, const_string_type_node))
   12320            9 :         maybe_raw_p = true;
   12321              :     }
   12322       111322 :   if (!argtype)
   12323              :     return false; /* Found ellipsis.  */
   12324              : 
   12325       111322 :   if (!maybe_raw_p || arity != 1)
   12326       111316 :     return false;
   12327              : 
   12328              :   return true;
   12329              : }
   12330              : 
   12331              : 
   12332              : /* Return true if a user-defined literal operator has one of the allowed
   12333              :    argument types.  */
   12334              : 
   12335              : bool
   12336       299122 : check_literal_operator_args (const_tree decl,
   12337              :                              bool *long_long_unsigned_p, bool *long_double_p)
   12338              : {
   12339       299122 :   tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl));
   12340              : 
   12341       299122 :   *long_long_unsigned_p = false;
   12342       299122 :   *long_double_p = false;
   12343       299122 :   if (processing_template_decl || processing_specialization)
   12344        55793 :     return argtypes == void_list_node;
   12345              :   else
   12346              :     {
   12347              :       tree argtype;
   12348              :       int arity;
   12349              :       int max_arity = 2;
   12350              : 
   12351              :       /* Count the number and type of arguments and check for ellipsis.  */
   12352       243220 :       for (argtype = argtypes, arity = 0;
   12353       486549 :            argtype && argtype != void_list_node;
   12354       243220 :            argtype = TREE_CHAIN (argtype))
   12355              :         {
   12356       243335 :           tree t = TREE_VALUE (argtype);
   12357       243335 :           ++arity;
   12358              : 
   12359       243335 :           if (TYPE_PTR_P (t))
   12360              :             {
   12361       115202 :               bool maybe_raw_p = false;
   12362       115202 :               t = TREE_TYPE (t);
   12363       115202 :               if (cp_type_quals (t) != TYPE_QUAL_CONST)
   12364              :                 return false;
   12365       115199 :               t = TYPE_MAIN_VARIANT (t);
   12366       115199 :               if ((maybe_raw_p = same_type_p (t, char_type_node))
   12367        91985 :                   || same_type_p (t, wchar_type_node)
   12368        68938 :                   || same_type_p (t, char8_type_node)
   12369        46106 :                   || same_type_p (t, char16_type_node)
   12370       138252 :                   || same_type_p (t, char32_type_node))
   12371              :                 {
   12372       115196 :                   argtype = TREE_CHAIN (argtype);
   12373       115196 :                   if (!argtype)
   12374              :                     return false;
   12375       115196 :                   t = TREE_VALUE (argtype);
   12376       115196 :                   if (maybe_raw_p && argtype == void_list_node)
   12377              :                     return true;
   12378       115108 :                   else if (same_type_p (t, size_type_node))
   12379              :                     {
   12380       115102 :                       ++arity;
   12381       115102 :                       continue;
   12382              :                     }
   12383              :                   else
   12384              :                     return false;
   12385              :                 }
   12386              :             }
   12387       128133 :           else if (same_type_p (t, long_long_unsigned_type_node))
   12388              :             {
   12389        45145 :               max_arity = 1;
   12390        45145 :               *long_long_unsigned_p = true;
   12391              :             }
   12392        82988 :           else if (same_type_p (t, long_double_type_node))
   12393              :             {
   12394        82888 :               max_arity = 1;
   12395        82888 :               *long_double_p = true;
   12396              :             }
   12397          100 :           else if (same_type_p (t, char_type_node))
   12398              :             max_arity = 1;
   12399           56 :           else if (same_type_p (t, wchar_type_node))
   12400              :             max_arity = 1;
   12401           45 :           else if (same_type_p (t, char8_type_node))
   12402              :             max_arity = 1;
   12403           40 :           else if (same_type_p (t, char16_type_node))
   12404              :             max_arity = 1;
   12405           29 :           else if (same_type_p (t, char32_type_node))
   12406              :             max_arity = 1;
   12407              :           else
   12408              :             return false;
   12409              :         }
   12410       243214 :       if (!argtype)
   12411              :         return false; /* Found ellipsis.  */
   12412              : 
   12413       243211 :       if (arity != max_arity)
   12414              :         return false;
   12415              : 
   12416              :       return true;
   12417              :     }
   12418              : }
   12419              : 
   12420              : /* Always returns false since unlike C90, C++ has no concept of implicit
   12421              :    function declarations.  */
   12422              : 
   12423              : bool
   12424          395 : c_decl_implicit (const_tree)
   12425              : {
   12426          395 :   return false;
   12427              : }
        

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.