LCOV - code coverage report
Current view: top level - gcc/c-family - c-warn.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 95.4 % 1736 1657
Test Date: 2026-02-28 14:20:25 Functions: 98.3 % 60 59
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Diagnostic routines shared by all languages that are variants of C.
       2              :    Copyright (C) 1992-2026 Free Software Foundation, Inc.
       3              : 
       4              : This file is part of GCC.
       5              : 
       6              : GCC is free software; you can redistribute it and/or modify it under
       7              : the terms of the GNU General Public License as published by the Free
       8              : Software Foundation; either version 3, or (at your option) any later
       9              : version.
      10              : 
      11              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      12              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      14              : for more details.
      15              : 
      16              : You should have received a copy of the GNU General Public License
      17              : along with GCC; see the file COPYING3.  If not see
      18              : <http://www.gnu.org/licenses/>.  */
      19              : 
      20              : #define INCLUDE_STRING
      21              : #include "config.h"
      22              : #include "system.h"
      23              : #include "coretypes.h"
      24              : #include "target.h"
      25              : #include "function.h"
      26              : #include "tree.h"
      27              : #include "c-common.h"
      28              : #include "memmodel.h"
      29              : #include "tm_p.h"
      30              : #include "diagnostic.h"
      31              : #include "intl.h"
      32              : #include "stringpool.h"
      33              : #include "attribs.h"
      34              : #include "asan.h"
      35              : #include "c-family/c-type-mismatch.h"
      36              : #include "gimplify.h"
      37              : #include "c-family/c-indentation.h"
      38              : #include "c-family/c-spellcheck.h"
      39              : #include "calls.h"
      40              : #include "stor-layout.h"
      41              : #include "tree-pretty-print.h"
      42              : #include "langhooks.h"
      43              : #include "gcc-urlifier.h"
      44              : 
      45              : /* Print a warning if a constant expression had overflow in folding.
      46              :    Invoke this function on every expression that the language
      47              :    requires to be a constant expression.
      48              :    Note the ANSI C standard says it is erroneous for a
      49              :    constant expression to overflow.  */
      50              : 
      51              : void
      52     13712109 : constant_expression_warning (tree value)
      53              : {
      54     13711430 :   if (warn_overflow && pedantic
      55       162397 :       && (TREE_CODE (value) == INTEGER_CST || TREE_CODE (value) == REAL_CST
      56         4575 :           || TREE_CODE (value) == FIXED_CST
      57         4575 :           || TREE_CODE (value) == VECTOR_CST
      58         4572 :           || TREE_CODE (value) == COMPLEX_CST)
      59     13871863 :       && TREE_OVERFLOW (value))
      60           47 :     pedwarn (input_location, OPT_Woverflow, "overflow in constant expression");
      61     13712109 : }
      62              : 
      63              : /* The same as above but print an unconditional error.  */
      64              : 
      65              : void
      66            0 : constant_expression_error (tree value)
      67              : {
      68            0 :   if ((TREE_CODE (value) == INTEGER_CST || TREE_CODE (value) == REAL_CST
      69            0 :        || TREE_CODE (value) == FIXED_CST
      70            0 :        || TREE_CODE (value) == VECTOR_CST
      71            0 :        || TREE_CODE (value) == COMPLEX_CST)
      72            0 :       && TREE_OVERFLOW (value))
      73            0 :     error ("overflow in constant expression");
      74            0 : }
      75              : 
      76              : /* Print a warning if an expression result VALUE had an overflow
      77              :    in folding and its operands hadn't.  EXPR, which may be null, is
      78              :    the operand of the expression.
      79              : 
      80              :    Invoke this function on every expression that
      81              :    (1) appears in the source code, and
      82              :    (2) is a constant expression that overflowed, and
      83              :    (3) is not already checked by convert_and_check;
      84              :    however, do not invoke this function on operands of explicit casts
      85              :    or when the expression is the result of an operator and any operand
      86              :    already overflowed.  */
      87              : 
      88              : void
      89          473 : overflow_warning (location_t loc, tree value, tree expr)
      90              : {
      91          473 :   if (c_inhibit_evaluation_warnings != 0)
      92              :     return;
      93              : 
      94          406 :   const char *warnfmt = NULL;
      95              : 
      96          406 :   switch (TREE_CODE (value))
      97              :     {
      98          406 :     case INTEGER_CST:
      99          406 :       warnfmt = (expr
     100          406 :                  ? G_("integer overflow in expression %qE of type %qT "
     101              :                       "results in %qE")
     102              :                  : G_("integer overflow in expression of type %qT "
     103              :                       "results in %qE"));
     104              :       break;
     105              : 
     106            0 :     case REAL_CST:
     107            0 :       warnfmt = (expr
     108            0 :                  ? G_("floating point overflow in expression %qE "
     109              :                       "of type %qT results in %qE")
     110              :                  : G_("floating point overflow in expression of type %qT "
     111              :                       "results in %qE"));
     112              :       break;
     113              : 
     114            0 :     case FIXED_CST:
     115            0 :       warnfmt = (expr
     116            0 :                  ? G_("fixed-point overflow in expression %qE of type %qT "
     117              :                       "results in %qE")
     118              :                  : G_("fixed-point overflow in expression of type %qT "
     119              :                       "results in %qE"));
     120              :       break;
     121              : 
     122            0 :     case VECTOR_CST:
     123            0 :       warnfmt = (expr
     124            0 :                  ? G_("vector overflow in expression %qE of type %qT "
     125              :                       "results in %qE")
     126              :                  : G_("vector overflow in expression of type %qT "
     127              :                       "results in %qE"));
     128              :       break;
     129              : 
     130            0 :     case COMPLEX_CST:
     131            0 :       if (TREE_CODE (TREE_REALPART (value)) == INTEGER_CST)
     132            0 :         warnfmt = (expr
     133            0 :                    ? G_("complex integer overflow in expression %qE "
     134              :                         "of type %qT results in %qE")
     135              :                    : G_("complex integer overflow in expression of type %qT "
     136              :                         "results in %qE"));
     137            0 :       else if (TREE_CODE (TREE_REALPART (value)) == REAL_CST)
     138            0 :         warnfmt = (expr
     139            0 :                    ? G_("complex floating point overflow in expression %qE "
     140              :                         "of type %qT results in %qE")
     141              :                    : G_("complex floating point overflow in expression "
     142              :                         "of type %qT results in %qE"));
     143              :       else
     144              :         return;
     145              :       break;
     146              : 
     147              :     default:
     148              :       return;
     149              :     }
     150              : 
     151              :   bool warned;
     152              :   if (expr)
     153           14 :     warned = warning_at (loc, OPT_Woverflow, warnfmt, expr, TREE_TYPE (expr),
     154              :                          value);
     155              :   else
     156          392 :     warned = warning_at (loc, OPT_Woverflow, warnfmt, TREE_TYPE (value),
     157              :                          value);
     158              : 
     159          405 :   if (warned)
     160          229 :     suppress_warning (value, OPT_Woverflow);
     161              : }
     162              : 
     163              : /* Helper function for walk_tree.  Unwrap C_MAYBE_CONST_EXPRs in an expression
     164              :    pointed to by TP.  */
     165              : 
     166              : static tree
     167         3197 : unwrap_c_maybe_const (tree *tp, int *walk_subtrees, void *)
     168              : {
     169         3197 :   if (TREE_CODE (*tp) == C_MAYBE_CONST_EXPR)
     170              :     {
     171          210 :       *tp = C_MAYBE_CONST_EXPR_EXPR (*tp);
     172              :       /* C_MAYBE_CONST_EXPRs don't nest.  */
     173          210 :       *walk_subtrees = false;
     174              :     }
     175         3197 :   return NULL_TREE;
     176              : }
     177              : 
     178              : /* Warn about uses of logical || / && operator in a context where it
     179              :    is likely that the bitwise equivalent was intended by the
     180              :    programmer.  We have seen an expression in which CODE is a binary
     181              :    operator used to combine expressions OP_LEFT and OP_RIGHT, which before folding
     182              :    had CODE_LEFT and CODE_RIGHT, into an expression of type TYPE.  */
     183              : 
     184              : void
     185      9190496 : warn_logical_operator (location_t location, enum tree_code code, tree type,
     186              :                        enum tree_code code_left, tree op_left,
     187              :                        enum tree_code ARG_UNUSED (code_right), tree op_right)
     188              : {
     189      9190496 :   int or_op = (code == TRUTH_ORIF_EXPR || code == TRUTH_OR_EXPR);
     190      9190496 :   int in0_p, in1_p, in_p;
     191      9190496 :   tree low0, low1, low, high0, high1, high, lhs, rhs, tem;
     192      9190496 :   bool strict_overflow_p = false;
     193              : 
     194      9190496 :   if (!warn_logical_op)
     195      9189991 :     return;
     196              : 
     197          850 :   if (code != TRUTH_ANDIF_EXPR
     198          850 :       && code != TRUTH_AND_EXPR
     199          460 :       && code != TRUTH_ORIF_EXPR
     200          460 :       && code != TRUTH_OR_EXPR)
     201              :     return;
     202              : 
     203              :   /* We don't want to warn if either operand comes from a macro
     204              :      expansion.  ??? This doesn't work with e.g. NEGATE_EXPR yet;
     205              :      see PR61534.  */
     206          692 :   if (from_macro_expansion_at (EXPR_LOCATION (op_left))
     207         1380 :       || from_macro_expansion_at (EXPR_LOCATION (op_right)))
     208            4 :     return;
     209              : 
     210              :   /* Warn if &&/|| are being used in a context where it is
     211              :      likely that the bitwise equivalent was intended by the
     212              :      programmer. That is, an expression such as op && MASK
     213              :      where op should not be any boolean expression, nor a
     214              :      constant, and mask seems to be a non-boolean integer constant.  */
     215          688 :   STRIP_ANY_LOCATION_WRAPPER (op_right);
     216          688 :   if (TREE_CODE (op_right) == CONST_DECL)
     217              :     /* An enumerator counts as a constant.  */
     218           18 :     op_right = DECL_INITIAL (op_right);
     219          688 :   tree stripped_op_left = tree_strip_any_location_wrapper (op_left);
     220          688 :   if (!truth_value_p (code_left)
     221          375 :       && INTEGRAL_TYPE_P (TREE_TYPE (op_left))
     222          369 :       && !CONSTANT_CLASS_P (stripped_op_left)
     223          283 :       && TREE_CODE (stripped_op_left) != CONST_DECL
     224          265 :       && !warning_suppressed_p (op_left, OPT_Wlogical_op)
     225          247 :       && TREE_CODE (op_right) == INTEGER_CST
     226           20 :       && !integer_zerop (op_right)
     227          708 :       && !integer_onep (op_right))
     228              :     {
     229           20 :       bool warned;
     230           20 :       if (or_op)
     231           10 :         warned
     232           10 :           = warning_at (location, OPT_Wlogical_op,
     233              :                         "logical %<or%> applied to non-boolean constant");
     234              :       else
     235           10 :         warned
     236           10 :           = warning_at (location, OPT_Wlogical_op,
     237              :                         "logical %<and%> applied to non-boolean constant");
     238           20 :       if (warned)
     239           20 :         suppress_warning (op_left, OPT_Wlogical_op);
     240           20 :       return;
     241              :     }
     242              : 
     243              :   /* We do not warn for constants because they are typical of macro
     244              :      expansions that test for features.  */
     245          668 :   if (CONSTANT_CLASS_P (fold_for_warn (op_left))
     246          668 :       || CONSTANT_CLASS_P (fold_for_warn (op_right)))
     247          153 :     return;
     248              : 
     249              :   /* This warning only makes sense with logical operands.  */
     250          695 :   if (!(truth_value_p (TREE_CODE (op_left))
     251          180 :         || INTEGRAL_TYPE_P (TREE_TYPE (op_left)))
     252          689 :       || !(truth_value_p (TREE_CODE (op_right))
     253          229 :            || INTEGRAL_TYPE_P (TREE_TYPE (op_right))))
     254              :     return;
     255              : 
     256              :   /* The range computations only work with scalars.  */
     257          509 :   if (VECTOR_TYPE_P (TREE_TYPE (op_left))
     258          509 :       || VECTOR_TYPE_P (TREE_TYPE (op_right)))
     259              :     return;
     260              : 
     261              :   /* We first test whether either side separately is trivially true
     262              :      (with OR) or trivially false (with AND).  If so, do not warn.
     263              :      This is a common idiom for testing ranges of data types in
     264              :      portable code.  */
     265          509 :   op_left = unshare_expr (op_left);
     266          509 :   walk_tree_without_duplicates (&op_left, unwrap_c_maybe_const, NULL);
     267          509 :   lhs = make_range (op_left, &in0_p, &low0, &high0, &strict_overflow_p);
     268          509 :   if (!lhs)
     269              :     return;
     270              : 
     271              :   /* If this is an OR operation, invert both sides; now, the result
     272              :      should be always false to get a warning.  */
     273          507 :   if (or_op)
     274          222 :     in0_p = !in0_p;
     275              : 
     276          507 :   tem = build_range_check (UNKNOWN_LOCATION, type, lhs, in0_p, low0, high0);
     277          507 :   if (tem && integer_zerop (tem))
     278              :     return;
     279              : 
     280          505 :   op_right = unshare_expr (op_right);
     281          505 :   walk_tree_without_duplicates (&op_right, unwrap_c_maybe_const, NULL);
     282          505 :   rhs = make_range (op_right, &in1_p, &low1, &high1, &strict_overflow_p);
     283          505 :   if (!rhs)
     284              :     return;
     285              : 
     286              :   /* If this is an OR operation, invert both sides; now, the result
     287              :      should be always false to get a warning.  */
     288          505 :   if (or_op)
     289          222 :     in1_p = !in1_p;
     290              : 
     291          505 :   tem = build_range_check (UNKNOWN_LOCATION, type, rhs, in1_p, low1, high1);
     292          505 :   if (tem && integer_zerop (tem))
     293              :     return;
     294              : 
     295              :   /* If both expressions have the same operand, if we can merge the
     296              :      ranges, ...  */
     297          505 :   if (operand_equal_p (lhs, rhs, 0)
     298          505 :       && merge_ranges (&in_p, &low, &high, in0_p, low0, high0,
     299              :                        in1_p, low1, high1))
     300              :     {
     301          351 :       tem = build_range_check (UNKNOWN_LOCATION, type, lhs, in_p, low, high);
     302              :       /* ... and if the range test is always false, then warn.  */
     303          351 :       if (tem && integer_zerop (tem))
     304              :         {
     305          147 :           if (or_op)
     306           49 :             warning_at (location, OPT_Wlogical_op,
     307              :                         "logical %<or%> of collectively exhaustive tests is "
     308              :                         "always true");
     309              :           else
     310           98 :             warning_at (location, OPT_Wlogical_op,
     311              :                         "logical %<and%> of mutually exclusive tests is "
     312              :                         "always false");
     313              :         }
     314              :       /* Or warn if the operands have exactly the same range, e.g.
     315              :          A > 0 && A > 0.  */
     316          204 :       else if (tree_int_cst_equal (low0, low1)
     317          204 :                && tree_int_cst_equal (high0, high1))
     318              :         {
     319          184 :           if (or_op)
     320           92 :             warning_at (location, OPT_Wlogical_op,
     321              :                         "logical %<or%> of equal expressions");
     322              :           else
     323           92 :             warning_at (location, OPT_Wlogical_op,
     324              :                         "logical %<and%> of equal expressions");
     325              :         }
     326              :     }
     327              : }
     328              : 
     329              : /* Helper function for warn_tautological_cmp.  Look for ARRAY_REFs
     330              :    with constant indices.  */
     331              : 
     332              : static tree
     333          226 : find_array_ref_with_const_idx_r (tree *expr_p, int *, void *)
     334              : {
     335          226 :   tree expr = *expr_p;
     336              : 
     337          226 :   if ((TREE_CODE (expr) == ARRAY_REF
     338          226 :        || TREE_CODE (expr) == ARRAY_RANGE_REF)
     339          226 :       && (TREE_CODE (fold_for_warn (TREE_OPERAND (expr, 1)))
     340              :           == INTEGER_CST))
     341           32 :     return integer_type_node;
     342              : 
     343              :   return NULL_TREE;
     344              : }
     345              : 
     346              : /* Subroutine of warn_tautological_cmp.  Warn about bitwise comparison
     347              :    that always evaluate to true or false.  LOC is the location of the
     348              :    ==/!= comparison specified by CODE; LHS and RHS are the usual operands
     349              :    of this comparison.  */
     350              : 
     351              : static void
     352       449262 : warn_tautological_bitwise_comparison (const op_location_t &loc, tree_code code,
     353              :                                       tree lhs, tree rhs)
     354              : {
     355       449262 :   if (code != EQ_EXPR && code != NE_EXPR)
     356       449122 :     return;
     357              : 
     358              :   /* Extract the operands from e.g. (x & 8) == 4.  */
     359       236831 :   tree bitop;
     360       236831 :   tree cst;
     361       236831 :   tree stripped_lhs = tree_strip_any_location_wrapper (lhs);
     362       236831 :   tree stripped_rhs = tree_strip_any_location_wrapper (rhs);
     363       236831 :   if ((TREE_CODE (lhs) == BIT_AND_EXPR
     364       224406 :        || TREE_CODE (lhs) == BIT_IOR_EXPR)
     365        12480 :       && TREE_CODE (stripped_rhs) == INTEGER_CST)
     366              :     bitop = lhs, cst = stripped_rhs;
     367       224797 :   else if ((TREE_CODE (rhs) == BIT_AND_EXPR
     368       224631 :             || TREE_CODE (rhs) == BIT_IOR_EXPR)
     369          200 :            && TREE_CODE (stripped_lhs) == INTEGER_CST)
     370              :     bitop = rhs, cst = stripped_lhs;
     371              :   else
     372              :     return;
     373              : 
     374        12106 :   tree bitopcst;
     375        12106 :   tree bitop_op0 = fold_for_warn (TREE_OPERAND (bitop, 0));
     376        12106 :   if (TREE_CODE (bitop_op0) == INTEGER_CST)
     377              :     bitopcst = bitop_op0;
     378              :   else {
     379        12022 :     tree bitop_op1 = fold_for_warn (TREE_OPERAND (bitop, 1));
     380        12022 :     if (TREE_CODE (bitop_op1) == INTEGER_CST)
     381              :       bitopcst = bitop_op1;
     382              :     else
     383              :       return;
     384              :   }
     385              : 
     386              :   /* Note that the two operands are from before the usual integer
     387              :      conversions, so their types might not be the same.
     388              :      Use the larger of the two precisions and ignore bits outside
     389              :      of that.  */
     390        10454 :   int prec = MAX (TYPE_PRECISION (TREE_TYPE (cst)),
     391              :                   TYPE_PRECISION (TREE_TYPE (bitopcst)));
     392              : 
     393        10454 :   wide_int bitopcstw = wi::to_wide (bitopcst, prec);
     394        10454 :   wide_int cstw = wi::to_wide (cst, prec);
     395              : 
     396        10454 :   wide_int res;
     397        10454 :   if (TREE_CODE (bitop) == BIT_AND_EXPR)
     398        10382 :     res = bitopcstw & cstw;
     399              :   else
     400           72 :     res = bitopcstw | cstw;
     401              : 
     402              :   /* For BIT_AND only warn if (CST2 & CST1) != CST1, and
     403              :      for BIT_OR only if (CST2 | CST1) != CST1.  */
     404        10454 :   if (res == cstw)
     405        10314 :     return;
     406              : 
     407          140 :   binary_op_rich_location richloc (loc, lhs, rhs, false);
     408          140 :   if (code == EQ_EXPR)
     409           76 :     warning_at (&richloc, OPT_Wtautological_compare,
     410              :                 "bitwise comparison always evaluates to false");
     411              :   else
     412           64 :     warning_at (&richloc, OPT_Wtautological_compare,
     413              :                 "bitwise comparison always evaluates to true");
     414        10454 : }
     415              : 
     416              : /* Given LOC from a macro expansion, return the map for the outermost
     417              :    macro in the nest of expansions.  */
     418              : 
     419              : static const line_map_macro *
     420          996 : get_outermost_macro_expansion (location_t loc)
     421              : {
     422          996 :   gcc_assert (from_macro_expansion_at (loc));
     423              : 
     424          996 :   const line_map *map = linemap_lookup (line_table, loc);
     425         1451 :   const line_map_macro *macro_map;
     426         1451 :   do
     427              :     {
     428         1451 :       macro_map = linemap_check_macro (map);
     429         1451 :       loc = linemap_unwind_toward_expansion (line_table, loc, &map);
     430         1451 :     } while (linemap_macro_expansion_map_p (map));
     431              : 
     432          996 :   return macro_map;
     433              : }
     434              : 
     435              : /* Given LOC_A and LOC_B from macro expansions, return true if
     436              :    they are "spelled the same" i.e. if they are both directly from
     437              :    expansion of the same non-function-like macro.  */
     438              : 
     439              : static bool
     440          498 : spelled_the_same_p (location_t loc_a, location_t loc_b)
     441              : {
     442          498 :   gcc_assert (from_macro_expansion_at (loc_a));
     443          498 :   gcc_assert (from_macro_expansion_at (loc_b));
     444              : 
     445          498 :   const line_map_macro *map_a = get_outermost_macro_expansion (loc_a);
     446          498 :   const line_map_macro *map_b = get_outermost_macro_expansion (loc_b);
     447              : 
     448          498 :   if (map_a->macro == map_b->macro)
     449           37 :     if (!cpp_fun_like_macro_p (map_a->macro))
     450           21 :       return true;
     451              : 
     452              :   return false;
     453              : }
     454              : 
     455              : /* Warn if a self-comparison always evaluates to true or false.  LOC
     456              :    is the location of the comparison with code CODE, LHS and RHS are
     457              :    operands of the comparison.  */
     458              : 
     459              : void
     460      2429570 : warn_tautological_cmp (const op_location_t &loc, enum tree_code code,
     461              :                        tree lhs, tree rhs)
     462              : {
     463      2429570 :   if (TREE_CODE_CLASS (code) != tcc_comparison)
     464              :     return;
     465              : 
     466              :   /* Don't warn for various macro expansions.  */
     467       747397 :   if (from_macro_expansion_at (loc))
     468              :     return;
     469       466004 :   bool lhs_in_macro = from_macro_expansion_at (EXPR_LOCATION (lhs));
     470       466004 :   bool rhs_in_macro = from_macro_expansion_at (EXPR_LOCATION (rhs));
     471       466004 :   if (lhs_in_macro || rhs_in_macro)
     472              :     {
     473              :       /* Don't warn if exactly one is from a macro.  */
     474        16763 :       if (!(lhs_in_macro && rhs_in_macro))
     475              :         return;
     476              : 
     477              :       /* If both are in a macro, only warn if they're spelled the same.  */
     478          498 :       if (!spelled_the_same_p (EXPR_LOCATION (lhs), EXPR_LOCATION (rhs)))
     479              :         return;
     480              :     }
     481              : 
     482       449262 :   warn_tautological_bitwise_comparison (loc, code, lhs, rhs);
     483              : 
     484              :   /* We do not warn for constants because they are typical of macro
     485              :      expansions that test for features, sizeof, and similar.  */
     486       449262 :   if (CONSTANT_CLASS_P (fold_for_warn (lhs))
     487       449262 :       || CONSTANT_CLASS_P (fold_for_warn (rhs)))
     488       259190 :     return;
     489              : 
     490              :   /* Don't warn for e.g.
     491              :      HOST_WIDE_INT n;
     492              :      ...
     493              :      if (n == (long) n) ...
     494              :    */
     495       190072 :   if ((CONVERT_EXPR_P (lhs) || TREE_CODE (lhs) == NON_LVALUE_EXPR)
     496       185914 :       || (CONVERT_EXPR_P (rhs) || TREE_CODE (rhs) == NON_LVALUE_EXPR))
     497              :     return;
     498              : 
     499              :   /* Don't warn if either LHS or RHS has an IEEE floating-point type.
     500              :      It could be a NaN, and NaN never compares equal to anything, even
     501              :      itself.  */
     502       156771 :   if (FLOAT_TYPE_P (TREE_TYPE (lhs)) || FLOAT_TYPE_P (TREE_TYPE (rhs)))
     503              :     return;
     504              : 
     505       155183 :   if (operand_equal_p (lhs, rhs, 0))
     506              :     {
     507              :       /* Don't warn about array references with constant indices;
     508              :          these are likely to come from a macro.  */
     509          104 :       if (walk_tree_without_duplicates (&lhs, find_array_ref_with_const_idx_r,
     510              :                                         NULL))
     511           32 :         return;
     512           72 :       const bool always_true = (code == EQ_EXPR || code == LE_EXPR
     513              :                                 || code == GE_EXPR || code == UNLE_EXPR
     514              :                                 || code == UNGE_EXPR || code == UNEQ_EXPR);
     515           72 :       binary_op_rich_location richloc (loc, lhs, rhs, false);
     516           72 :       if (always_true)
     517           49 :         warning_at (&richloc, OPT_Wtautological_compare,
     518              :                     "self-comparison always evaluates to true");
     519              :       else
     520           23 :         warning_at (&richloc, OPT_Wtautological_compare,
     521              :                     "self-comparison always evaluates to false");
     522           72 :     }
     523              : }
     524              : 
     525              : /* Return true iff EXPR only contains boolean operands, or comparisons.  */
     526              : 
     527              : static bool
     528          449 : expr_has_boolean_operands_p (tree expr)
     529              : {
     530          481 :   STRIP_NOPS (expr);
     531              : 
     532          481 :   if (CONVERT_EXPR_P (expr))
     533          100 :     return bool_promoted_to_int_p (expr);
     534          381 :   else if (UNARY_CLASS_P (expr))
     535           32 :     return expr_has_boolean_operands_p (TREE_OPERAND (expr, 0));
     536          349 :   else if (BINARY_CLASS_P (expr))
     537           68 :     return (expr_has_boolean_operands_p (TREE_OPERAND (expr, 0))
     538           68 :             && expr_has_boolean_operands_p (TREE_OPERAND (expr, 1)));
     539          281 :   else if (COMPARISON_CLASS_P (expr))
     540              :     return true;
     541              :   else
     542              :     return false;
     543              : }
     544              : 
     545              : /* Warn about logical not used on the left hand side operand of a comparison.
     546              :    This function assumes that the LHS is inside of TRUTH_NOT_EXPR.
     547              :    Do not warn if RHS is of a boolean type, a logical operator, or
     548              :    a comparison.  */
     549              : 
     550              : void
     551          367 : warn_logical_not_parentheses (location_t location, enum tree_code code,
     552              :                               tree lhs, tree rhs)
     553              : {
     554          367 :   if (TREE_CODE_CLASS (code) != tcc_comparison
     555          367 :       || TREE_TYPE (rhs) == NULL_TREE
     556          367 :       || TREE_CODE (TREE_TYPE (rhs)) == BOOLEAN_TYPE
     557          701 :       || truth_value_p (TREE_CODE (rhs)))
     558          110 :     return;
     559              : 
     560              :   /* Don't warn for expression like !x == ~(bool1 | bool2).  */
     561          325 :   if (expr_has_boolean_operands_p (rhs))
     562              :     return;
     563              : 
     564              :   /* Don't warn for !x == 0 or !y != 0, those are equivalent to
     565              :      !(x == 0) or !(y != 0).  */
     566          273 :   if ((code == EQ_EXPR || code == NE_EXPR)
     567          273 :       && integer_zerop (rhs))
     568              :     return;
     569              : 
     570          257 :   auto_diagnostic_group d;
     571          290 :   if (warning_at (location, OPT_Wlogical_not_parentheses,
     572              :                   "logical not is only applied to the left hand side of "
     573              :                   "comparison")
     574          257 :       && EXPR_HAS_LOCATION (lhs))
     575              :     {
     576          224 :       location_t lhs_loc = EXPR_LOCATION (lhs);
     577          224 :       rich_location richloc (line_table, lhs_loc);
     578          224 :       richloc.add_fixit_insert_before (lhs_loc, "(");
     579          224 :       richloc.add_fixit_insert_after (lhs_loc, ")");
     580          224 :       inform (&richloc, "add parentheses around left hand side "
     581              :               "expression to silence this warning");
     582          224 :     }
     583          257 : }
     584              : 
     585              : /* Warn if EXP contains any computations whose results are not used.
     586              :    Return true if a warning is printed; false otherwise.  LOCUS is the
     587              :    (potential) location of the expression.  */
     588              : 
     589              : bool
     590      1607389 : warn_if_unused_value (const_tree exp, location_t locus, bool quiet)
     591              : {
     592      1607435 :  restart:
     593      1607435 :   if (TREE_USED (exp) || warning_suppressed_p (exp, OPT_Wunused_value))
     594         5792 :     return false;
     595              : 
     596              :   /* Don't warn about void constructs.  This includes casting to void,
     597              :      void function calls, and statement expressions with a final cast
     598              :      to void.  */
     599      1601643 :   if (VOID_TYPE_P (TREE_TYPE (exp)))
     600              :     return false;
     601              : 
     602       950964 :   if (EXPR_HAS_LOCATION (exp))
     603       950923 :     locus = EXPR_LOCATION (exp);
     604              : 
     605       950964 :   switch (TREE_CODE (exp))
     606              :     {
     607              :     case PREINCREMENT_EXPR:
     608              :     case POSTINCREMENT_EXPR:
     609              :     case PREDECREMENT_EXPR:
     610              :     case POSTDECREMENT_EXPR:
     611              :     case MODIFY_EXPR:
     612              :     case INIT_EXPR:
     613              :     case TARGET_EXPR:
     614              :     case CALL_EXPR:
     615              :     case TRY_CATCH_EXPR:
     616              :     case EXIT_EXPR:
     617              :     case VA_ARG_EXPR:
     618              :       return false;
     619              : 
     620            0 :     case BIND_EXPR:
     621              :       /* For a binding, warn if no side effect within it.  */
     622            0 :       exp = BIND_EXPR_BODY (exp);
     623            0 :       goto restart;
     624              : 
     625            5 :     case SAVE_EXPR:
     626            5 :     case NON_LVALUE_EXPR:
     627            5 :     case NOP_EXPR:
     628            5 :       exp = TREE_OPERAND (exp, 0);
     629            5 :       goto restart;
     630              : 
     631           41 :     case TRUTH_ORIF_EXPR:
     632           41 :     case TRUTH_ANDIF_EXPR:
     633              :       /* In && or ||, warn if 2nd operand has no side effect.  */
     634           41 :       exp = TREE_OPERAND (exp, 1);
     635           41 :       goto restart;
     636              : 
     637           41 :     case COMPOUND_EXPR:
     638           41 :       if (warn_if_unused_value (TREE_OPERAND (exp, 0), locus, quiet))
     639              :         return true;
     640              :       /* Let people do `(foo (), 0)' without a warning.  */
     641           41 :       if (TREE_CONSTANT (TREE_OPERAND (exp, 1)))
     642              :         return false;
     643            0 :       exp = TREE_OPERAND (exp, 1);
     644            0 :       goto restart;
     645              : 
     646           64 :     case COND_EXPR:
     647              :       /* If this is an expression with side effects, don't warn; this
     648              :          case commonly appears in macro expansions.  */
     649           64 :       if (TREE_SIDE_EFFECTS (exp))
     650              :         return false;
     651            0 :       goto warn;
     652              : 
     653           36 :     case COMPLEX_EXPR:
     654              :       /* Warn only if both operands are unused.  */
     655           36 :       if (warn_if_unused_value (TREE_OPERAND (exp, 0), locus, true)
     656           36 :           && warn_if_unused_value (TREE_OPERAND (exp, 1), locus, true))
     657           16 :         goto warn;
     658              :       return false;
     659              : 
     660            2 :     case INDIRECT_REF:
     661              :       /* Don't warn about automatic dereferencing of references, since
     662              :          the user cannot control it.  */
     663            2 :       if (TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == REFERENCE_TYPE)
     664              :         {
     665            0 :           exp = TREE_OPERAND (exp, 0);
     666            0 :           goto restart;
     667              :         }
     668              :       /* Fall through.  */
     669              : 
     670          104 :     default:
     671              :       /* Referencing a volatile value is a side effect, so don't warn.  */
     672          104 :       if ((DECL_P (exp) || REFERENCE_CLASS_P (exp))
     673           18 :           && TREE_THIS_VOLATILE (exp))
     674              :         return false;
     675              : 
     676              :       /* If this is an expression which has no operands, there is no value
     677              :          to be unused.  There are no such language-independent codes,
     678              :          but front ends may define such.  */
     679          104 :       if (EXPRESSION_CLASS_P (exp) && TREE_OPERAND_LENGTH (exp) == 0)
     680              :         return false;
     681              : 
     682          120 :     warn:
     683          120 :       if (quiet)
     684              :         return true;
     685           88 :       return warning_at (locus, OPT_Wunused_value, "value computed is not used");
     686              :     }
     687              : }
     688              : 
     689              : /* Print a warning about casts that might indicate violation of strict
     690              :    aliasing rules if -Wstrict-aliasing is used and strict aliasing
     691              :    mode is in effect.  LOC is the location of the expression being
     692              :    cast, EXPR might be from inside it.  TYPE is the type we're casting
     693              :    to.  */
     694              : 
     695              : bool
     696     94319962 : strict_aliasing_warning (location_t loc, tree type, tree expr)
     697              : {
     698     94319962 :   if (loc == UNKNOWN_LOCATION)
     699     59373803 :     loc = input_location;
     700              : 
     701              :   /* Strip pointer conversion chains and get to the correct original type.  */
     702     94319962 :   STRIP_NOPS (expr);
     703     94319962 :   tree otype = TREE_TYPE (expr);
     704              : 
     705     97070720 :   if (!(flag_strict_aliasing
     706     90622075 :         && POINTER_TYPE_P (type)
     707      3091432 :         && POINTER_TYPE_P (otype)
     708      2750758 :         && !VOID_TYPE_P (TREE_TYPE (type)))
     709              :       /* If the type we are casting to is a ref-all pointer
     710              :          dereferencing it is always valid.  */
     711     97050671 :       || TYPE_REF_CAN_ALIAS_ALL (type))
     712              :     return false;
     713              : 
     714       375498 :   if ((warn_strict_aliasing > 1) && TREE_CODE (expr) == ADDR_EXPR
     715      2382560 :       && (DECL_P (TREE_OPERAND (expr, 0))
     716        12857 :           || handled_component_p (TREE_OPERAND (expr, 0))))
     717              :     {
     718              :       /* Casting the address of an object to non void pointer. Warn
     719              :          if the cast breaks type based aliasing.  */
     720        47341 :       if (!COMPLETE_TYPE_P (TREE_TYPE (type)) && warn_strict_aliasing == 2)
     721              :         {
     722            1 :           warning_at (loc, OPT_Wstrict_aliasing,
     723              :                       "type-punning to incomplete type "
     724              :                       "might break strict-aliasing rules");
     725            1 :           return true;
     726              :         }
     727              :       else
     728              :         {
     729              :           /* warn_strict_aliasing >= 3.   This includes the default (3).
     730              :              Only warn if the cast is dereferenced immediately.  */
     731        47340 :           alias_set_type set1
     732        47340 :             = get_alias_set (TREE_TYPE (TREE_OPERAND (expr, 0)));
     733        47340 :           alias_set_type set2 = get_alias_set (TREE_TYPE (type));
     734              : 
     735        47340 :           if (set2 != 0
     736        47340 :               && set1 != set2
     737          794 :               && !alias_set_subset_of (set2, set1)
     738        47389 :               && !alias_sets_conflict_p (set1, set2))
     739              :             {
     740           48 :               warning_at (loc, OPT_Wstrict_aliasing,
     741              :                           "dereferencing type-punned "
     742              :                           "pointer will break strict-aliasing rules");
     743           48 :               return true;
     744              :             }
     745        47292 :           else if (warn_strict_aliasing == 2
     746        47292 :                    && !alias_sets_must_conflict_p (set1, set2))
     747              :             {
     748            1 :               warning_at (loc, OPT_Wstrict_aliasing,
     749              :                           "dereferencing type-punned "
     750              :                           "pointer might break strict-aliasing rules");
     751            1 :               return true;
     752              :             }
     753              :         }
     754              :     }
     755      2283429 :   else if ((warn_strict_aliasing == 1) && !VOID_TYPE_P (TREE_TYPE (otype)))
     756              :     {
     757              :       /* At this level, warn for any conversions, even if an address is
     758              :          not taken in the same statement.  This will likely produce many
     759              :          false positives, but could be useful to pinpoint problems that
     760              :          are not revealed at higher levels.  */
     761           28 :       alias_set_type set1 = get_alias_set (TREE_TYPE (otype));
     762           28 :       alias_set_type set2 = get_alias_set (TREE_TYPE (type));
     763           28 :       if (!COMPLETE_TYPE_P (TREE_TYPE (type))
     764           28 :           || !alias_sets_must_conflict_p (set1, set2))
     765              :         {
     766           20 :           warning_at (loc, OPT_Wstrict_aliasing,
     767              :                       "dereferencing type-punned "
     768              :                       "pointer might break strict-aliasing rules");
     769           20 :           return true;
     770              :         }
     771              :     }
     772              : 
     773              :   return false;
     774              : }
     775              : 
     776              : /* Warn about memset (&a, 0, sizeof (&a)); and similar mistakes with
     777              :    sizeof as last operand of certain builtins.  */
     778              : 
     779              : void
     780      5570528 : sizeof_pointer_memaccess_warning (location_t *sizeof_arg_loc, tree callee,
     781              :                                   vec<tree, va_gc> *params, tree *sizeof_arg,
     782              :                                   bool (*comp_types) (tree, tree))
     783              : {
     784      5570528 :   tree type, dest = NULL_TREE, src = NULL_TREE, tem;
     785      5570528 :   bool strop = false, cmp = false;
     786      5570528 :   unsigned int idx = ~0;
     787      5570528 :   location_t loc;
     788              : 
     789      5570528 :   if (TREE_CODE (callee) != FUNCTION_DECL
     790      5395235 :       || !fndecl_built_in_p (callee, BUILT_IN_NORMAL)
     791      5880946 :       || vec_safe_length (params) <= 1)
     792              :     return;
     793              : 
     794       174718 :   enum built_in_function fncode = DECL_FUNCTION_CODE (callee);
     795       174718 :   switch (fncode)
     796              :     {
     797         1139 :     case BUILT_IN_STRNCMP:
     798         1139 :     case BUILT_IN_STRNCASECMP:
     799         1139 :       cmp = true;
     800              :       /* FALLTHRU */
     801              :     case BUILT_IN_STRNCPY:
     802              :     case BUILT_IN_STRNCPY_CHK:
     803              :     case BUILT_IN_STRNCAT:
     804              :     case BUILT_IN_STRNCAT_CHK:
     805              :     case BUILT_IN_STPNCPY:
     806              :     case BUILT_IN_STPNCPY_CHK:
     807              :       strop = true;
     808              :       /* FALLTHRU */
     809        12544 :     case BUILT_IN_MEMCPY:
     810        12544 :     case BUILT_IN_MEMCPY_CHK:
     811        12544 :     case BUILT_IN_MEMMOVE:
     812        12544 :     case BUILT_IN_MEMMOVE_CHK:
     813        12544 :       if (params->length () < 3)
     814              :         return;
     815        12543 :       src = (*params)[1];
     816        12543 :       dest = (*params)[0];
     817        12543 :       idx = 2;
     818        12543 :       break;
     819          154 :     case BUILT_IN_BCOPY:
     820          154 :       if (params->length () < 3)
     821              :         return;
     822          154 :       src = (*params)[0];
     823          154 :       dest = (*params)[1];
     824          154 :       idx = 2;
     825          154 :       break;
     826        10656 :     case BUILT_IN_MEMCMP:
     827        10656 :     case BUILT_IN_BCMP:
     828        10656 :       if (params->length () < 3)
     829              :         return;
     830        10656 :       src = (*params)[1];
     831        10656 :       dest = (*params)[0];
     832        10656 :       idx = 2;
     833        10656 :       cmp = true;
     834        10656 :       break;
     835         9258 :     case BUILT_IN_MEMSET:
     836         9258 :     case BUILT_IN_MEMSET_CHK:
     837         9258 :       if (params->length () < 3)
     838              :         return;
     839         9258 :       dest = (*params)[0];
     840         9258 :       idx = 2;
     841         9258 :       break;
     842           76 :     case BUILT_IN_BZERO:
     843           76 :       dest = (*params)[0];
     844           76 :       idx = 1;
     845           76 :       break;
     846           60 :     case BUILT_IN_STRNDUP:
     847           60 :       src = (*params)[0];
     848           60 :       strop = true;
     849           60 :       idx = 1;
     850           60 :       break;
     851         1154 :     case BUILT_IN_MEMCHR:
     852         1154 :       if (params->length () < 3)
     853              :         return;
     854         1154 :       src = (*params)[0];
     855         1154 :       idx = 2;
     856         1154 :       break;
     857         2597 :     case BUILT_IN_SNPRINTF:
     858         2597 :     case BUILT_IN_SNPRINTF_CHK:
     859         2597 :     case BUILT_IN_VSNPRINTF:
     860         2597 :     case BUILT_IN_VSNPRINTF_CHK:
     861         2597 :       dest = (*params)[0];
     862         2597 :       idx = 1;
     863         2597 :       strop = true;
     864         2597 :       break;
     865              :     default:
     866              :       break;
     867              :     }
     868              : 
     869        36498 :   if (idx >= 3)
     870              :     return;
     871              : 
     872              :   /* Use error_operand_p to detect non-error arguments with an error
     873              :      type that the C++ front-end constructs.  */
     874        36498 :   if (error_operand_p (src)
     875        36497 :       || error_operand_p (dest)
     876        36492 :       || !sizeof_arg[idx]
     877        53329 :       || error_operand_p (sizeof_arg[idx]))
     878              :     return;
     879              : 
     880        11058 :   type = TYPE_P (sizeof_arg[idx])
     881        16831 :          ? sizeof_arg[idx] : TREE_TYPE (sizeof_arg[idx]);
     882              : 
     883        16831 :   if (!POINTER_TYPE_P (type))
     884              :     {
     885              :       /* The argument type may be an array.  Diagnose bounded string
     886              :          copy functions that specify the bound in terms of the source
     887              :          argument rather than the destination unless they are equal
     888              :          to one another.  Handle constant sizes and also try to handle
     889              :          sizeof expressions involving VLAs.  */
     890        14369 :       if (strop && !cmp && fncode != BUILT_IN_STRNDUP && src)
     891              :         {
     892          281 :           tem = tree_strip_nop_conversions (src);
     893          281 :           if (TREE_CODE (tem) == ADDR_EXPR)
     894           44 :             tem = TREE_OPERAND (tem, 0);
     895              : 
     896              :           /* Avoid diagnosing sizeof SRC when SRC is declared with
     897              :              attribute nonstring.  */
     898          281 :           tree dummy;
     899          281 :           if (get_attr_nonstring_decl (tem, &dummy))
     900           15 :             return;
     901              : 
     902          266 :           tree d = tree_strip_nop_conversions (dest);
     903          266 :           if (TREE_CODE (d) == ADDR_EXPR)
     904          158 :             d = TREE_OPERAND (d, 0);
     905              : 
     906          266 :           tree dstsz = TYPE_SIZE_UNIT (TREE_TYPE (d));
     907          266 :           tree srcsz = TYPE_SIZE_UNIT (TREE_TYPE (tem));
     908              : 
     909          266 :           if ((!dstsz
     910          266 :                || !srcsz
     911          262 :                || !operand_equal_p (dstsz, srcsz, OEP_LEXICOGRAPHIC))
     912          523 :               && operand_equal_p (tem, sizeof_arg[idx], OEP_ADDRESS_OF))
     913           80 :             warning_at (sizeof_arg_loc[idx], OPT_Wsizeof_pointer_memaccess,
     914              :                         "argument to %<sizeof%> in %qD call is the same "
     915              :                         "expression as the source; did you mean to use "
     916              :                         "the size of the destination?",
     917              :                         callee);
     918              :         }
     919              : 
     920        14354 :       return;
     921              :     }
     922              : 
     923         2462 :   if (dest
     924         2332 :       && (tem = tree_strip_nop_conversions (dest))
     925         2332 :       && POINTER_TYPE_P (TREE_TYPE (tem))
     926         4794 :       && comp_types (TREE_TYPE (TREE_TYPE (tem)), type))
     927              :     return;
     928              : 
     929         2402 :   if (src
     930         2042 :       && (tem = tree_strip_nop_conversions (src))
     931         2042 :       && POINTER_TYPE_P (TREE_TYPE (tem))
     932         4444 :       && comp_types (TREE_TYPE (TREE_TYPE (tem)), type))
     933              :     return;
     934              : 
     935         2346 :   loc = sizeof_arg_loc[idx];
     936              : 
     937         2346 :   if (dest && !cmp)
     938              :     {
     939         1754 :       if (!TYPE_P (sizeof_arg[idx])
     940         1314 :           && operand_equal_p (dest, sizeof_arg[idx], 0)
     941         2511 :           && comp_types (TREE_TYPE (dest), type))
     942              :         {
     943          533 :           if (TREE_CODE (sizeof_arg[idx]) == ADDR_EXPR && !strop)
     944           96 :             warning_at (loc, OPT_Wsizeof_pointer_memaccess,
     945              :                         "argument to %<sizeof%> in %qD call is the same "
     946              :                         "expression as the destination; did you mean to "
     947              :                         "remove the addressof?", callee);
     948          874 :           else if ((INTEGRAL_TYPE_P (TREE_TYPE (type))
     949          145 :                     && (TYPE_PRECISION (TREE_TYPE (type))
     950          145 :                         == TYPE_PRECISION (char_type_node)))
     951          729 :                    || strop)
     952          145 :             warning_at (loc, OPT_Wsizeof_pointer_memaccess,
     953              :                         "argument to %<sizeof%> in %qD call is the same "
     954              :                         "expression as the destination; did you mean to "
     955              :                         "provide an explicit length?", callee);
     956              :           else
     957          292 :             warning_at (loc, OPT_Wsizeof_pointer_memaccess,
     958              :                         "argument to %<sizeof%> in %qD call is the same "
     959              :                         "expression as the destination; did you mean to "
     960              :                         "dereference it?", callee);
     961          533 :           return;
     962              :         }
     963              : 
     964         1221 :       if (POINTER_TYPE_P (TREE_TYPE (dest))
     965         1221 :           && !strop
     966         1183 :           && comp_types (TREE_TYPE (dest), type)
     967         1477 :           && !VOID_TYPE_P (TREE_TYPE (type)))
     968              :         {
     969          256 :           warning_at (loc, OPT_Wsizeof_pointer_memaccess,
     970              :                       "argument to %<sizeof%> in %qD call is the same "
     971              :                       "pointer type %qT as the destination; expected %qT "
     972          256 :                       "or an explicit length", callee, TREE_TYPE (dest),
     973          256 :                       TREE_TYPE (TREE_TYPE (dest)));
     974          256 :           return;
     975              :         }
     976              :     }
     977              : 
     978         1557 :   if (src && !cmp)
     979              :     {
     980         1007 :       if (!TYPE_P (sizeof_arg[idx])
     981          791 :           && operand_equal_p (src, sizeof_arg[idx], 0)
     982         1605 :           && comp_types (TREE_TYPE (src), type))
     983              :         {
     984          423 :           if (TREE_CODE (sizeof_arg[idx]) == ADDR_EXPR && !strop)
     985           75 :             warning_at (loc, OPT_Wsizeof_pointer_memaccess,
     986              :                         "argument to %<sizeof%> in %qD call is the same "
     987              :                         "expression as the source; did you mean to "
     988              :                         "remove the addressof?", callee);
     989          696 :           else if ((INTEGRAL_TYPE_P (TREE_TYPE (type))
     990          119 :                     && (TYPE_PRECISION (TREE_TYPE (type))
     991          119 :                         == TYPE_PRECISION (char_type_node)))
     992          577 :                    || strop)
     993          119 :             warning_at (loc, OPT_Wsizeof_pointer_memaccess,
     994              :                         "argument to %<sizeof%> in %qD call is the same "
     995              :                         "expression as the source; did you mean to "
     996              :                         "provide an explicit length?", callee);
     997              :           else
     998          229 :             warning_at (loc, OPT_Wsizeof_pointer_memaccess,
     999              :                         "argument to %<sizeof%> in %qD call is the same "
    1000              :                         "expression as the source; did you mean to "
    1001              :                         "dereference it?", callee);
    1002          423 :           return;
    1003              :         }
    1004              : 
    1005          584 :       if (POINTER_TYPE_P (TREE_TYPE (src))
    1006          584 :           && !strop
    1007          584 :           && comp_types (TREE_TYPE (src), type)
    1008          788 :           && !VOID_TYPE_P (TREE_TYPE (type)))
    1009              :         {
    1010          200 :           warning_at (loc, OPT_Wsizeof_pointer_memaccess,
    1011              :                       "argument to %<sizeof%> in %qD call is the same "
    1012              :                       "pointer type %qT as the source; expected %qT "
    1013          200 :                       "or an explicit length", callee, TREE_TYPE (src),
    1014          200 :                       TREE_TYPE (TREE_TYPE (src)));
    1015          200 :           return;
    1016              :         }
    1017              :     }
    1018              : 
    1019          934 :   if (dest)
    1020              :     {
    1021          902 :       if (!TYPE_P (sizeof_arg[idx])
    1022          793 :           && operand_equal_p (dest, sizeof_arg[idx], 0)
    1023         1296 :           && comp_types (TREE_TYPE (dest), type))
    1024              :         {
    1025          121 :           if (TREE_CODE (sizeof_arg[idx]) == ADDR_EXPR && !strop)
    1026           21 :             warning_at (loc, OPT_Wsizeof_pointer_memaccess,
    1027              :                         "argument to %<sizeof%> in %qD call is the same "
    1028              :                         "expression as the first source; did you mean to "
    1029              :                         "remove the addressof?", callee);
    1030          200 :           else if ((INTEGRAL_TYPE_P (TREE_TYPE (type))
    1031           33 :                     && (TYPE_PRECISION (TREE_TYPE (type))
    1032           33 :                         == TYPE_PRECISION (char_type_node)))
    1033          167 :                    || strop)
    1034           33 :             warning_at (loc, OPT_Wsizeof_pointer_memaccess,
    1035              :                         "argument to %<sizeof%> in %qD call is the same "
    1036              :                         "expression as the first source; did you mean to "
    1037              :                         "provide an explicit length?", callee);
    1038              :           else
    1039           67 :             warning_at (loc, OPT_Wsizeof_pointer_memaccess,
    1040              :                         "argument to %<sizeof%> in %qD call is the same "
    1041              :                         "expression as the first source; did you mean to "
    1042              :                         "dereference it?", callee);
    1043          121 :           return;
    1044              :         }
    1045              : 
    1046          781 :       if (POINTER_TYPE_P (TREE_TYPE (dest))
    1047          781 :           && !strop
    1048          769 :           && comp_types (TREE_TYPE (dest), type)
    1049          823 :           && !VOID_TYPE_P (TREE_TYPE (type)))
    1050              :         {
    1051           42 :           warning_at (loc, OPT_Wsizeof_pointer_memaccess,
    1052              :                       "argument to %<sizeof%> in %qD call is the same "
    1053              :                       "pointer type %qT as the first source; expected %qT "
    1054           42 :                       "or an explicit length", callee, TREE_TYPE (dest),
    1055           42 :                       TREE_TYPE (TREE_TYPE (dest)));
    1056           42 :           return;
    1057              :         }
    1058              :     }
    1059              : 
    1060          771 :   if (src)
    1061              :     {
    1062          683 :       if (!TYPE_P (sizeof_arg[idx])
    1063          616 :           && operand_equal_p (src, sizeof_arg[idx], 0)
    1064         1043 :           && comp_types (TREE_TYPE (src), type))
    1065              :         {
    1066          136 :           if (TREE_CODE (sizeof_arg[idx]) == ADDR_EXPR && !strop)
    1067           24 :             warning_at (loc, OPT_Wsizeof_pointer_memaccess,
    1068              :                         "argument to %<sizeof%> in %qD call is the same "
    1069              :                         "expression as the second source; did you mean to "
    1070              :                         "remove the addressof?", callee);
    1071          224 :           else if ((INTEGRAL_TYPE_P (TREE_TYPE (type))
    1072           33 :                     && (TYPE_PRECISION (TREE_TYPE (type))
    1073           33 :                         == TYPE_PRECISION (char_type_node)))
    1074          191 :                    || strop)
    1075           33 :             warning_at (loc, OPT_Wsizeof_pointer_memaccess,
    1076              :                         "argument to %<sizeof%> in %qD call is the same "
    1077              :                         "expression as the second source; did you mean to "
    1078              :                         "provide an explicit length?", callee);
    1079              :           else
    1080           79 :             warning_at (loc, OPT_Wsizeof_pointer_memaccess,
    1081              :                         "argument to %<sizeof%> in %qD call is the same "
    1082              :                         "expression as the second source; did you mean to "
    1083              :                         "dereference it?", callee);
    1084          136 :           return;
    1085              :         }
    1086              : 
    1087          547 :       if (POINTER_TYPE_P (TREE_TYPE (src))
    1088          547 :           && !strop
    1089          547 :           && comp_types (TREE_TYPE (src), type)
    1090          602 :           && !VOID_TYPE_P (TREE_TYPE (type)))
    1091              :         {
    1092           51 :           warning_at (loc, OPT_Wsizeof_pointer_memaccess,
    1093              :                       "argument to %<sizeof%> in %qD call is the same "
    1094              :                       "pointer type %qT as the second source; expected %qT "
    1095           51 :                       "or an explicit length", callee, TREE_TYPE (src),
    1096           51 :                       TREE_TYPE (TREE_TYPE (src)));
    1097           51 :           return;
    1098              :         }
    1099              :     }
    1100              : 
    1101              : }
    1102              : 
    1103              : /* Warn for unlikely, improbable, or stupid DECL declarations
    1104              :    of `main'.  */
    1105              : 
    1106              : void
    1107        36308 : check_main_parameter_types (tree decl)
    1108              : {
    1109        36308 :   function_args_iterator iter;
    1110        36308 :   tree type;
    1111        36308 :   int argct = 0;
    1112              : 
    1113        40451 :   FOREACH_FUNCTION_ARGS (TREE_TYPE (decl), type, iter)
    1114              :     {
    1115              :       /* XXX void_type_node belies the abstraction.  */
    1116        40134 :       if (type == void_type_node || type == error_mark_node)
    1117              :         break;
    1118              : 
    1119         4143 :       tree t = type;
    1120         4143 :       if (TYPE_ATOMIC (t))
    1121            1 :           pedwarn (input_location, OPT_Wmain,
    1122              :                    "%<_Atomic%>-qualified parameter type %qT of %q+D",
    1123              :                    type, decl);
    1124         8283 :       while (POINTER_TYPE_P (t))
    1125              :         {
    1126         4140 :           t = TREE_TYPE (t);
    1127         4140 :           if (TYPE_ATOMIC (t))
    1128            1 :             pedwarn (input_location, OPT_Wmain,
    1129              :                      "%<_Atomic%>-qualified parameter type %qT of %q+D",
    1130              :                      type, decl);
    1131              :         }
    1132              : 
    1133         4143 :       ++argct;
    1134         4143 :       switch (argct)
    1135              :         {
    1136         2073 :         case 1:
    1137         2073 :           if (TYPE_MAIN_VARIANT (type) != integer_type_node)
    1138            9 :             pedwarn (input_location, OPT_Wmain,
    1139              :                      "first argument of %q+D should be %<int%>", decl);
    1140              :           break;
    1141              : 
    1142         2061 :         case 2:
    1143         2061 :           if (TREE_CODE (type) != POINTER_TYPE
    1144         2061 :               || TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
    1145         4122 :               || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
    1146         2061 :                   != char_type_node))
    1147            0 :             pedwarn (input_location, OPT_Wmain,
    1148              :                      "second argument of %q+D should be %<char **%>", decl);
    1149              :           break;
    1150              : 
    1151            9 :         case 3:
    1152            9 :           if (TREE_CODE (type) != POINTER_TYPE
    1153            9 :               || TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
    1154           18 :               || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
    1155            9 :                   != char_type_node))
    1156            0 :             pedwarn (input_location, OPT_Wmain,
    1157              :                      "third argument of %q+D should probably be "
    1158              :                      "%<char **%>", decl);
    1159              :           break;
    1160              :         }
    1161              :     }
    1162              : 
    1163              :   /* It is intentional that this message does not mention the third
    1164              :     argument because it's only mentioned in an appendix of the
    1165              :     standard.  */
    1166        36308 :   if (argct > 0 && (argct < 2 || argct > 3))
    1167           12 :     pedwarn (input_location, OPT_Wmain,
    1168              :              "%q+D takes only zero or two arguments", decl);
    1169              : 
    1170        36308 :   if (stdarg_p (TREE_TYPE (decl)))
    1171            4 :     pedwarn (input_location, OPT_Wmain,
    1172              :              "%q+D declared as variadic function", decl);
    1173        36308 : }
    1174              : 
    1175              : /* Warns and returns true if the conversion of EXPR to TYPE may alter a value.
    1176              :    This is a helper function for warnings_for_convert_and_check.  */
    1177              : 
    1178              : static bool
    1179    118797313 : conversion_warning (location_t loc, tree type, tree expr, tree result)
    1180              : {
    1181    118797313 :   tree expr_type = TREE_TYPE (expr);
    1182    118797313 :   enum conversion_safety conversion_kind;
    1183    118797313 :   int arith_ops = 0;
    1184              : 
    1185    118797313 :   if (!warn_conversion && !warn_sign_conversion && !warn_float_conversion)
    1186              :     return false;
    1187              : 
    1188              :   /* This may happen, because for LHS op= RHS we preevaluate
    1189              :      RHS and create C_MAYBE_CONST_EXPR <SAVE_EXPR <RHS>>, which
    1190              :      means we could no longer see the code of the EXPR.  */
    1191         6663 :   if (TREE_CODE (expr) == C_MAYBE_CONST_EXPR)
    1192            0 :     expr = C_MAYBE_CONST_EXPR_EXPR (expr);
    1193         6663 :   if (TREE_CODE (expr) == SAVE_EXPR)
    1194           17 :     expr = TREE_OPERAND (expr, 0);
    1195              : 
    1196         6663 :   switch (TREE_CODE (expr))
    1197              :     {
    1198          130 :     case EQ_EXPR:
    1199          130 :     case NE_EXPR:
    1200          130 :     case LE_EXPR:
    1201          130 :     case GE_EXPR:
    1202          130 :     case LT_EXPR:
    1203          130 :     case GT_EXPR:
    1204          130 :     case TRUTH_ANDIF_EXPR:
    1205          130 :     case TRUTH_ORIF_EXPR:
    1206          130 :     case TRUTH_AND_EXPR:
    1207          130 :     case TRUTH_OR_EXPR:
    1208          130 :     case TRUTH_XOR_EXPR:
    1209          130 :     case TRUTH_NOT_EXPR:
    1210              :       /* Conversion from boolean to a signed:1 bit-field (which only
    1211              :          can hold the values 0 and -1) doesn't lose information - but
    1212              :          it does change the value.  */
    1213          130 :       if (TYPE_PRECISION (type) == 1 && !TYPE_UNSIGNED (type))
    1214           31 :         warning_at (loc, OPT_Wconversion,
    1215              :                     "conversion to %qT from boolean expression", type);
    1216              :       return true;
    1217              : 
    1218         3292 :     case REAL_CST:
    1219         3292 :     case INTEGER_CST:
    1220         3292 :     case COMPLEX_CST:
    1221         3292 :       {
    1222         3292 :         conversion_kind = unsafe_conversion_p (type, expr, result, true);
    1223         3292 :         int warnopt;
    1224         3292 :         if (conversion_kind == UNSAFE_REAL)
    1225              :           warnopt = OPT_Wfloat_conversion;
    1226         3003 :         else if (conversion_kind)
    1227              :           warnopt = OPT_Wconversion;
    1228              :         else
    1229              :           break;
    1230              : 
    1231          636 :         if (conversion_kind == UNSAFE_SIGN)
    1232              :           {
    1233         1158 :             bool cstresult
    1234              :               = (result
    1235          579 :                  && CONSTANT_CLASS_P (result));
    1236          579 :             if (TYPE_UNSIGNED (type))
    1237              :               {
    1238          244 :                 if (cstresult)
    1239          200 :                   warning_at (loc, OPT_Wsign_conversion,
    1240              :                               "unsigned conversion from %qT to %qT "
    1241              :                               "changes value from %qE to %qE",
    1242              :                               expr_type, type, expr, result);
    1243              :                 else
    1244           44 :                   warning_at (loc, OPT_Wsign_conversion,
    1245              :                               "unsigned conversion from %qT to %qT "
    1246              :                               "changes the value of %qE",
    1247              :                               expr_type, type, expr);
    1248              :               }
    1249              :             else
    1250              :               {
    1251          335 :                 if (cstresult)
    1252          335 :                   warning_at (loc, OPT_Wsign_conversion,
    1253              :                               "signed conversion from %qT to %qT changes "
    1254              :                               "value from %qE to %qE",
    1255              :                               expr_type, type, expr, result);
    1256              :                 else
    1257            0 :                   warning_at (loc, OPT_Wsign_conversion,
    1258              :                               "signed conversion from %qT to %qT changes "
    1259              :                               "the value of %qE",
    1260              :                               expr_type, type, expr);
    1261              :               }
    1262              :           }
    1263          346 :         else if (CONSTANT_CLASS_P (result))
    1264          297 :           warning_at (loc, warnopt,
    1265              :                       "conversion from %qT to %qT changes value from %qE to %qE",
    1266              :                       expr_type, type, expr, result);
    1267              :         else
    1268           49 :           warning_at (loc, warnopt,
    1269              :                       "conversion from %qT to %qT changes the value of %qE",
    1270              :                       expr_type, type, expr);
    1271              :         return true;
    1272              :       }
    1273              : 
    1274          179 :     case PLUS_EXPR:
    1275          179 :     case MINUS_EXPR:
    1276          179 :     case MULT_EXPR:
    1277          179 :     case MAX_EXPR:
    1278          179 :     case MIN_EXPR:
    1279          179 :     case TRUNC_MOD_EXPR:
    1280          179 :     case FLOOR_MOD_EXPR:
    1281          179 :     case TRUNC_DIV_EXPR:
    1282          179 :     case FLOOR_DIV_EXPR:
    1283          179 :     case CEIL_DIV_EXPR:
    1284          179 :     case EXACT_DIV_EXPR:
    1285          179 :     case RDIV_EXPR:
    1286          179 :       arith_ops = 2;
    1287          179 :       goto default_;
    1288              : 
    1289          257 :     case PREDECREMENT_EXPR:
    1290          257 :     case PREINCREMENT_EXPR:
    1291          257 :     case POSTDECREMENT_EXPR:
    1292          257 :     case POSTINCREMENT_EXPR:
    1293          257 :     case LSHIFT_EXPR:
    1294          257 :     case RSHIFT_EXPR:
    1295          257 :     case FIX_TRUNC_EXPR:
    1296          257 :     case NON_LVALUE_EXPR:
    1297          257 :     case NEGATE_EXPR:
    1298          257 :     case BIT_NOT_EXPR:
    1299          257 :       arith_ops = 1;
    1300          257 :       goto default_;
    1301              : 
    1302          176 :     case COND_EXPR:
    1303          176 :       {
    1304              :         /* In case of COND_EXPR, we do not care about the type of
    1305              :            COND_EXPR, only about the conversion of each operand.  */
    1306          176 :         tree op1 = TREE_OPERAND (expr, 1);
    1307          176 :         tree op2 = TREE_OPERAND (expr, 2);
    1308              : 
    1309          173 :         return ((op1 && conversion_warning (loc, type, op1, result))
    1310          296 :                 || conversion_warning (loc, type, op2, result));
    1311              :       }
    1312              : 
    1313           62 :     case BIT_AND_EXPR:
    1314           62 :       if ((TREE_CODE (expr_type) == INTEGER_TYPE
    1315           62 :            || TREE_CODE (expr_type) == BITINT_TYPE)
    1316           62 :           && (TREE_CODE (type) == INTEGER_TYPE
    1317           62 :               || TREE_CODE (type) == BITINT_TYPE))
    1318          145 :         for (int i = 0; i < 2; ++i)
    1319              :           {
    1320          124 :             tree op = TREE_OPERAND (expr, i);
    1321          124 :             if (TREE_CODE (op) != INTEGER_CST)
    1322           71 :               continue;
    1323              : 
    1324              :             /* If one of the operands is a non-negative constant
    1325              :                that fits in the target type, then the type of the
    1326              :                other operand does not matter.  */
    1327           53 :             if (int_fits_type_p (op, c_common_signed_type (type))
    1328           53 :                 && int_fits_type_p (op, c_common_unsigned_type (type)))
    1329              :               return false;
    1330              : 
    1331              :             /* If constant is unsigned and fits in the target
    1332              :                type, then the result will also fit.  */
    1333           19 :             if (TYPE_UNSIGNED (TREE_TYPE (op)) && int_fits_type_p (op, type))
    1334              :               return false;
    1335              :           }
    1336              :       /* FALLTHRU */
    1337          174 :     case BIT_IOR_EXPR:
    1338          174 :     case BIT_XOR_EXPR:
    1339          174 :       return (conversion_warning (loc, type, TREE_OPERAND (expr, 0), result)
    1340          174 :               || conversion_warning (loc, type, TREE_OPERAND (expr, 1),
    1341              :                                      result));
    1342              : 
    1343         2850 :     default_:
    1344         2850 :     default:
    1345         2850 :       conversion_kind = unsafe_conversion_p (type, expr, result, true);
    1346         2850 :       {
    1347         2850 :         int warnopt;
    1348         2850 :         if (conversion_kind == UNSAFE_REAL)
    1349              :           warnopt = OPT_Wfloat_conversion;
    1350         2767 :         else if (conversion_kind == UNSAFE_SIGN)
    1351              :           warnopt = OPT_Wsign_conversion;
    1352         1656 :         else if (conversion_kind)
    1353              :           warnopt = OPT_Wconversion;
    1354              :         else
    1355              :           break;
    1356              : 
    1357         1692 :         if (arith_ops
    1358         1692 :             && global_dc->option_enabled_p (warnopt))
    1359              :           {
    1360          691 :             for (int i = 0; i < arith_ops; ++i)
    1361              :               {
    1362          555 :                 tree op = TREE_OPERAND (expr, i);
    1363              :                 /* Avoid -Wsign-conversion for (unsigned)(x + (-1)).  */
    1364          112 :                 if (TREE_CODE (expr) == PLUS_EXPR && i == 1
    1365           56 :                     && INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type)
    1366            8 :                     && TREE_CODE (op) == INTEGER_CST
    1367          563 :                     && tree_int_cst_sgn (op) < 0)
    1368            0 :                   op = fold_build1 (NEGATE_EXPR, TREE_TYPE (op), op);
    1369          555 :                 tree opr = convert (type, op);
    1370          555 :                 if (unsafe_conversion_p (type, op, opr, true))
    1371          267 :                   goto op_unsafe;
    1372              :               }
    1373              :             /* The operands seem safe, we might still want to warn if
    1374              :                -Warith-conversion.  */
    1375              :             warnopt = OPT_Warith_conversion;
    1376         1692 :           op_unsafe:;
    1377              :           }
    1378              : 
    1379         1692 :         if (conversion_kind == UNSAFE_SIGN)
    1380         1111 :           warning_at (loc, warnopt, "conversion to %qT from %qT "
    1381              :                       "may change the sign of the result",
    1382              :                       type, expr_type);
    1383          581 :         else if (conversion_kind == UNSAFE_IMAGINARY)
    1384           22 :           warning_at (loc, warnopt,
    1385              :                       "conversion from %qT to %qT discards imaginary component",
    1386              :                       expr_type, type);
    1387              :         else
    1388          559 :           warning_at (loc, warnopt,
    1389              :                       "conversion from %qT to %qT may change value",
    1390              :                       expr_type, type);
    1391              :         return true;
    1392              :       }
    1393              :     }
    1394              :   return false;
    1395              : }
    1396              : 
    1397              : /* Produce warnings after a conversion. RESULT is the result of
    1398              :    converting EXPR to TYPE.  This is a helper function for
    1399              :    convert_and_check and cp_convert_and_check.  */
    1400              : 
    1401              : void
    1402    118799053 : warnings_for_convert_and_check (location_t loc, tree type, tree expr,
    1403              :                                 tree result)
    1404              : {
    1405    118799053 :   loc = expansion_point_location_if_in_system_header (loc);
    1406              : 
    1407    237629902 :   while (TREE_CODE (expr) == COMPOUND_EXPR)
    1408        31796 :     expr = TREE_OPERAND (expr, 1);
    1409    118834250 :   while (TREE_CODE (result) == COMPOUND_EXPR)
    1410        35197 :     result = TREE_OPERAND (result, 1);
    1411              : 
    1412    118799053 :   bool cst = CONSTANT_CLASS_P (result);
    1413    118799053 :   tree exprtype = TREE_TYPE (expr);
    1414    118799053 :   tree result_diag;
    1415              :   /* We're interested in the actual numerical value here, not its ASCII
    1416              :      representation.  */
    1417    118799053 :   if (cst && TYPE_MAIN_VARIANT (TREE_TYPE (result)) == char_type_node)
    1418       678344 :     result_diag = fold_convert (integer_type_node, result);
    1419              :   else
    1420              :     result_diag = result;
    1421              : 
    1422    118799053 :   if (TREE_CODE (expr) == INTEGER_CST
    1423     97061315 :       && (TREE_CODE (type) == INTEGER_TYPE
    1424     97061315 :           || TREE_CODE (type) == BITINT_TYPE
    1425      5878787 :           || (TREE_CODE (type) == ENUMERAL_TYPE
    1426        78594 :               && TREE_CODE (ENUM_UNDERLYING_TYPE (type)) != BOOLEAN_TYPE))
    1427    210060171 :       && !int_fits_type_p (expr, type))
    1428              :     {
    1429              :       /* Do not diagnose overflow in a constant expression merely
    1430              :          because a conversion overflowed.  */
    1431       774729 :       if (TREE_OVERFLOW (result))
    1432         1920 :         TREE_OVERFLOW (result) = TREE_OVERFLOW (expr);
    1433              : 
    1434       774729 :       if (TYPE_UNSIGNED (type))
    1435              :         {
    1436              :           /* This detects cases like converting -129 or 256 to
    1437              :              unsigned char.  */
    1438       129210 :           if (!int_fits_type_p (expr, c_common_signed_type (type)))
    1439              :             {
    1440         1656 :               if (cst)
    1441         1656 :                 warning_at (loc, OPT_Woverflow,
    1442         1656 :                             (TYPE_UNSIGNED (exprtype)
    1443              :                              ? G_("conversion from %qT to %qT "
    1444              :                                   "changes value from %qE to %qE")
    1445              :                              : G_("unsigned conversion from %qT to %qT "
    1446              :                                   "changes value from %qE to %qE")),
    1447              :                             exprtype, type, expr, result_diag);
    1448              :               else
    1449            0 :                 warning_at (loc, OPT_Woverflow,
    1450            0 :                             (TYPE_UNSIGNED (exprtype)
    1451              :                              ? G_("conversion from %qT to %qT "
    1452              :                                   "changes the value of %qE")
    1453              :                              : G_("unsigned conversion from %qT to %qT "
    1454              :                                   "changes the value of %qE")),
    1455              :                             exprtype, type, expr);
    1456              :             }
    1457              :           else
    1458       127554 :             conversion_warning (loc, type, expr, result);
    1459              :         }
    1460       645519 :       else if (!int_fits_type_p (expr, c_common_unsigned_type (type)))
    1461              :         {
    1462          380 :           if (cst)
    1463          380 :             warning_at (loc, OPT_Woverflow,
    1464              :                         "overflow in conversion from %qT to %qT "
    1465              :                         "changes value from %qE to %qE",
    1466              :                         exprtype, type, expr, result_diag);
    1467              :           else
    1468            0 :             warning_at (loc, OPT_Woverflow,
    1469              :                         "overflow in conversion from %qT to %qT "
    1470              :                         "changes the value of %qE",
    1471              :                         exprtype, type, expr);
    1472              :         }
    1473              :       /* No warning for converting 0x80000000 to int.  */
    1474       645139 :       else if (pedantic
    1475       645139 :                && ((TREE_CODE (exprtype) != INTEGER_TYPE
    1476         1152 :                     && TREE_CODE (exprtype) != BITINT_TYPE)
    1477         1152 :                    || (TYPE_PRECISION (exprtype)
    1478         1152 :                        != TYPE_PRECISION (type))))
    1479              :         {
    1480           64 :           if (cst)
    1481           64 :             warning_at (loc, OPT_Woverflow,
    1482              :                         "overflow in conversion from %qT to %qT "
    1483              :                         "changes value from %qE to %qE",
    1484              :                         exprtype, type, expr, result_diag);
    1485              :           else
    1486            0 :             warning_at (loc, OPT_Woverflow,
    1487              :                         "overflow in conversion from %qT to %qT "
    1488              :                         "changes the value of %qE",
    1489              :                         exprtype, type, expr);
    1490              :         }
    1491              :       else
    1492       645075 :         conversion_warning (loc, type, expr, result);
    1493              :     }
    1494    118024324 :   else if ((TREE_CODE (result) == INTEGER_CST
    1495    118024324 :             || TREE_CODE (result) == FIXED_CST) && TREE_OVERFLOW (result))
    1496              :     {
    1497          139 :       if (cst)
    1498          139 :         warning_at (loc, OPT_Woverflow,
    1499              :                     "overflow in conversion from %qT to %qT "
    1500              :                     "changes value from %qE to %qE",
    1501              :                     exprtype, type, expr, result_diag);
    1502              :       else
    1503            0 :         warning_at (loc, OPT_Woverflow,
    1504              :                     "overflow in conversion from %qT to %qT "
    1505              :                     "changes the value of %qE",
    1506              :                     exprtype, type, expr);
    1507              :     }
    1508              :   else
    1509    118024185 :     conversion_warning (loc, type, expr, result);
    1510    118799053 : }
    1511              : 
    1512              : /* Subroutines of c_do_switch_warnings, called via splay_tree_foreach.
    1513              :    Used to verify that case values match up with enumerator values.  */
    1514              : 
    1515              : static void
    1516           46 : match_case_to_enum_1 (tree key, tree type, tree label)
    1517              : {
    1518              :   /* Avoid warning about enums that have no enumerators.  */
    1519           46 :   if (TYPE_VALUES (type) == NULL_TREE)
    1520           15 :     return;
    1521              : 
    1522           31 :   char buf[WIDE_INT_PRINT_BUFFER_SIZE];
    1523           31 :   wide_int w = wi::to_wide (key);
    1524              : 
    1525           31 :   gcc_assert (w.get_precision () <= WIDE_INT_MAX_INL_PRECISION);
    1526           31 :   if (tree_fits_uhwi_p (key))
    1527           31 :     print_dec (w, buf, UNSIGNED);
    1528            0 :   else if (tree_fits_shwi_p (key))
    1529            0 :     print_dec (w, buf, SIGNED);
    1530              :   else
    1531            0 :     print_hex (w, buf);
    1532              : 
    1533           31 :   if (TYPE_NAME (type) == NULL_TREE)
    1534            1 :     warning_at (DECL_SOURCE_LOCATION (CASE_LABEL (label)),
    1535            2 :                 warn_switch ? OPT_Wswitch : OPT_Wswitch_enum,
    1536              :                 "case value %qs not in enumerated type",
    1537              :                 buf);
    1538              :   else
    1539           30 :     warning_at (DECL_SOURCE_LOCATION (CASE_LABEL (label)),
    1540           34 :                 warn_switch ? OPT_Wswitch : OPT_Wswitch_enum,
    1541              :                 "case value %qs not in enumerated type %qT",
    1542              :                 buf, type);
    1543           31 : }
    1544              : 
    1545              : /* Subroutine of c_do_switch_warnings, called via splay_tree_foreach.
    1546              :    Used to verify that case values match up with enumerator values.  */
    1547              : 
    1548              : static int
    1549        35417 : match_case_to_enum (splay_tree_node node, void *data)
    1550              : {
    1551        35417 :   tree label = (tree) node->value;
    1552        35417 :   tree type = (tree) data;
    1553              : 
    1554              :   /* Skip default case.  */
    1555        35417 :   if (!CASE_LOW (label))
    1556              :     return 0;
    1557              : 
    1558              :   /* If CASE_LOW_SEEN is not set, that means CASE_LOW did not appear
    1559              :      when we did our enum->case scan.  Reset our scratch bit after.  */
    1560        33257 :   if (!CASE_LOW_SEEN (label))
    1561           45 :     match_case_to_enum_1 (CASE_LOW (label), type, label);
    1562              :   else
    1563        33212 :     CASE_LOW_SEEN (label) = 0;
    1564              : 
    1565              :   /* If CASE_HIGH is non-null, we have a range.  If CASE_HIGH_SEEN is
    1566              :      not set, that means that CASE_HIGH did not appear when we did our
    1567              :      enum->case scan.  Reset our scratch bit after.  */
    1568        33257 :   if (CASE_HIGH (label))
    1569              :     {
    1570            3 :       if (!CASE_HIGH_SEEN (label))
    1571            1 :         match_case_to_enum_1 (CASE_HIGH (label), type, label);
    1572              :       else
    1573            2 :         CASE_HIGH_SEEN (label) = 0;
    1574              :     }
    1575              : 
    1576              :   return 0;
    1577              : }
    1578              : 
    1579              : /* Handle -Wswitch*.  Called from the front end after parsing the
    1580              :    switch construct.  */
    1581              : /* ??? Should probably be somewhere generic, since other languages
    1582              :    besides C and C++ would want this.  At the moment, however, C/C++
    1583              :    are the only tree-ssa languages that support enumerations at all,
    1584              :    so the point is moot.  */
    1585              : 
    1586              : void
    1587       648662 : c_do_switch_warnings (splay_tree cases, location_t switch_location,
    1588              :                       tree type, tree cond, bool bool_cond_p)
    1589              : {
    1590       648662 :   splay_tree_node default_node;
    1591       648662 :   splay_tree_node node;
    1592       648662 :   tree chain;
    1593       648662 :   bool outside_range_p = false;
    1594              : 
    1595       648662 :   if (type != error_mark_node
    1596       648586 :       && type != TREE_TYPE (cond)
    1597       391266 :       && INTEGRAL_TYPE_P (type)
    1598       391255 :       && INTEGRAL_TYPE_P (TREE_TYPE (cond))
    1599      1039916 :       && (!tree_int_cst_equal (TYPE_MIN_VALUE (type),
    1600       391254 :                                TYPE_MIN_VALUE (TREE_TYPE (cond)))
    1601       277690 :           || !tree_int_cst_equal (TYPE_MAX_VALUE (type),
    1602       277690 :                                   TYPE_MAX_VALUE (TREE_TYPE (cond)))))
    1603              :     {
    1604       315068 :       tree min_value = TYPE_MIN_VALUE (type);
    1605       315068 :       tree max_value = TYPE_MAX_VALUE (type);
    1606              : 
    1607       315068 :       node = splay_tree_predecessor (cases, (splay_tree_key) min_value);
    1608       315068 :       if (node && node->key)
    1609              :         {
    1610           69 :           outside_range_p = true;
    1611              :           /* There is at least one case smaller than TYPE's minimum value.
    1612              :              NODE itself could be still a range overlapping the valid values,
    1613              :              but any predecessors thereof except the default case will be
    1614              :              completely outside of range.  */
    1615           69 :           if (CASE_HIGH ((tree) node->value)
    1616           69 :               && tree_int_cst_compare (CASE_HIGH ((tree) node->value),
    1617              :                                        min_value) >= 0)
    1618              :             {
    1619           27 :               location_t loc = EXPR_LOCATION ((tree) node->value);
    1620           27 :               warning_at (loc, OPT_Wswitch_outside_range,
    1621              :                           "lower value in case label range less than minimum"
    1622              :                           " value for type");
    1623           27 :               CASE_LOW ((tree) node->value) = convert (TREE_TYPE (cond),
    1624              :                                                        min_value);
    1625           27 :               node->key = (splay_tree_key) CASE_LOW ((tree) node->value);
    1626              :             }
    1627              :           /* All the following ones are completely outside of range.  */
    1628          179 :           do
    1629              :             {
    1630          124 :               node = splay_tree_predecessor (cases,
    1631              :                                              (splay_tree_key) min_value);
    1632          124 :               if (node == NULL || !node->key)
    1633              :                 break;
    1634           55 :               location_t loc = EXPR_LOCATION ((tree) node->value);
    1635           55 :               warning_at (loc, OPT_Wswitch_outside_range, "case label value is"
    1636              :                           " less than minimum value for type");
    1637           55 :               splay_tree_remove (cases, node->key);
    1638           55 :             }
    1639              :           while (1);
    1640              :         }
    1641       315068 :       node = splay_tree_lookup (cases, (splay_tree_key) max_value);
    1642       315068 :       if (node == NULL)
    1643       315012 :         node = splay_tree_predecessor (cases, (splay_tree_key) max_value);
    1644              :       /* Handle a single node that might partially overlap the range.  */
    1645       315012 :       if (node
    1646       314959 :           && node->key
    1647       314918 :           && CASE_HIGH ((tree) node->value)
    1648       315070 :           && tree_int_cst_compare (CASE_HIGH ((tree) node->value),
    1649              :                                    max_value) > 0)
    1650              :         {
    1651           27 :           location_t loc = EXPR_LOCATION ((tree) node->value);
    1652           27 :           warning_at (loc, OPT_Wswitch_outside_range, "upper value in case"
    1653              :                       " label range exceeds maximum value for type");
    1654           27 :           CASE_HIGH ((tree) node->value)
    1655           27 :             = convert (TREE_TYPE (cond), max_value);
    1656           27 :           outside_range_p = true;
    1657              :         }
    1658              :       /* And any nodes that are completely outside of the range.  */
    1659       630372 :       while ((node = splay_tree_successor (cases,
    1660              :                                            (splay_tree_key) max_value))
    1661       315186 :              != NULL)
    1662              :         {
    1663          118 :           location_t loc = EXPR_LOCATION ((tree) node->value);
    1664          118 :           warning_at (loc, OPT_Wswitch_outside_range,
    1665              :                       "case label value exceeds maximum value for type");
    1666          118 :           splay_tree_remove (cases, node->key);
    1667          118 :           outside_range_p = true;
    1668              :         }
    1669              :     }
    1670              : 
    1671       648662 :   if (!warn_switch && !warn_switch_enum && !warn_switch_default
    1672       639728 :       && !warn_switch_bool)
    1673              :     return;
    1674              : 
    1675       648662 :   default_node = splay_tree_lookup (cases, (splay_tree_key) NULL);
    1676       648662 :   if (!default_node)
    1677        84434 :     warning_at (switch_location, OPT_Wswitch_default,
    1678              :                 "switch missing default case");
    1679              : 
    1680              :   /* There are certain cases where -Wswitch-bool warnings aren't
    1681              :      desirable, such as
    1682              :      switch (boolean)
    1683              :        {
    1684              :        case true: ...
    1685              :        case false: ...
    1686              :        }
    1687              :      so be careful here.  */
    1688       648662 :   if (warn_switch_bool && bool_cond_p)
    1689              :     {
    1690          170 :       splay_tree_node min_node;
    1691              :       /* If there's a default node, it's also the value with the minimal
    1692              :          key.  So look at the penultimate key (if any).  */
    1693          170 :       if (default_node)
    1694           54 :         min_node = splay_tree_successor (cases, (splay_tree_key) NULL);
    1695              :       else
    1696          116 :         min_node = splay_tree_min (cases);
    1697          170 :       tree min = min_node ? (tree) min_node->key : NULL_TREE;
    1698              : 
    1699          170 :       splay_tree_node max_node = splay_tree_max (cases);
    1700              :       /* This might be a case range, so look at the value with the
    1701              :          maximal key and then check CASE_HIGH.  */
    1702          170 :       tree max = max_node ? (tree) max_node->value : NULL_TREE;
    1703          103 :       if (max)
    1704          103 :         max = CASE_HIGH (max) ? CASE_HIGH (max) : CASE_LOW (max);
    1705              : 
    1706              :       /* If there's a case value > 1 or < 0, that is outside bool
    1707              :          range, warn.  */
    1708          170 :       if (outside_range_p
    1709           89 :           || (max && wi::gts_p (wi::to_wide (max), 1))
    1710           74 :           || (min && wi::lts_p (wi::to_wide (min), 0))
    1711              :           /* And handle the
    1712              :              switch (boolean)
    1713              :                {
    1714              :                case true: ...
    1715              :                case false: ...
    1716              :                default: ...
    1717              :                }
    1718              :              case, where we want to warn.  */
    1719          170 :           || (default_node
    1720           70 :               && max && wi::to_wide (max) == 1
    1721           70 :               && min && wi::to_wide (min) == 0))
    1722          108 :         warning_at (switch_location, OPT_Wswitch_bool,
    1723              :                     "switch condition has boolean value");
    1724              :     }
    1725              : 
    1726              :   /* From here on, we only care about enumerated types.  */
    1727       648662 :   if (!type || TREE_CODE (type) != ENUMERAL_TYPE)
    1728              :     return;
    1729              : 
    1730              :   /* From here on, we only care about -Wswitch and -Wswitch-enum.  */
    1731       358762 :   if (!warn_switch_enum && !warn_switch)
    1732              :     return;
    1733              : 
    1734              :   /* Check the cases.  Warn about case values which are not members of
    1735              :      the enumerated type.  For -Wswitch-enum, or for -Wswitch when
    1736              :      there is no default case, check that exactly all enumeration
    1737              :      literals are covered by the cases.  */
    1738              : 
    1739              :   /* Clearing COND if it is not an integer constant simplifies
    1740              :      the tests inside the loop below.  */
    1741         3079 :   if (TREE_CODE (cond) != INTEGER_CST)
    1742         3078 :     cond = NULL_TREE;
    1743              : 
    1744              :   /* The time complexity here is O(N*lg(N)) worst case, but for the
    1745              :       common case of monotonically increasing enumerators, it is
    1746              :       O(N), since the nature of the splay tree will keep the next
    1747              :       element adjacent to the root at all times.  */
    1748              : 
    1749        67127 :   for (chain = TYPE_VALUES (type); chain; chain = TREE_CHAIN (chain))
    1750              :     {
    1751        64048 :       tree value = TREE_VALUE (chain);
    1752        64048 :       tree attrs = DECL_ATTRIBUTES (value);
    1753        64048 :       value = DECL_INITIAL (value);
    1754        64048 :       node = splay_tree_lookup (cases, (splay_tree_key) value);
    1755        64048 :       if (node)
    1756              :         {
    1757              :           /* Mark the CASE_LOW part of the case entry as seen.  */
    1758        36316 :           tree label = (tree) node->value;
    1759        36316 :           CASE_LOW_SEEN (label) = 1;
    1760        36316 :           continue;
    1761        36316 :         }
    1762              : 
    1763              :       /* Even though there wasn't an exact match, there might be a
    1764              :          case range which includes the enumerator's value.  */
    1765        27732 :       node = splay_tree_predecessor (cases, (splay_tree_key) value);
    1766        27732 :       if (node && CASE_HIGH ((tree) node->value))
    1767              :         {
    1768            4 :           tree label = (tree) node->value;
    1769            4 :           int cmp = tree_int_cst_compare (CASE_HIGH (label), value);
    1770            4 :           if (cmp >= 0)
    1771              :             {
    1772              :               /* If we match the upper bound exactly, mark the CASE_HIGH
    1773              :                  part of the case entry as seen.  */
    1774            4 :               if (cmp == 0)
    1775            2 :                 CASE_HIGH_SEEN (label) = 1;
    1776            4 :               continue;
    1777              :             }
    1778              :         }
    1779              : 
    1780              :       /* We've now determined that this enumerated literal isn't
    1781              :          handled by the case labels of the switch statement.  */
    1782              : 
    1783              :       /* Don't warn if the enumerator was marked as unused.  We can't use
    1784              :          TREE_USED here: it could have been set on the enumerator if the
    1785              :          enumerator was used earlier.  */
    1786        27728 :       if (lookup_attribute ("unused", attrs)
    1787        27728 :           || lookup_attribute ("maybe_unused", attrs))
    1788           23 :         continue;
    1789              : 
    1790              :       /* If the switch expression is a constant, we only really care
    1791              :          about whether that constant is handled by the switch.  */
    1792        27705 :       if (cond && tree_int_cst_compare (cond, value))
    1793            0 :         continue;
    1794              : 
    1795              :       /* If the enumerator is defined in a system header and uses a reserved
    1796              :          name, then we continue to avoid throwing a warning.  */
    1797        27705 :       location_t loc = DECL_SOURCE_LOCATION
    1798              :             (TYPE_STUB_DECL (TYPE_MAIN_VARIANT (type)));
    1799        27705 :       if (in_system_header_at (loc)
    1800        27717 :           && name_reserved_for_implementation_p
    1801           12 :               (IDENTIFIER_POINTER (TREE_PURPOSE (chain))))
    1802            8 :         continue;
    1803              : 
    1804              :       /* If there is a default_node, the only relevant option is
    1805              :          Wswitch-enum.  Otherwise, if both are enabled then we prefer
    1806              :          to warn using -Wswitch because -Wswitch is enabled by -Wall
    1807              :          while -Wswitch-enum is explicit.  */
    1808        55394 :       warning_at (switch_location,
    1809           50 :                   (default_node || !warn_switch
    1810        27697 :                    ? OPT_Wswitch_enum
    1811              :                    : OPT_Wswitch),
    1812              :                   "enumeration value %qE not handled in switch",
    1813        27697 :                   TREE_PURPOSE (chain));
    1814              :     }
    1815              : 
    1816              :   /* Attribute flag_enum means bitwise combinations are OK.  */
    1817         3079 :   if (lookup_attribute ("flag_enum", TYPE_ATTRIBUTES (type)))
    1818              :     return;
    1819              : 
    1820              :   /* Warn if there are case expressions that don't correspond to
    1821              :      enumerators.  This can occur since C and C++ don't enforce
    1822              :      type-checking of assignments to enumeration variables.
    1823              : 
    1824              :      The time complexity here is now always O(N) worst case, since
    1825              :      we should have marked both the lower bound and upper bound of
    1826              :      every disjoint case label, with CASE_LOW_SEEN and CASE_HIGH_SEEN
    1827              :      above.  This scan also resets those fields.  */
    1828              : 
    1829         3061 :   splay_tree_foreach (cases, match_case_to_enum, type);
    1830              : }
    1831              : 
    1832              : /* Warn for A ?: C expressions (with B omitted) where A is a boolean
    1833              :    expression, because B will always be true. */
    1834              : 
    1835              : void
    1836         1414 : warn_for_omitted_condop (location_t location, tree cond)
    1837              : {
    1838              :   /* In C++ template declarations it can happen that the type is dependent
    1839              :      and not yet known, thus TREE_TYPE (cond) == NULL_TREE.  */
    1840         1414 :   if (truth_value_p (TREE_CODE (cond))
    1841         1414 :       || (TREE_TYPE (cond) != NULL_TREE
    1842         1138 :           && TREE_CODE (TREE_TYPE (cond)) == BOOLEAN_TYPE))
    1843          348 :       warning_at (location, OPT_Wparentheses,
    1844              :                 "the omitted middle operand in %<?:%> will always be %<true%>, "
    1845              :                 "suggest explicit middle operand");
    1846         1414 : }
    1847              : 
    1848              : /* Give an error for storing into ARG, which is 'const'.  USE indicates
    1849              :    how ARG was being used.  */
    1850              : 
    1851              : void
    1852          298 : readonly_error (location_t loc, tree arg, enum lvalue_use use)
    1853              : {
    1854          298 :   gcc_assert (use == lv_assign || use == lv_increment || use == lv_decrement
    1855              :               || use == lv_asm);
    1856          298 :   STRIP_ANY_LOCATION_WRAPPER (arg);
    1857              :   /* Using this macro rather than (for example) arrays of messages
    1858              :      ensures that all the format strings are checked at compile
    1859              :      time.  */
    1860              : #define READONLY_MSG(A, I, D, AS) (use == lv_assign ? (A)               \
    1861              :                                    : (use == lv_increment ? (I)         \
    1862              :                                    : (use == lv_decrement ? (D) : (AS))))
    1863          298 :   if (TREE_CODE (arg) == COMPONENT_REF)
    1864              :     {
    1865           55 :       if (TYPE_READONLY (TREE_TYPE (TREE_OPERAND (arg, 0))))
    1866           90 :         error_at (loc, READONLY_MSG (G_("assignment of member "
    1867              :                                         "%qD in read-only object"),
    1868              :                                      G_("increment of member "
    1869              :                                         "%qD in read-only object"),
    1870              :                                      G_("decrement of member "
    1871              :                                         "%qD in read-only object"),
    1872              :                                      G_("member %qD in read-only object "
    1873              :                                         "used as %<asm%> output")),
    1874           45 :                   TREE_OPERAND (arg, 1));
    1875              :       else
    1876           20 :         error_at (loc, READONLY_MSG (G_("assignment of read-only member %qD"),
    1877              :                                      G_("increment of read-only member %qD"),
    1878              :                                      G_("decrement of read-only member %qD"),
    1879              :                                      G_("read-only member %qD used as %<asm%> output")),
    1880           10 :                   TREE_OPERAND (arg, 1));
    1881              :     }
    1882              :   else if (VAR_P (arg))
    1883          194 :     error_at (loc, READONLY_MSG (G_("assignment of read-only variable %qD"),
    1884              :                                  G_("increment of read-only variable %qD"),
    1885              :                                  G_("decrement of read-only variable %qD"),
    1886              :                                  G_("read-only variable %qD used as %<asm%> output")),
    1887              :               arg);
    1888              :   else if (TREE_CODE (arg) == PARM_DECL)
    1889           12 :     error_at (loc, READONLY_MSG (G_("assignment of read-only parameter %qD"),
    1890              :                                  G_("increment of read-only parameter %qD"),
    1891              :                                  G_("decrement of read-only parameter %qD"),
    1892              :                                  G_("read-only parameter %qD use as %<asm%> output")),
    1893              :               arg);
    1894              :   else if (TREE_CODE (arg) == RESULT_DECL)
    1895              :     {
    1896            0 :       gcc_assert (c_dialect_cxx ());
    1897            0 :       error_at (loc, READONLY_MSG (G_("assignment of "
    1898              :                                       "read-only named return value %qD"),
    1899              :                                    G_("increment of "
    1900              :                                       "read-only named return value %qD"),
    1901              :                                    G_("decrement of "
    1902              :                                       "read-only named return value %qD"),
    1903              :                                    G_("read-only named return value %qD "
    1904              :                                       "used as %<asm%>output")),
    1905              :                 arg);
    1906              :     }
    1907              :   else if (TREE_CODE (arg) == FUNCTION_DECL)
    1908            6 :     error_at (loc, READONLY_MSG (G_("assignment of function %qD"),
    1909              :                                  G_("increment of function %qD"),
    1910              :                                  G_("decrement of function %qD"),
    1911              :                                  G_("function %qD used as %<asm%> output")),
    1912              :               arg);
    1913              :   else
    1914          266 :     error_at (loc, READONLY_MSG (G_("assignment of read-only location %qE"),
    1915              :                                  G_("increment of read-only location %qE"),
    1916              :                                  G_("decrement of read-only location %qE"),
    1917              :                                  G_("read-only location %qE used as %<asm%> output")),
    1918              :               arg);
    1919          298 : }
    1920              : 
    1921              : /* Print an error message for an invalid lvalue.  USE says
    1922              :    how the lvalue is being used and so selects the error message.  LOC
    1923              :    is the location for the error.  */
    1924              : 
    1925              : void
    1926          208 : lvalue_error (location_t loc, enum lvalue_use use)
    1927              : {
    1928          208 :   switch (use)
    1929              :     {
    1930           96 :     case lv_assign:
    1931           96 :       error_at (loc, "lvalue required as left operand of assignment");
    1932           96 :       break;
    1933           36 :     case lv_increment:
    1934           36 :       error_at (loc, "lvalue required as increment operand");
    1935           36 :       break;
    1936           22 :     case lv_decrement:
    1937           22 :       error_at (loc, "lvalue required as decrement operand");
    1938           22 :       break;
    1939           41 :     case lv_addressof:
    1940           41 :       error_at (loc, "lvalue required as unary %<&%> operand");
    1941           41 :       break;
    1942           13 :     case lv_asm:
    1943           13 :       error_at (loc, "lvalue required in %<asm%> statement");
    1944           13 :       break;
    1945            0 :     default:
    1946            0 :       gcc_unreachable ();
    1947              :     }
    1948          208 : }
    1949              : 
    1950              : /* Print an error message for an invalid indirection of type TYPE.
    1951              :    ERRSTRING is the name of the operator for the indirection.  */
    1952              : 
    1953              : void
    1954          303 : invalid_indirection_error (location_t loc, tree type, ref_operator errstring)
    1955              : {
    1956          303 :   switch (errstring)
    1957              :     {
    1958            0 :     case RO_NULL:
    1959            0 :       gcc_assert (c_dialect_cxx ());
    1960            0 :       error_at (loc, "invalid type argument (have %qT)", type);
    1961            0 :       break;
    1962            0 :     case RO_ARRAY_INDEXING:
    1963            0 :       error_at (loc,
    1964              :                 "invalid type argument of array indexing (have %qT)",
    1965              :                 type);
    1966            0 :       break;
    1967          298 :     case RO_UNARY_STAR:
    1968          298 :       error_at (loc,
    1969              :                 "invalid type argument of unary %<*%> (have %qT)",
    1970              :                 type);
    1971          298 :       break;
    1972            2 :     case RO_ARROW:
    1973            2 :       error_at (loc,
    1974              :                 "invalid type argument of %<->%> (have %qT)",
    1975              :                 type);
    1976            2 :       break;
    1977            3 :     case RO_ARROW_STAR:
    1978            3 :       error_at (loc,
    1979              :                 "invalid type argument of %<->*%> (have %qT)",
    1980              :                 type);
    1981            3 :       break;
    1982            0 :     case RO_IMPLICIT_CONVERSION:
    1983            0 :       error_at (loc,
    1984              :                 "invalid type argument of implicit conversion (have %qT)",
    1985              :                 type);
    1986            0 :       break;
    1987            0 :     default:
    1988            0 :       gcc_unreachable ();
    1989              :     }
    1990          303 : }
    1991              : 
    1992              : /* Subscripting with type char is likely to lose on a machine where
    1993              :    chars are signed.  So warn on any machine, but optionally.  Don't
    1994              :    warn for unsigned char since that type is safe.  Don't warn for
    1995              :    signed char because anyone who uses that must have done so
    1996              :    deliberately. Furthermore, we reduce the false positive load by
    1997              :    warning only for non-constant value of type char.
    1998              :    LOC is the location of the subscripting expression.  */
    1999              : 
    2000              : void
    2001     10000433 : warn_array_subscript_with_type_char (location_t loc, tree index)
    2002              : {
    2003     10000433 :   if (TYPE_MAIN_VARIANT (TREE_TYPE (index)) == char_type_node)
    2004              :     {
    2005              :       /* If INDEX has a location, use it; otherwise use LOC (the location
    2006              :          of the subscripting expression as a whole).  */
    2007       267110 :       loc = EXPR_LOC_OR_LOC (index, loc);
    2008       267110 :       STRIP_ANY_LOCATION_WRAPPER (index);
    2009       267110 :       if (TREE_CODE (index) != INTEGER_CST)
    2010          438 :         warning_at (loc, OPT_Wchar_subscripts,
    2011              :                     "array subscript has type %<char%>");
    2012              :     }
    2013     10000433 : }
    2014              : 
    2015              : /* Implement -Wparentheses for the unexpected C precedence rules, to
    2016              :    cover cases like x + y << z which readers are likely to
    2017              :    misinterpret.  We have seen an expression in which CODE is a binary
    2018              :    operator used to combine expressions ARG_LEFT and ARG_RIGHT, which
    2019              :    before folding had CODE_LEFT and CODE_RIGHT.  CODE_LEFT and
    2020              :    CODE_RIGHT may be ERROR_MARK, which means that that side of the
    2021              :    expression was not formed using a binary or unary operator, or it
    2022              :    was enclosed in parentheses.  */
    2023              : 
    2024              : void
    2025      2795624 : warn_about_parentheses (location_t loc, enum tree_code code,
    2026              :                         enum tree_code code_left, tree arg_left,
    2027              :                         enum tree_code code_right, tree arg_right)
    2028              : {
    2029      2795624 :   if (!warn_parentheses)
    2030              :     return;
    2031              : 
    2032              :   /* This macro tests that the expression ARG with original tree code
    2033              :      CODE appears to be a boolean expression. or the result of folding a
    2034              :      boolean expression.  */
    2035              : #define APPEARS_TO_BE_BOOLEAN_EXPR_P(CODE, ARG)                             \
    2036              :         (truth_value_p (TREE_CODE (ARG))                                    \
    2037              :          || TREE_CODE (TREE_TYPE (ARG)) == BOOLEAN_TYPE                     \
    2038              :          /* Folding may create 0 or 1 integers from other expressions.  */  \
    2039              :          || ((CODE) != INTEGER_CST                                          \
    2040              :              && (integer_onep (ARG) || integer_zerop (ARG))))
    2041              : 
    2042      2795624 :   switch (code)
    2043              :     {
    2044       264737 :     case LSHIFT_EXPR:
    2045       264737 :       if (code_left == PLUS_EXPR)
    2046           23 :         warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses,
    2047              :                     "suggest parentheses around %<+%> inside %<<<%>");
    2048       264716 :       else if (code_right == PLUS_EXPR)
    2049           22 :         warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses,
    2050              :                     "suggest parentheses around %<+%> inside %<<<%>");
    2051       264695 :       else if (code_left == MINUS_EXPR)
    2052           23 :         warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses,
    2053              :                     "suggest parentheses around %<-%> inside %<<<%>");
    2054       264674 :       else if (code_right == MINUS_EXPR)
    2055           22 :         warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses,
    2056              :                     "suggest parentheses around %<-%> inside %<<<%>");
    2057              :       return;
    2058              : 
    2059       101902 :     case RSHIFT_EXPR:
    2060       101902 :       if (code_left == PLUS_EXPR)
    2061           26 :         warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses,
    2062              :                     "suggest parentheses around %<+%> inside %<>>%>");
    2063       101878 :       else if (code_right == PLUS_EXPR)
    2064           25 :         warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses,
    2065              :                     "suggest parentheses around %<+%> inside %<>>%>");
    2066       101854 :       else if (code_left == MINUS_EXPR)
    2067           23 :         warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses,
    2068              :                     "suggest parentheses around %<-%> inside %<>>%>");
    2069       101833 :       else if (code_right == MINUS_EXPR)
    2070           22 :         warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses,
    2071              :                     "suggest parentheses around %<-%> inside %<>>%>");
    2072              :       return;
    2073              : 
    2074        58275 :     case TRUTH_ORIF_EXPR:
    2075        58275 :       if (code_left == TRUTH_ANDIF_EXPR)
    2076           27 :         warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses,
    2077              :                     "suggest parentheses around %<&&%> within %<||%>");
    2078        58250 :       else if (code_right == TRUTH_ANDIF_EXPR)
    2079           22 :         warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses,
    2080              :                     "suggest parentheses around %<&&%> within %<||%>");
    2081              :       return;
    2082              : 
    2083       129994 :     case BIT_IOR_EXPR:
    2084       129994 :       if (code_left == BIT_AND_EXPR || code_left == BIT_XOR_EXPR
    2085       129994 :           || code_left == PLUS_EXPR || code_left == MINUS_EXPR)
    2086           98 :         warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses,
    2087              :                  "suggest parentheses around arithmetic in operand of %<|%>");
    2088       129904 :       else if (code_right == BIT_AND_EXPR || code_right == BIT_XOR_EXPR
    2089       129904 :                || code_right == PLUS_EXPR || code_right == MINUS_EXPR)
    2090           95 :         warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses,
    2091              :                  "suggest parentheses around arithmetic in operand of %<|%>");
    2092              :       /* Check cases like x|y==z */
    2093       129813 :       else if (TREE_CODE_CLASS (code_left) == tcc_comparison)
    2094           46 :         warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses,
    2095              :                  "suggest parentheses around comparison in operand of %<|%>");
    2096       129771 :       else if (TREE_CODE_CLASS (code_right) == tcc_comparison)
    2097           44 :         warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses,
    2098              :                  "suggest parentheses around comparison in operand of %<|%>");
    2099              :       /* Check cases like !x | y */
    2100       129729 :       else if (code_left == TRUTH_NOT_EXPR
    2101       129729 :                && !APPEARS_TO_BE_BOOLEAN_EXPR_P (code_right, arg_right))
    2102          144 :         warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses,
    2103              :                     "suggest parentheses around operand of "
    2104              :                     "%<!%> or change %<|%> to %<||%> or %<!%> to %<~%>");
    2105              :       return;
    2106              : 
    2107        10616 :     case BIT_XOR_EXPR:
    2108        10616 :       if (code_left == BIT_AND_EXPR
    2109        10616 :           || code_left == PLUS_EXPR || code_left == MINUS_EXPR)
    2110           69 :         warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses,
    2111              :                  "suggest parentheses around arithmetic in operand of %<^%>");
    2112        10553 :       else if (code_right == BIT_AND_EXPR
    2113        10553 :                || code_right == PLUS_EXPR || code_right == MINUS_EXPR)
    2114           66 :         warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses,
    2115              :                  "suggest parentheses around arithmetic in operand of %<^%>");
    2116              :       /* Check cases like x^y==z */
    2117        10490 :       else if (TREE_CODE_CLASS (code_left) == tcc_comparison)
    2118           69 :         warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses,
    2119              :                  "suggest parentheses around comparison in operand of %<^%>");
    2120        10427 :       else if (TREE_CODE_CLASS (code_right) == tcc_comparison)
    2121           66 :         warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses,
    2122              :                  "suggest parentheses around comparison in operand of %<^%>");
    2123              :       return;
    2124              : 
    2125       113340 :     case BIT_AND_EXPR:
    2126       113340 :       if (code_left == PLUS_EXPR)
    2127           23 :         warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses,
    2128              :                  "suggest parentheses around %<+%> in operand of %<&%>");
    2129       113319 :       else if (code_right == PLUS_EXPR)
    2130           22 :         warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses,
    2131              :                  "suggest parentheses around %<+%> in operand of %<&%>");
    2132       113298 :       else if (code_left == MINUS_EXPR)
    2133           23 :         warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses,
    2134              :                  "suggest parentheses around %<-%> in operand of %<&%>");
    2135       113277 :       else if (code_right == MINUS_EXPR)
    2136           22 :         warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses,
    2137              :                  "suggest parentheses around %<-%> in operand of %<&%>");
    2138              :       /* Check cases like x&y==z */
    2139       113256 :       else if (TREE_CODE_CLASS (code_left) == tcc_comparison)
    2140           69 :         warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses,
    2141              :                  "suggest parentheses around comparison in operand of %<&%>");
    2142       113193 :       else if (TREE_CODE_CLASS (code_right) == tcc_comparison)
    2143           66 :         warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses,
    2144              :                  "suggest parentheses around comparison in operand of %<&%>");
    2145              :       /* Check cases like !x & y */
    2146       113130 :       else if (code_left == TRUTH_NOT_EXPR
    2147       113130 :                && !APPEARS_TO_BE_BOOLEAN_EXPR_P (code_right, arg_right))
    2148          148 :         warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses,
    2149              :                     "suggest parentheses around operand of "
    2150              :                     "%<!%> or change %<&%> to %<&&%> or %<!%> to %<~%>");
    2151              :       return;
    2152              : 
    2153       232676 :     case EQ_EXPR:
    2154       232676 :       if (TREE_CODE_CLASS (code_left) == tcc_comparison)
    2155           32 :         warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses,
    2156              :                  "suggest parentheses around comparison in operand of %<==%>");
    2157       232649 :       else if (TREE_CODE_CLASS (code_right) == tcc_comparison)
    2158            9 :         warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses,
    2159              :                  "suggest parentheses around comparison in operand of %<==%>");
    2160              :       return;
    2161        97779 :     case NE_EXPR:
    2162        97779 :       if (TREE_CODE_CLASS (code_left) == tcc_comparison)
    2163           32 :         warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses,
    2164              :                  "suggest parentheses around comparison in operand of %<!=%>");
    2165        97751 :       else if (TREE_CODE_CLASS (code_right) == tcc_comparison)
    2166            6 :         warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses,
    2167              :                  "suggest parentheses around comparison in operand of %<!=%>");
    2168              :       return;
    2169              : 
    2170      1786305 :     default:
    2171      1786305 :       if (TREE_CODE_CLASS (code) == tcc_comparison)
    2172              :         {
    2173       358070 :           if (TREE_CODE_CLASS (code_left) == tcc_comparison
    2174          108 :                 && code_left != NE_EXPR && code_left != EQ_EXPR
    2175       358178 :                 && INTEGRAL_TYPE_P (TREE_TYPE (arg_left)))
    2176          104 :             warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses,
    2177              :                         "comparisons like %<X<=Y<=Z%> do not "
    2178              :                         "have their mathematical meaning");
    2179       357974 :           else if (TREE_CODE_CLASS (code_right) == tcc_comparison
    2180            0 :                    && code_right != NE_EXPR && code_right != EQ_EXPR
    2181       357974 :                    && INTEGRAL_TYPE_P (TREE_TYPE (arg_right)))
    2182            0 :             warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses,
    2183              :                         "comparisons like %<X<=Y<=Z%> do not "
    2184              :                         "have their mathematical meaning");
    2185              :         }
    2186              :       return;
    2187              :     }
    2188              : }
    2189              : 
    2190              : /* If LABEL (a LABEL_DECL) has not been used, issue a warning.  */
    2191              : 
    2192              : void
    2193        43997 : warn_for_unused_label (tree label)
    2194              : {
    2195        43997 :   if (!TREE_USED (label))
    2196              :     {
    2197         1101 :       if (warning_suppressed_p (label, OPT_Wunused_label))
    2198              :         /* Don't warn.  */;
    2199          725 :       else if (DECL_INITIAL (label))
    2200          708 :         warning (OPT_Wunused_label, "label %q+D defined but not used", label);
    2201              :       else
    2202           17 :         warning (OPT_Wunused_label, "label %q+D declared but not defined", label);
    2203              :     }
    2204        42896 :   else if (asan_sanitize_use_after_scope ())
    2205              :     {
    2206          814 :       if (asan_used_labels == NULL)
    2207          115 :         asan_used_labels = new hash_set<tree> (16);
    2208              : 
    2209          814 :       asan_used_labels->add (label);
    2210              :     }
    2211        43997 : }
    2212              : 
    2213              : /* Warn for division by zero according to the value of DIVISOR.  LOC
    2214              :    is the location of the division operator.  */
    2215              : 
    2216              : void
    2217     13843431 : warn_for_div_by_zero (location_t loc, tree divisor)
    2218              : {
    2219              :   /* If DIVISOR is zero, and has integral or fixed-point type, issue a warning
    2220              :      about division by zero.  Do not issue a warning if DIVISOR has a
    2221              :      floating-point type, since we consider 0.0/0.0 a valid way of
    2222              :      generating a NaN.  */
    2223     13843431 :   if (c_inhibit_evaluation_warnings == 0
    2224     13843431 :       && (integer_zerop (divisor) || fixed_zerop (divisor)))
    2225          871 :     warning_at (loc, OPT_Wdiv_by_zero, "division by zero");
    2226     13843430 : }
    2227              : 
    2228              : /* Warn for patterns where memset appears to be used incorrectly.  The
    2229              :    warning location should be LOC.  ARG0, and ARG2 are the first and
    2230              :    last arguments to the call, while LITERAL_ZERO_MASK has a 1 bit for
    2231              :    each argument that was a literal zero.  */
    2232              : 
    2233              : void
    2234       229893 : warn_for_memset (location_t loc, tree arg0, tree arg2,
    2235              :                  int literal_zero_mask)
    2236              : {
    2237       229893 :   arg0 = fold_for_warn (arg0);
    2238       229893 :   arg2 = fold_for_warn (arg2);
    2239              : 
    2240       229893 :   if (warn_memset_transposed_args
    2241         9355 :       && integer_zerop (arg2)
    2242          297 :       && (literal_zero_mask & (1 << 2)) != 0
    2243       230095 :       && (literal_zero_mask & (1 << 1)) == 0)
    2244          155 :     warning_at (loc, OPT_Wmemset_transposed_args,
    2245              :                 "%<memset%> used with constant zero length "
    2246              :                 "parameter; this could be due to transposed "
    2247              :                 "parameters");
    2248              : 
    2249       229893 :   if (warn_memset_elt_size && TREE_CODE (arg2) == INTEGER_CST)
    2250              :     {
    2251         7321 :       STRIP_NOPS (arg0);
    2252         7321 :       if (TREE_CODE (arg0) == ADDR_EXPR)
    2253         6186 :         arg0 = TREE_OPERAND (arg0, 0);
    2254         7321 :       tree type = TREE_TYPE (arg0);
    2255         7321 :       if (type != NULL_TREE && TREE_CODE (type) == ARRAY_TYPE)
    2256              :         {
    2257         2783 :           tree elt_type = TREE_TYPE (type);
    2258         2783 :           tree domain = TYPE_DOMAIN (type);
    2259         2783 :           if (COMPLETE_TYPE_P (elt_type)
    2260         2780 :               && !integer_onep (TYPE_SIZE_UNIT (elt_type))
    2261         2337 :               && domain != NULL_TREE
    2262         2336 :               && TYPE_MAX_VALUE (domain)
    2263         2336 :               && TYPE_MIN_VALUE (domain)
    2264         2336 :               && integer_zerop (TYPE_MIN_VALUE (domain))
    2265         5119 :               && integer_onep (fold_build2 (MINUS_EXPR, domain,
    2266              :                                             arg2,
    2267              :                                             TYPE_MAX_VALUE (domain))))
    2268           30 :             warning_at (loc, OPT_Wmemset_elt_size,
    2269              :                         "%<memset%> used with length equal to "
    2270              :                         "number of elements without multiplication "
    2271              :                         "by element size");
    2272              :         }
    2273              :     }
    2274       229893 : }
    2275              : 
    2276              : /* Warn for calloc (sizeof (X), n).  */
    2277              : 
    2278              : void
    2279          206 : warn_for_calloc (location_t *sizeof_arg_loc, tree callee,
    2280              :                  vec<tree, va_gc> *params, tree *sizeof_arg, tree attr)
    2281              : {
    2282          206 :   if (!TREE_VALUE (attr) || !TREE_CHAIN (TREE_VALUE (attr)))
    2283              :     return;
    2284              : 
    2285          206 :   int arg1 = TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr))) - 1;
    2286          206 :   int arg2
    2287          206 :     = TREE_INT_CST_LOW (TREE_VALUE (TREE_CHAIN (TREE_VALUE (attr)))) - 1;
    2288          206 :   if (arg1 < 0
    2289          206 :       || (unsigned) arg1 >= vec_safe_length (params)
    2290          206 :       || arg1 >= 6
    2291          206 :       || arg2 < 0
    2292          206 :       || (unsigned) arg2 >= vec_safe_length (params)
    2293          206 :       || arg2 >= 6
    2294          412 :       || arg1 >= arg2)
    2295              :     return;
    2296              : 
    2297          206 :   if (sizeof_arg[arg1] == NULL_TREE || sizeof_arg[arg2] != NULL_TREE)
    2298              :     return;
    2299              : 
    2300           28 :   if (warning_at (sizeof_arg_loc[arg1], OPT_Wcalloc_transposed_args,
    2301              :                   "%qD sizes specified with %<sizeof%> in the earlier "
    2302              :                   "argument and not in the later argument", callee))
    2303           28 :     inform (sizeof_arg_loc[arg1], "earlier argument should specify number "
    2304              :             "of elements, later size of each element");
    2305              : }
    2306              : 
    2307              : /* Warn for allocator calls where the constant allocated size is smaller
    2308              :    than sizeof (TYPE).  */
    2309              : 
    2310              : void
    2311         1957 : warn_for_alloc_size (location_t loc, tree type, tree call, tree alloc_size)
    2312              : {
    2313         1957 :   if (!TREE_VALUE (alloc_size))
    2314              :     return;
    2315              : 
    2316         1957 :   tree arg1 = TREE_VALUE (TREE_VALUE (alloc_size));
    2317         1957 :   int idx1 = TREE_INT_CST_LOW (arg1) - 1;
    2318         1957 :   if (idx1 < 0 || idx1 >= call_expr_nargs (call))
    2319              :     return;
    2320         1953 :   arg1 = CALL_EXPR_ARG (call, idx1);
    2321         1953 :   if (TREE_CODE (arg1) != INTEGER_CST)
    2322              :     return;
    2323          294 :   if (TREE_CHAIN (TREE_VALUE (alloc_size)))
    2324              :     {
    2325          107 :       tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_VALUE (alloc_size)));
    2326          107 :       int idx2 = TREE_INT_CST_LOW (arg2) - 1;
    2327          107 :       if (idx2 < 0 || idx2 >= call_expr_nargs (call))
    2328              :         return;
    2329          107 :       arg2 = CALL_EXPR_ARG (call, idx2);
    2330          107 :       if (TREE_CODE (arg2) != INTEGER_CST)
    2331              :         return;
    2332           51 :       arg1 = int_const_binop (MULT_EXPR, fold_convert (sizetype, arg1),
    2333           51 :                               fold_convert (sizetype, arg2));
    2334           51 :       if (TREE_CODE (arg1) != INTEGER_CST)
    2335              :         return;
    2336              :     }
    2337          238 :   if (!VOID_TYPE_P (type)
    2338          237 :       && TYPE_SIZE_UNIT (type)
    2339          236 :       && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST
    2340          474 :       && tree_int_cst_lt (arg1, TYPE_SIZE_UNIT (type)))
    2341           44 :     warning_at (loc, OPT_Walloc_size,
    2342              :                 "allocation of insufficient size %qE for type %qT with "
    2343           44 :                 "size %qE", arg1, type, TYPE_SIZE_UNIT (type));
    2344              : }
    2345              : 
    2346              : /* Subroutine of build_binary_op. Give warnings for comparisons
    2347              :    between signed and unsigned quantities that may fail. Do the
    2348              :    checking based on the original operand trees ORIG_OP0 and ORIG_OP1,
    2349              :    so that casts will be considered, but default promotions won't
    2350              :    be.
    2351              : 
    2352              :    LOCATION is the location of the comparison operator.
    2353              : 
    2354              :    The arguments of this function map directly to local variables
    2355              :    of build_binary_op.  */
    2356              : 
    2357              : void
    2358       684434 : warn_for_sign_compare (location_t location,
    2359              :                        tree orig_op0, tree orig_op1,
    2360              :                        tree op0, tree op1,
    2361              :                        tree result_type, enum tree_code resultcode)
    2362              : {
    2363       684434 :   if (error_operand_p (orig_op0) || error_operand_p (orig_op1))
    2364            0 :     return;
    2365              : 
    2366       684434 :   int op0_signed = !TYPE_UNSIGNED (TREE_TYPE (orig_op0));
    2367       684434 :   int op1_signed = !TYPE_UNSIGNED (TREE_TYPE (orig_op1));
    2368       684434 :   int unsignedp0, unsignedp1;
    2369              : 
    2370              :   /* Do not warn if the comparison is being done in a signed type,
    2371              :      since the signed type will only be chosen if it can represent
    2372              :      all the values of the unsigned type.  */
    2373       684434 :   if (!TYPE_UNSIGNED (result_type))
    2374              :     /* OK */;
    2375              :   /* Do not warn if both operands are unsigned.  */
    2376       256171 :   else if (op0_signed == op1_signed)
    2377              :     /* OK */;
    2378              :   else
    2379              :     {
    2380       138106 :       tree sop, uop, base_type;
    2381       138106 :       bool ovf;
    2382              : 
    2383       138106 :       if (op0_signed)
    2384              :         sop = orig_op0, uop = orig_op1;
    2385              :       else
    2386       137418 :         sop = orig_op1, uop = orig_op0;
    2387              : 
    2388       138106 :       sop = fold_for_warn (sop);
    2389       138106 :       uop = fold_for_warn (uop);
    2390              : 
    2391       276212 :       STRIP_TYPE_NOPS (sop);
    2392       138106 :       STRIP_TYPE_NOPS (uop);
    2393            8 :       base_type = (TREE_CODE (result_type) == COMPLEX_TYPE
    2394       138106 :                    ? TREE_TYPE (result_type) : result_type);
    2395              : 
    2396              :       /* Do not warn if the signed quantity is an unsuffixed integer
    2397              :          literal (or some static constant expression involving such
    2398              :          literals or a conditional expression involving such literals)
    2399              :          and it is non-negative.  */
    2400       138106 :       if (tree_expr_nonnegative_warnv_p (sop, &ovf))
    2401              :         /* OK */;
    2402              :       /* Do not warn if the comparison is an equality operation, the
    2403              :          unsigned quantity is an integral constant, and it would fit
    2404              :          in the result if the result were signed.  */
    2405          234 :       else if (TREE_CODE (uop) == INTEGER_CST
    2406          106 :                && (resultcode == EQ_EXPR || resultcode == NE_EXPR)
    2407          337 :                && int_fits_type_p (uop, c_common_signed_type (base_type)))
    2408              :         /* OK */;
    2409              :       /* In C, do not warn if the unsigned quantity is an enumeration
    2410              :          constant and its maximum value would fit in the result if the
    2411              :          result were signed.  */
    2412           87 :       else if (!c_dialect_cxx() && TREE_CODE (uop) == INTEGER_CST
    2413            1 :                && TREE_CODE (TREE_TYPE (uop)) == ENUMERAL_TYPE
    2414          135 :                && int_fits_type_p (TYPE_MAX_VALUE (TREE_TYPE (uop)),
    2415            0 :                                    c_common_signed_type (base_type)))
    2416              :         /* OK */;
    2417              :       else
    2418          135 :         warning_at (location, OPT_Wsign_compare,
    2419              :                     "comparison of integer expressions of different "
    2420          135 :                     "signedness: %qT and %qT", TREE_TYPE (orig_op0),
    2421          135 :                     TREE_TYPE (orig_op1));
    2422              :     }
    2423              : 
    2424              :   /* Warn if two unsigned values are being compared in a size larger
    2425              :      than their original size, and one (and only one) is the result of
    2426              :      a `~' operator.  This comparison will always fail.
    2427              : 
    2428              :      Also warn if one operand is a constant, and the constant does not
    2429              :      have all bits set that are set in the ~ operand when it is
    2430              :      extended.  */
    2431              : 
    2432              :   /* bits0 is the bit index of op0 extended to result_type, which will
    2433              :      be always 0 and so all bits above it.  If there is a BIT_NOT_EXPR
    2434              :      in that operand possibly sign or zero extended to op0 and then
    2435              :      possibly further sign or zero extended to result_type, bits0 will
    2436              :      be the precision of result type if all the extensions involved
    2437              :      if any are sign extensions, and will be the place of the innermost
    2438              :      zero extension otherwise.  We warn only if BIT_NOT_EXPR's operand is
    2439              :      zero extended from some even smaller precision, in that case after
    2440              :      BIT_NOT_EXPR some bits below bits0 will be guaranteed to be set.
    2441              :      Similarly for bits1.  */
    2442       684434 :   int bits0 = TYPE_PRECISION (result_type);
    2443       684434 :   if (TYPE_UNSIGNED (TREE_TYPE (op0)))
    2444       257629 :     bits0 = TYPE_PRECISION (TREE_TYPE (op0));
    2445       684434 :   tree arg0 = c_common_get_narrower (op0, &unsignedp0);
    2446       684434 :   if (TYPE_PRECISION (TREE_TYPE (arg0)) == TYPE_PRECISION (TREE_TYPE (op0)))
    2447       663214 :     unsignedp0 = TYPE_UNSIGNED (TREE_TYPE (op0));
    2448        21220 :   else if (unsignedp0)
    2449         7966 :     bits0 = TYPE_PRECISION (TREE_TYPE (arg0));
    2450       684434 :   op0 = arg0;
    2451       684434 :   int bits1 = TYPE_PRECISION (result_type);
    2452       684434 :   if (TYPE_UNSIGNED (TREE_TYPE (op1)))
    2453       188500 :     bits1 = TYPE_PRECISION (TREE_TYPE (op1));
    2454       684434 :   tree arg1 = c_common_get_narrower (op1, &unsignedp1);
    2455       684434 :   if (TYPE_PRECISION (TREE_TYPE (arg1)) == TYPE_PRECISION (TREE_TYPE (op1)))
    2456       669098 :     unsignedp1 = TYPE_UNSIGNED (TREE_TYPE (op1));
    2457        15336 :   else if (unsignedp1)
    2458         4401 :     bits1 = TYPE_PRECISION (TREE_TYPE (arg1));
    2459       684434 :   op1 = arg1;
    2460              : 
    2461       684434 :   if ((TREE_CODE (op0) == BIT_NOT_EXPR)
    2462       684434 :       ^ (TREE_CODE (op1) == BIT_NOT_EXPR))
    2463              :     {
    2464          191 :       if (TREE_CODE (op1) == BIT_NOT_EXPR)
    2465              :         {
    2466          138 :           std::swap (op0, op1);
    2467          138 :           std::swap (unsignedp0, unsignedp1);
    2468          138 :           std::swap (bits0, bits1);
    2469              :         }
    2470              : 
    2471          191 :       int unsignedp;
    2472          191 :       arg0 = c_common_get_narrower (TREE_OPERAND (op0, 0), &unsignedp);
    2473              : 
    2474              :       /* For these warnings, we need BIT_NOT_EXPR operand to be
    2475              :          zero extended from narrower type to BIT_NOT_EXPR's type.
    2476              :          In that case, all those bits above the narrower's type
    2477              :          are after BIT_NOT_EXPR set to 1.  */
    2478          191 :       if (tree_fits_shwi_p (op1))
    2479              :         {
    2480           36 :           HOST_WIDE_INT constant = tree_to_shwi (op1);
    2481           36 :           unsigned int bits = TYPE_PRECISION (TREE_TYPE (arg0));
    2482           36 :           if (unsignedp
    2483           32 :               && bits < TYPE_PRECISION (TREE_TYPE (op0))
    2484           65 :               && bits < HOST_BITS_PER_WIDE_INT)
    2485              :             {
    2486           29 :               HOST_WIDE_INT mask = HOST_WIDE_INT_M1U << bits;
    2487           29 :               if (bits0 < HOST_BITS_PER_WIDE_INT)
    2488           29 :                 mask &= ~(HOST_WIDE_INT_M1U << bits0);
    2489           29 :               if ((mask & constant) != mask)
    2490              :                 {
    2491           19 :                   if (constant == 0)
    2492            9 :                     warning_at (location, OPT_Wsign_compare,
    2493              :                                 "promoted bitwise complement of an unsigned "
    2494              :                                 "value is always nonzero");
    2495              :                   else
    2496           10 :                     warning_at (location, OPT_Wsign_compare,
    2497              :                                 "comparison of promoted bitwise complement "
    2498              :                                 "of an unsigned value with constant");
    2499              :                 }
    2500              :             }
    2501              :         }
    2502          155 :       else if ((TYPE_PRECISION (TREE_TYPE (arg0))
    2503          155 :                 < TYPE_PRECISION (TREE_TYPE (op0)))
    2504           16 :                && unsignedp
    2505           16 :                && unsignedp1
    2506          171 :                && TYPE_PRECISION (TREE_TYPE (op1)) < bits0)
    2507           11 :         warning_at (location, OPT_Wsign_compare,
    2508              :                     "comparison of promoted bitwise complement "
    2509              :                     "of an unsigned value with unsigned");
    2510              :     }
    2511              : }
    2512              : 
    2513              : /* RESULT_TYPE is the result of converting TYPE1 and TYPE2 to a common
    2514              :    type via c_common_type.  If -Wdouble-promotion is in use, and the
    2515              :    conditions for warning have been met, issue a warning.  GMSGID is
    2516              :    the warning message.  It must have two %T specifiers for the type
    2517              :    that was converted (generally "float") and the type to which it was
    2518              :    converted (generally "double), respectively.  LOC is the location
    2519              :    to which the warning should refer.  */
    2520              : 
    2521              : void
    2522    122356792 : do_warn_double_promotion (tree result_type, tree type1, tree type2,
    2523              :                          const char *gmsgid, location_t loc)
    2524              : {
    2525    122356792 :   tree source_type;
    2526              : 
    2527    122356792 :   if (!warn_double_promotion)
    2528              :     return;
    2529              :   /* If the conversion will not occur at run-time, there is no need to
    2530              :      warn about it.  */
    2531          127 :   if (c_inhibit_evaluation_warnings)
    2532              :     return;
    2533              :   /* If an invalid conversion has occurred, don't warn.  */
    2534          107 :   if (result_type == error_mark_node)
    2535              :     return;
    2536          106 :   if (TYPE_MAIN_VARIANT (result_type) != double_type_node
    2537          106 :       && TYPE_MAIN_VARIANT (result_type) != complex_double_type_node)
    2538              :     return;
    2539           92 :   if (TYPE_MAIN_VARIANT (type1) == float_type_node
    2540           92 :       || TYPE_MAIN_VARIANT (type1) == complex_float_type_node)
    2541              :     source_type = type1;
    2542           52 :   else if (TYPE_MAIN_VARIANT (type2) == float_type_node
    2543           52 :            || TYPE_MAIN_VARIANT (type2) == complex_float_type_node)
    2544              :     source_type = type2;
    2545              :   else
    2546              :     return;
    2547           44 :   warning_at (loc, OPT_Wdouble_promotion, gmsgid, source_type, result_type);
    2548              : }
    2549              : 
    2550              : /* Possibly warn about unused parameters.  */
    2551              : 
    2552              : void
    2553      3208043 : do_warn_unused_parameter (tree fn)
    2554              : {
    2555      3208043 :   tree decl;
    2556              : 
    2557      3208043 :   for (decl = DECL_ARGUMENTS (fn);
    2558     11551109 :        decl; decl = DECL_CHAIN (decl))
    2559        66210 :     if (!TREE_USED (decl) && TREE_CODE (decl) == PARM_DECL
    2560        66210 :         && DECL_NAME (decl) && !DECL_ARTIFICIAL (decl)
    2561      8343290 :         && !warning_suppressed_p (decl, OPT_Wunused_parameter))
    2562          123 :       warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wunused_parameter,
    2563              :                   "unused parameter %qD", decl);
    2564      3208043 : }
    2565              : 
    2566              : /* If DECL is a typedef that is declared in the current function,
    2567              :    record it for the purpose of -Wunused-local-typedefs.  */
    2568              : 
    2569              : void
    2570    268558110 : record_locally_defined_typedef (tree decl)
    2571              : {
    2572    268558110 :   struct c_language_function *l;
    2573              : 
    2574    268558110 :   if (!warn_unused_local_typedefs
    2575      3539215 :       || cfun == NULL
    2576              :       /* if this is not a locally defined typedef then we are not
    2577              :          interested.  */
    2578        57840 :       || !is_typedef_decl (decl)
    2579    268612758 :       || !decl_function_context (decl))
    2580    268503462 :     return;
    2581              : 
    2582        54648 :   l = (struct c_language_function *) cfun->language;
    2583        54648 :   vec_safe_push (l->local_typedefs, decl);
    2584              : }
    2585              : 
    2586              : /* If T is a TYPE_DECL declared locally, mark it as used.  */
    2587              : 
    2588              : void
    2589   6025355470 : maybe_record_typedef_use (tree t)
    2590              : {
    2591   6025355470 :   if (!is_typedef_decl (t))
    2592              :     return;
    2593              : 
    2594   1174824888 :   TREE_USED (t) = true;
    2595              : }
    2596              : 
    2597              : /* Warn if there are some unused locally defined typedefs in the
    2598              :    current function. */
    2599              : 
    2600              : void
    2601    202414664 : maybe_warn_unused_local_typedefs (void)
    2602              : {
    2603    202414664 :   int i;
    2604    202414664 :   tree decl;
    2605              :   /* The number of times we have emitted -Wunused-local-typedefs
    2606              :      warnings.  If this is different from errorcount, that means some
    2607              :      unrelated errors have been issued.  In which case, we'll avoid
    2608              :      emitting "unused-local-typedefs" warnings.  */
    2609    202414664 :   static int unused_local_typedefs_warn_count;
    2610    202414664 :   struct c_language_function *l;
    2611              : 
    2612    202414664 :   if (cfun == NULL)
    2613    202414664 :     return;
    2614              : 
    2615    202414664 :   if ((l = (struct c_language_function *) cfun->language) == NULL)
    2616              :     return;
    2617              : 
    2618    169279388 :   if (warn_unused_local_typedefs
    2619    169279388 :       && errorcount == unused_local_typedefs_warn_count)
    2620              :     {
    2621      5081195 :       FOR_EACH_VEC_SAFE_ELT (l->local_typedefs, i, decl)
    2622        54639 :         if (!TREE_USED (decl))
    2623          241 :           warning_at (DECL_SOURCE_LOCATION (decl),
    2624          241 :                       OPT_Wunused_local_typedefs,
    2625              :                       "typedef %qD locally defined but not used", decl);
    2626      5026556 :       unused_local_typedefs_warn_count = errorcount;
    2627              :     }
    2628              : 
    2629    169310695 :   vec_free (l->local_typedefs);
    2630              : }
    2631              : 
    2632              : /* If we're creating an if-else-if condition chain, first see if we
    2633              :    already have this COND in the CHAIN.  If so, warn and don't add COND
    2634              :    into the vector, otherwise add the COND there.  LOC is the location
    2635              :    of COND.  */
    2636              : 
    2637              : void
    2638          311 : warn_duplicated_cond_add_or_warn (location_t loc, tree cond, vec<tree> **chain)
    2639              : {
    2640              :   /* No chain has been created yet.  Do nothing.  */
    2641          311 :   if (*chain == NULL)
    2642          311 :     return;
    2643              : 
    2644          186 :   if (TREE_SIDE_EFFECTS (cond) || instantiation_dependent_expression_p (cond))
    2645              :     {
    2646              :       /* Uh-oh!  This condition has a side-effect, thus invalidates
    2647              :          the whole chain.  */
    2648           31 :       delete *chain;
    2649           31 :       *chain = NULL;
    2650           31 :       return;
    2651              :     }
    2652              : 
    2653              :   unsigned int ix;
    2654              :   tree t;
    2655          397 :   bool found = false;
    2656          397 :   FOR_EACH_VEC_ELT (**chain, ix, t)
    2657          335 :     if (operand_equal_p (cond, t, 0))
    2658              :       {
    2659           93 :         auto_diagnostic_group d;
    2660           93 :         if (warning_at (loc, OPT_Wduplicated_cond,
    2661              :                         "duplicated %<if%> condition"))
    2662           93 :           inform (EXPR_LOCATION (t), "previously used here");
    2663           93 :         found = true;
    2664           93 :         break;
    2665           93 :       }
    2666              : 
    2667           93 :   if (!found
    2668           62 :       && !CONSTANT_CLASS_P (cond)
    2669              :       /* Don't infinitely grow the chain.  */
    2670           54 :       && (*chain)->length () < 512)
    2671           54 :     (*chain)->safe_push (cond);
    2672              : }
    2673              : 
    2674              : /* Check and possibly warn if two declarations have contradictory
    2675              :    attributes, such as always_inline vs. noinline.  */
    2676              : 
    2677              : bool
    2678     19080514 : diagnose_mismatched_attributes (tree olddecl, tree newdecl)
    2679              : {
    2680     19080514 :   auto_urlify_attributes sentinel;
    2681     19080514 :   bool warned = false;
    2682              : 
    2683     19080514 :   tree a1 = lookup_attribute ("optimize", DECL_ATTRIBUTES (olddecl));
    2684     19080514 :   tree a2 = lookup_attribute ("optimize", DECL_ATTRIBUTES (newdecl));
    2685              :   /* An optimization attribute applied on a declaration after the
    2686              :      definition is likely not what the user wanted.  */
    2687     19080514 :   if (a2 != NULL_TREE
    2688       117522 :       && DECL_SAVED_TREE (olddecl) != NULL_TREE
    2689     19080548 :       && (a1 == NULL_TREE || !attribute_list_equal (a1, a2)))
    2690           26 :     warned |= warning (OPT_Wattributes,
    2691              :                        "optimization attribute on %qD follows "
    2692              :                        "definition but the attribute doesn%'t match",
    2693              :                        newdecl);
    2694              : 
    2695              :   /* Diagnose inline __attribute__ ((noinline)) which is silly.  */
    2696     19080514 :   if (DECL_DECLARED_INLINE_P (newdecl)
    2697      4825515 :       && DECL_UNINLINABLE (olddecl)
    2698     19080528 :       && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl)))
    2699           14 :     warned |= warning (OPT_Wattributes, "inline declaration of %qD follows "
    2700              :                        "declaration with attribute %<noinline%>", newdecl);
    2701     19080500 :   else if (DECL_DECLARED_INLINE_P (olddecl)
    2702      1615787 :            && DECL_UNINLINABLE (newdecl)
    2703     19080513 :            && lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl)))
    2704           13 :     warned |= warning (OPT_Wattributes, "declaration of %q+D with attribute "
    2705              :                        "%<noinline%> follows inline declaration", newdecl);
    2706              : 
    2707     19080514 :   return warned;
    2708     19080514 : }
    2709              : 
    2710              : /* Warn if signed left shift overflows.  We don't warn
    2711              :    about left-shifting 1 into the sign bit in C++14; cf.
    2712              :    <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3367.html#1457>
    2713              :    and don't warn for C++20 at all, as signed left shifts never
    2714              :    overflow.
    2715              :    LOC is a location of the shift; OP0 and OP1 are the operands.
    2716              :    Return true if an overflow is detected, false otherwise.  */
    2717              : 
    2718              : bool
    2719      2870522 : maybe_warn_shift_overflow (location_t loc, tree op0, tree op1)
    2720              : {
    2721      2870522 :   if (TREE_CODE (op0) != INTEGER_CST
    2722      2870483 :       || TREE_CODE (op1) != INTEGER_CST)
    2723              :     return false;
    2724              : 
    2725              :   /* match.pd could have narrowed the left shift already,
    2726              :      take type promotion into account.  */
    2727      2870453 :   tree type0 = lang_hooks.types.type_promotes_to (TREE_TYPE (op0));
    2728      2870453 :   unsigned int prec0 = TYPE_PRECISION (type0);
    2729              : 
    2730              :   /* Left-hand operand must be signed.  */
    2731      2870453 :   if (TYPE_OVERFLOW_WRAPS (type0) || cxx_dialect >= cxx20)
    2732              :     return false;
    2733              : 
    2734       346709 :   signop sign = SIGNED;
    2735       346709 :   if (TYPE_PRECISION (TREE_TYPE (op0)) < TYPE_PRECISION (type0))
    2736           16 :     sign = TYPE_SIGN (TREE_TYPE (op0));
    2737       346709 :   unsigned int min_prec = (wi::min_precision (wi::to_wide (op0), sign)
    2738       346709 :                            + TREE_INT_CST_LOW (op1));
    2739              :   /* Handle the case of left-shifting 1 into the sign bit.
    2740              :    * However, shifting 1 _out_ of the sign bit, as in
    2741              :    * INT_MIN << 1, is considered an overflow.
    2742              :    */
    2743       346709 :   if (!tree_int_cst_sign_bit (op0) && min_prec == prec0 + 1)
    2744              :     {
    2745              :       /* Never warn for C++14 onwards.  */
    2746          595 :       if (cxx_dialect >= cxx14)
    2747              :         return false;
    2748              :       /* Otherwise only if -Wshift-overflow=2.  But return
    2749              :          true to signal an overflow for the sake of integer
    2750              :          constant expressions.  */
    2751          445 :       if (warn_shift_overflow < 2)
    2752              :         return true;
    2753              :     }
    2754              : 
    2755       346185 :   bool overflowed = min_prec > prec0;
    2756       346185 :   if (overflowed && c_inhibit_evaluation_warnings == 0)
    2757          487 :     warning_at (loc, OPT_Wshift_overflow_,
    2758              :                 "result of %qE requires %u bits to represent, "
    2759              :                 "but %qT only has %u bits",
    2760              :                 build2_loc (loc, LSHIFT_EXPR, type0,
    2761              :                             fold_convert (type0, op0), op1),
    2762              :                 min_prec, type0, prec0);
    2763              : 
    2764              :   return overflowed;
    2765              : }
    2766              : 
    2767              : /* Warn about boolean expression compared with an integer value different
    2768              :    from true/false.  Warns also e.g. about "(i1 == i2) == 2".
    2769              :    LOC is the location of the comparison, CODE is its code, OP0 and OP1
    2770              :    are the operands of the comparison.  The caller must ensure that
    2771              :    either operand is a boolean expression.  */
    2772              : 
    2773              : void
    2774        97220 : maybe_warn_bool_compare (location_t loc, enum tree_code code, tree op0,
    2775              :                          tree op1)
    2776              : {
    2777        97220 :   if (TREE_CODE_CLASS (code) != tcc_comparison)
    2778              :     return;
    2779              : 
    2780        97220 :   tree f, cst;
    2781        97220 :   if (f = fold_for_warn (op0),
    2782        97220 :       TREE_CODE (f) == INTEGER_CST)
    2783              :     cst = op0 = f;
    2784        92777 :   else if (f = fold_for_warn (op1),
    2785        92777 :            TREE_CODE (f) == INTEGER_CST)
    2786              :     cst = op1 = f;
    2787              :   else
    2788              :     return;
    2789              : 
    2790        92944 :   if (!integer_zerop (cst) && !integer_onep (cst))
    2791              :     {
    2792          286 :       int sign = (TREE_CODE (op0) == INTEGER_CST
    2793          286 :                  ? tree_int_cst_sgn (cst) : -tree_int_cst_sgn (cst));
    2794          286 :       if (code == EQ_EXPR
    2795          234 :           || ((code == GT_EXPR || code == GE_EXPR) && sign < 0)
    2796          176 :           || ((code == LT_EXPR || code == LE_EXPR) && sign > 0))
    2797          148 :         warning_at (loc, OPT_Wbool_compare, "comparison of constant %qE "
    2798              :                     "with boolean expression is always false", cst);
    2799              :       else
    2800          138 :         warning_at (loc, OPT_Wbool_compare, "comparison of constant %qE "
    2801              :                     "with boolean expression is always true", cst);
    2802              :     }
    2803        92658 :   else if (integer_zerop (cst) || integer_onep (cst))
    2804              :     {
    2805              :       /* If the non-constant operand isn't of a boolean type, we
    2806              :          don't want to warn here.  */
    2807        92658 :       tree noncst = TREE_CODE (op0) == INTEGER_CST ? op1 : op0;
    2808              :       /* Handle booleans promoted to integers.  */
    2809        92658 :       if (bool_promoted_to_int_p (noncst))
    2810              :         /* Warn.  */;
    2811        92658 :       else if (TREE_CODE (TREE_TYPE (noncst)) != BOOLEAN_TYPE
    2812        92658 :                && !truth_value_p (TREE_CODE (noncst)))
    2813              :         return;
    2814              :       /* Do some magic to get the right diagnostics.  */
    2815        89964 :       bool flag = TREE_CODE (op0) == INTEGER_CST;
    2816        89964 :       flag = integer_zerop (cst) ? flag : !flag;
    2817        89964 :       if ((code == GE_EXPR && !flag) || (code == LE_EXPR && flag))
    2818           79 :         warning_at (loc, OPT_Wbool_compare, "comparison of constant %qE "
    2819              :                     "with boolean expression is always true", cst);
    2820        89885 :       else if ((code == LT_EXPR && !flag) || (code == GT_EXPR && flag))
    2821           93 :         warning_at (loc, OPT_Wbool_compare, "comparison of constant %qE "
    2822              :                     "with boolean expression is always false", cst);
    2823              :     }
    2824              : }
    2825              : 
    2826              : /* Warn if an argument at position param_pos is passed to a
    2827              :    restrict-qualified param, and it aliases with another argument.
    2828              :    Return true if a warning has been issued.  */
    2829              : 
    2830              : bool
    2831       125612 : warn_for_restrict (unsigned param_pos, tree *argarray, unsigned nargs)
    2832              : {
    2833       125612 :   tree arg = argarray[param_pos];
    2834       125612 :   if (TREE_VISITED (arg) || integer_zerop (arg))
    2835        57342 :     return false;
    2836              : 
    2837        68270 :   location_t loc = EXPR_LOC_OR_LOC (arg, input_location);
    2838        68270 :   gcc_rich_location richloc (loc);
    2839              : 
    2840        68270 :   unsigned i;
    2841        68270 :   auto_vec<int, 16> arg_positions;
    2842              : 
    2843       286949 :   for (i = 0; i < nargs; i++)
    2844              :     {
    2845       218679 :       if (i == param_pos)
    2846        68270 :         continue;
    2847              : 
    2848       150409 :       tree current_arg = argarray[i];
    2849       150409 :       if (operand_equal_p (arg, current_arg, 0))
    2850              :         {
    2851           73 :           TREE_VISITED (current_arg) = 1;
    2852           73 :           arg_positions.safe_push (i + 1);
    2853              :         }
    2854              :     }
    2855              : 
    2856       136540 :   if (arg_positions.is_empty ())
    2857              :     return false;
    2858              : 
    2859              :   int pos;
    2860          142 :   FOR_EACH_VEC_ELT (arg_positions, i, pos)
    2861              :     {
    2862           73 :       arg = argarray[pos - 1];
    2863           73 :       if (EXPR_HAS_LOCATION (arg))
    2864           51 :         richloc.add_range (EXPR_LOCATION (arg));
    2865              :     }
    2866              : 
    2867          207 :   return warning_n (&richloc, OPT_Wrestrict, arg_positions.length (),
    2868              :                     "passing argument %i to %qs-qualified parameter"
    2869              :                     " aliases with argument %Z",
    2870              :                     "passing argument %i to %qs-qualified parameter"
    2871              :                     " aliases with arguments %Z",
    2872              :                     param_pos + 1, "restrict", arg_positions.address (),
    2873              :                     arg_positions.length ());
    2874        68270 : }
    2875              : 
    2876              : /* Callback function to determine whether an expression TP or one of its
    2877              :    subexpressions comes from macro expansion.  Used to suppress bogus
    2878              :    warnings.  */
    2879              : 
    2880              : static tree
    2881         2404 : expr_from_macro_expansion_r (tree *tp, int *, void *)
    2882              : {
    2883         2404 :   if (CAN_HAVE_LOCATION_P (*tp)
    2884         3836 :       && from_macro_expansion_at (EXPR_LOCATION (*tp)))
    2885           20 :     return integer_zero_node;
    2886              : 
    2887              :   return NULL_TREE;
    2888              : }
    2889              : 
    2890              : /* Possibly warn when an if-else has identical branches.  */
    2891              : 
    2892              : static void
    2893          450 : do_warn_duplicated_branches (tree expr)
    2894              : {
    2895          450 :   tree thenb = COND_EXPR_THEN (expr);
    2896          450 :   tree elseb = COND_EXPR_ELSE (expr);
    2897              : 
    2898              :   /* Don't bother if any of the branches is missing.  */
    2899          450 :   if (thenb == NULL_TREE || elseb == NULL_TREE)
    2900           32 :     return;
    2901              : 
    2902              :   /* And don't warn for empty statements.  */
    2903          441 :   if (TREE_CODE (thenb) == NOP_EXPR
    2904           11 :       && TREE_TYPE (thenb) == void_type_node
    2905          452 :       && TREE_OPERAND (thenb, 0) == size_zero_node)
    2906              :     return;
    2907              : 
    2908              :   /* ... or empty branches.  */
    2909          430 :   if (TREE_CODE (thenb) == STATEMENT_LIST
    2910          430 :       && STATEMENT_LIST_HEAD (thenb) == NULL)
    2911              :     return;
    2912              : 
    2913              :   /* Compute the hash of the then branch.  */
    2914          418 :   inchash::hash hstate0 (0);
    2915          418 :   inchash::add_expr (thenb, hstate0);
    2916          418 :   hashval_t h0 = hstate0.end ();
    2917              : 
    2918              :   /* Compute the hash of the else branch.  */
    2919          418 :   inchash::hash hstate1 (0);
    2920          418 :   inchash::add_expr (elseb, hstate1);
    2921          418 :   hashval_t h1 = hstate1.end ();
    2922              : 
    2923              :   /* Compare the hashes.  */
    2924          418 :   if (h0 == h1
    2925          178 :       && operand_equal_p (thenb, elseb, OEP_LEXICOGRAPHIC
    2926              :                                         | OEP_ADDRESS_OF_SAME_FIELD)
    2927              :       /* Don't warn if any of the branches or their subexpressions comes
    2928              :          from a macro.  */
    2929          178 :       && !walk_tree_without_duplicates (&thenb, expr_from_macro_expansion_r,
    2930              :                                         NULL)
    2931          580 :       && !walk_tree_without_duplicates (&elseb, expr_from_macro_expansion_r,
    2932              :                                         NULL))
    2933          158 :     warning_at (EXPR_LOCATION (expr), OPT_Wduplicated_branches,
    2934              :                 "this condition has identical branches");
    2935              : }
    2936              : 
    2937              : /* Callback for c_genericize to implement -Wduplicated-branches.  */
    2938              : 
    2939              : tree
    2940         5932 : do_warn_duplicated_branches_r (tree *tp, int *, void *)
    2941              : {
    2942         5932 :   if (TREE_CODE (*tp) == COND_EXPR)
    2943          450 :     do_warn_duplicated_branches (*tp);
    2944         5932 :   return NULL_TREE;
    2945              : }
    2946              : 
    2947              : /* Implementation of -Wmultistatement-macros.  This warning warns about
    2948              :    cases when a macro expands to multiple statements not wrapped in
    2949              :    do {} while (0) or ({ }) and is used as a body of if/else/for/while
    2950              :    conditionals.  For example,
    2951              : 
    2952              :    #define DOIT x++; y++
    2953              : 
    2954              :    if (c)
    2955              :      DOIT;
    2956              : 
    2957              :    will increment y unconditionally.
    2958              : 
    2959              :    BODY_LOC is the location of the first token in the body after labels
    2960              :    have been parsed, NEXT_LOC is the location of the next token after the
    2961              :    body of the conditional has been parsed, and GUARD_LOC is the location
    2962              :    of the conditional.  */
    2963              : 
    2964              : void
    2965     28917317 : warn_for_multistatement_macros (location_t body_loc, location_t next_loc,
    2966              :                                 location_t guard_loc, enum rid keyword)
    2967              : {
    2968     28917317 :   if (!warn_multistatement_macros)
    2969     28917209 :     return;
    2970              : 
    2971              :   /* Ain't got time to waste.  We only care about macros here.  */
    2972       400198 :   if (!from_macro_expansion_at (body_loc)
    2973       521105 :       || !from_macro_expansion_at (next_loc))
    2974       287181 :     return;
    2975              : 
    2976              :   /* Let's skip macros defined in system headers.  */
    2977       113017 :   if (in_system_header_at (body_loc)
    2978       224410 :       || in_system_header_at (next_loc))
    2979         1678 :     return;
    2980              : 
    2981              :   /* Find the actual tokens in the macro definition.  BODY_LOC and
    2982              :      NEXT_LOC have to come from the same spelling location, but they
    2983              :      will resolve to different locations in the context of the macro
    2984              :      definition.  */
    2985       111339 :   location_t body_loc_exp
    2986       111339 :     = linemap_resolve_location (line_table, body_loc,
    2987              :                                 LRK_MACRO_DEFINITION_LOCATION, NULL);
    2988       111339 :   location_t next_loc_exp
    2989       111339 :     = linemap_resolve_location (line_table, next_loc,
    2990              :                                 LRK_MACRO_DEFINITION_LOCATION, NULL);
    2991       111339 :   location_t guard_loc_exp
    2992       111339 :     = linemap_resolve_location (line_table, guard_loc,
    2993              :                                 LRK_MACRO_DEFINITION_LOCATION, NULL);
    2994              : 
    2995              :   /* These are some funky cases we don't want to warn about.  */
    2996       111339 :   if (body_loc_exp == guard_loc_exp
    2997       111339 :       || next_loc_exp == guard_loc_exp
    2998        93166 :       || body_loc_exp == next_loc_exp)
    2999              :     return;
    3000              : 
    3001              :   /* Find the macro maps for the macro expansions.  */
    3002        93078 :   const line_map *body_map = linemap_lookup (line_table, body_loc);
    3003        93078 :   const line_map *next_map = linemap_lookup (line_table, next_loc);
    3004        93078 :   const line_map *guard_map = linemap_lookup (line_table, guard_loc);
    3005              : 
    3006              :   /* Now see if the following token (after the body) is coming from the
    3007              :      same macro expansion.  If it is, it might be a problem.  */
    3008        93078 :   if (body_map != next_map)
    3009              :     return;
    3010              : 
    3011              :   /* The conditional itself must not come from the same expansion, because
    3012              :      we don't want to warn about
    3013              :      #define IF if (x) x++; y++
    3014              :      and similar.  */
    3015        75491 :   if (guard_map == body_map)
    3016              :     return;
    3017              : 
    3018              :   /* Handle the case where NEXT and BODY come from the same expansion while
    3019              :      GUARD doesn't, yet we shouldn't warn.  E.g.
    3020              : 
    3021              :        #define GUARD if (...)
    3022              :        #define GUARD2 GUARD
    3023              : 
    3024              :      and in the definition of another macro:
    3025              : 
    3026              :        GUARD2
    3027              :         foo ();
    3028              :        return 1;
    3029              :    */
    3030          212 :   while (linemap_macro_expansion_map_p (guard_map))
    3031              :     {
    3032          104 :       const line_map_macro *mm = linemap_check_macro (guard_map);
    3033          104 :       guard_loc_exp = mm->get_expansion_point_location ();
    3034          104 :       guard_map = linemap_lookup (line_table, guard_loc_exp);
    3035          104 :       if (guard_map == body_map)
    3036              :         return;
    3037              :     }
    3038              : 
    3039          108 :   auto_diagnostic_group d;
    3040          108 :   if (warning_at (body_loc, OPT_Wmultistatement_macros,
    3041              :                   "macro expands to multiple statements"))
    3042          108 :     inform (guard_loc, "some parts of macro expansion are not guarded by "
    3043              :             "this %qs clause", guard_tinfo_to_string (keyword));
    3044          108 : }
    3045              : 
    3046              : /* Return struct or union type if the alignment of data member, FIELD,
    3047              :    is less than the alignment of TYPE.  Otherwise, return NULL_TREE.
    3048              :    If RVALUE is true, only arrays evaluate to pointers.  */
    3049              : 
    3050              : static tree
    3051     11771215 : check_alignment_of_packed_member (tree type, tree field, bool rvalue)
    3052              : {
    3053              :   /* Check alignment of the data member.  */
    3054     11771215 :   if (TREE_CODE (field) == FIELD_DECL
    3055     11574566 :       && (DECL_PACKED (field) || TYPE_PACKED (TREE_TYPE (field)))
    3056              :       /* Ignore FIELDs not laid out yet.  */
    3057         1599 :       && DECL_FIELD_OFFSET (field)
    3058     11772802 :       && (!rvalue || TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE))
    3059              :     {
    3060              :       /* Check the expected alignment against the field alignment.  */
    3061         1461 :       unsigned int type_align = min_align_of_type (type);
    3062         1461 :       tree context = DECL_CONTEXT (field);
    3063         1461 :       unsigned int record_align = min_align_of_type (context);
    3064         1461 :       if (record_align < type_align)
    3065              :         return context;
    3066         1159 :       tree field_off = byte_position (field);
    3067         1159 :       if (!multiple_of_p (TREE_TYPE (field_off), field_off,
    3068         2318 :                           size_int (type_align)))
    3069              :         return context;
    3070              :     }
    3071              : 
    3072              :   return NULL_TREE;
    3073              : }
    3074              : 
    3075              : /* Return struct or union type if the right hand value, RHS,
    3076              :    is an address which takes the unaligned address of packed member
    3077              :    of struct or union when assigning to TYPE.
    3078              :    Otherwise, return NULL_TREE.  */
    3079              : 
    3080              : static tree
    3081     94531519 : check_address_of_packed_member (tree type, tree rhs)
    3082              : {
    3083     94531519 :   bool rvalue = true;
    3084     94531519 :   bool indirect = false;
    3085              : 
    3086     94531519 :   if (INDIRECT_REF_P (rhs))
    3087              :     {
    3088       691154 :       rhs = TREE_OPERAND (rhs, 0);
    3089       691154 :       STRIP_NOPS (rhs);
    3090       691154 :       indirect = true;
    3091              :     }
    3092              : 
    3093     94531519 :   if (TREE_CODE (rhs) == ADDR_EXPR)
    3094              :     {
    3095     36197681 :       rhs = TREE_OPERAND (rhs, 0);
    3096     36197681 :       rvalue = indirect;
    3097              :     }
    3098              : 
    3099     94531519 :   if (!POINTER_TYPE_P (type))
    3100              :     return NULL_TREE;
    3101              : 
    3102     94531519 :   type = TREE_TYPE (type);
    3103              : 
    3104     94531519 :   tree context = NULL_TREE;
    3105              : 
    3106              :   /* Check alignment of the object.  */
    3107    105298458 :   while (handled_component_p (rhs))
    3108              :     {
    3109     12374726 :       if (TREE_CODE (rhs) == COMPONENT_REF)
    3110              :         {
    3111     11771215 :           tree field = TREE_OPERAND (rhs, 1);
    3112     11771215 :           context = check_alignment_of_packed_member (type, field, rvalue);
    3113     11771215 :           if (context)
    3114              :             break;
    3115              :         }
    3116     12374328 :       if (TREE_CODE (TREE_TYPE (rhs)) == ARRAY_TYPE)
    3117              :         rvalue = false;
    3118     11786497 :       if (rvalue)
    3119              :         return NULL_TREE;
    3120     10766939 :       rhs = TREE_OPERAND (rhs, 0);
    3121              :     }
    3122              : 
    3123              :   return context;
    3124              : }
    3125              : 
    3126              : /* Check and warn if the right hand value, RHS,
    3127              :    is an address which takes the unaligned address of packed member
    3128              :    of struct or union when assigning to TYPE.  */
    3129              : 
    3130              : static void
    3131     99001695 : check_and_warn_address_of_packed_member (tree type, tree rhs)
    3132              : {
    3133     99534443 :   bool nop_p = false;
    3134              :   tree orig_rhs;
    3135              : 
    3136              :   do
    3137              :     {
    3138    177344738 :       while (TREE_CODE (rhs) == COMPOUND_EXPR)
    3139       756117 :         rhs = TREE_OPERAND (rhs, 1);
    3140    176588621 :       orig_rhs = rhs;
    3141    176588621 :       STRIP_NOPS (rhs);
    3142    176588621 :       nop_p |= orig_rhs != rhs;
    3143              :     }
    3144    176588621 :   while (orig_rhs != rhs);
    3145              : 
    3146     99534443 :   if (TREE_CODE (rhs) == COND_EXPR)
    3147              :     {
    3148              :       /* Check the THEN path.  */
    3149       532748 :       check_and_warn_address_of_packed_member
    3150       532748 :         (type, TREE_OPERAND (rhs, 1));
    3151              : 
    3152              :       /* Check the ELSE path.  */
    3153       532748 :       check_and_warn_address_of_packed_member
    3154       532748 :         (type, TREE_OPERAND (rhs, 2));
    3155              :     }
    3156              :   else
    3157              :     {
    3158     99001695 :       if (nop_p)
    3159              :         {
    3160     76481648 :           switch (TREE_CODE (rhs))
    3161              :             {
    3162              :             case ADDR_EXPR:
    3163              :               /* Address is taken.   */
    3164              :             case PARM_DECL:
    3165              :             case VAR_DECL:
    3166              :               /* Pointer conversion.  */
    3167              :               break;
    3168              :             case CALL_EXPR:
    3169              :               /* Function call. */
    3170              :               break;
    3171              :             default:
    3172              :               return;
    3173              :             }
    3174              :         }
    3175              : 
    3176     94531519 :       tree context
    3177     94531519 :         = check_address_of_packed_member (type, rhs);
    3178     94531519 :       if (context)
    3179              :         {
    3180          398 :           location_t loc = EXPR_LOC_OR_LOC (rhs, input_location);
    3181          398 :           warning_at (loc, OPT_Waddress_of_packed_member,
    3182              :                       "taking address of packed member of %qT may result "
    3183              :                       "in an unaligned pointer value",
    3184              :                       context);
    3185              :         }
    3186              :     }
    3187              : }
    3188              : 
    3189              : /* Warn if the right hand value, RHS,
    3190              :    is an address which takes the unaligned address of packed member
    3191              :    of struct or union when assigning to TYPE.  */
    3192              : 
    3193              : void
    3194    470739763 : warn_for_address_of_packed_member (tree type, tree rhs)
    3195              : {
    3196    470739763 :   if (!warn_address_of_packed_member)
    3197              :     return;
    3198              : 
    3199              :   /* Don't warn if we don't assign RHS to a pointer.  */
    3200    470559827 :   if (!POINTER_TYPE_P (type))
    3201              :     return;
    3202              : 
    3203     98468947 :   check_and_warn_address_of_packed_member (type, rhs);
    3204              : }
    3205              : 
    3206              : /* Return EXPR + 1.  Convenience helper used below.  */
    3207              : 
    3208              : static inline tree
    3209           22 : plus_one (tree expr)
    3210              : {
    3211           22 :   tree type = TREE_TYPE (expr);
    3212           22 :   return fold_build2 (PLUS_EXPR, type, expr, build_int_cst (type, 1));
    3213              : }
    3214              : 
    3215              : /* Try to strip the expressions from around a VLA bound added internally
    3216              :    to make it fit the domain mold, including any casts, and return
    3217              :    the result.  The goal is to obtain the PARM_DECL the VLA bound may
    3218              :    refer to.  */
    3219              : 
    3220              : static tree
    3221         9246 : vla_bound_parm_decl (tree expr)
    3222              : {
    3223         9246 :   if (!expr)
    3224              :     return NULL_TREE;
    3225              : 
    3226         9125 :   if (TREE_CODE (expr) == NOP_EXPR)
    3227           67 :     expr = TREE_OPERAND (expr, 0);
    3228         9125 :   if (TREE_CODE (expr) == PLUS_EXPR
    3229         9125 :       && integer_all_onesp (TREE_OPERAND (expr, 1)))
    3230              :     {
    3231           53 :       expr = TREE_OPERAND (expr, 0);
    3232           53 :       if (TREE_CODE (expr) == NOP_EXPR)
    3233           53 :         expr = TREE_OPERAND (expr, 0);
    3234              :     }
    3235         9125 :   if (TREE_CODE (expr) == SAVE_EXPR)
    3236              :     {
    3237           53 :       expr = TREE_OPERAND (expr, 0);
    3238           53 :       if (TREE_CODE (expr) == NOP_EXPR)
    3239            0 :         expr = TREE_OPERAND (expr, 0);
    3240              :     }
    3241              :   return expr;
    3242              : }
    3243              : 
    3244              : /* Diagnose mismatches in VLA bounds between function parameters NEWPARMS
    3245              :    of pointer types on a redeclaration of a function previously declared
    3246              :    with CURPARMS at ORIGLOC.  */
    3247              : 
    3248              : static void
    3249       609761 : warn_parm_ptrarray_mismatch (location_t origloc, tree curparms, tree newparms)
    3250              : {
    3251              :   /* Maps each named integral parameter seen so far to its position
    3252              :      in the argument list; used to associate VLA sizes with arguments.  */
    3253       609761 :   hash_map<tree, unsigned> curparm2pos;
    3254       609761 :   hash_map<tree, unsigned> newparm2pos;
    3255              : 
    3256       609761 :   unsigned parmpos = 1;
    3257      1722647 :   for (tree curp = curparms, newp = newparms; curp && newp;
    3258      1112886 :        curp = TREE_CHAIN (curp), newp = TREE_CHAIN (newp), ++parmpos)
    3259              :     {
    3260      1112888 :       tree curtyp = TREE_TYPE (curp), newtyp = TREE_TYPE (newp);
    3261      1112888 :       if (INTEGRAL_TYPE_P (curtyp))
    3262              :         {
    3263              :           /* Only add named parameters; unnamed ones cannot be referred
    3264              :              to in VLA bounds.  */
    3265       251763 :           if (DECL_NAME (curp))
    3266       240064 :             curparm2pos.put (curp, parmpos);
    3267       251763 :           if (DECL_NAME (newp))
    3268       239589 :             newparm2pos.put (newp, parmpos);
    3269              : 
    3270      1364615 :           continue;
    3271              :         }
    3272              : 
    3273              :       /* The parameter types should match at this point so only test one.  */
    3274       861125 :       if (TREE_CODE (curtyp) != POINTER_TYPE)
    3275       311690 :         continue;
    3276              : 
    3277       672300 :       do
    3278              :         {
    3279       672300 :           curtyp = TREE_TYPE (curtyp);
    3280       672300 :           newtyp = TREE_TYPE (newtyp);
    3281              : 
    3282       672300 :           if (!newtyp)
    3283              :             /* Bail on error.  */
    3284            2 :             return;
    3285              :         }
    3286       672298 :       while (TREE_CODE (curtyp) == POINTER_TYPE
    3287       672298 :              && TREE_CODE (newtyp) == POINTER_TYPE);
    3288              : 
    3289       549433 :       if (TREE_CODE (curtyp) != ARRAY_TYPE
    3290           53 :           || TREE_CODE (newtyp) != ARRAY_TYPE)
    3291              :         {
    3292       549380 :           if (curtyp == error_mark_node
    3293       549380 :               || newtyp == error_mark_node)
    3294              :             /* Bail on error.  */
    3295              :             return;
    3296              : 
    3297       549380 :           continue;
    3298              :         }
    3299              : 
    3300           53 :       tree curdom = TYPE_DOMAIN (curtyp), newdom = TYPE_DOMAIN (newtyp);
    3301           53 :       tree curbnd = curdom ? TYPE_MAX_VALUE (curdom) : NULL_TREE;
    3302           53 :       tree newbnd = newdom ? TYPE_MAX_VALUE (newdom) : NULL_TREE;
    3303              : 
    3304           53 :       if (DECL_P (curp))
    3305           53 :         origloc = DECL_SOURCE_LOCATION (curp);
    3306            0 :       else if (EXPR_P (curp) && EXPR_HAS_LOCATION (curp))
    3307            0 :         origloc = EXPR_LOCATION (curp);
    3308              : 
    3309              :       /* The location of the parameter in the current redeclaration.  */
    3310           53 :       location_t newloc = DECL_SOURCE_LOCATION (newp);
    3311           53 :       if (origloc == UNKNOWN_LOCATION)
    3312            0 :         origloc = newloc;
    3313              : 
    3314              :       /* Issue -Warray-parameter unless one or more mismatches involves
    3315              :          a VLA bound; then issue -Wvla-parameter.  */
    3316           53 :       int opt = OPT_Warray_parameter_;
    3317              :       /* Traverse the two array types looking for variable bounds and
    3318              :          comparing the two in each pair for mismatches either in their
    3319              :          positions in the function parameter list or lexicographically
    3320              :          for others.  Record the 1-based parameter position of each
    3321              :          mismatch in BNDVEC, and the location of each parameter in
    3322              :          the mismatch in WARNLOC (for the new parameter list) and
    3323              :          NOTELOC (for the current parameter list).  */
    3324           53 :       unsigned bndpos = 1;
    3325           53 :       auto_vec<int> bndvec;
    3326           53 :       gcc_rich_location warnloc (newloc);
    3327           53 :       gcc_rich_location noteloc (origloc);
    3328          199 :       for ( ; curtyp || newtyp;
    3329              :             ++bndpos,
    3330          146 :               curbnd = curdom ? TYPE_MAX_VALUE (curdom) : NULL_TREE,
    3331          146 :               newbnd = newdom ? TYPE_MAX_VALUE (newdom) : NULL_TREE)
    3332              :         {
    3333              :           /* Try to strip each bound down to the PARM_DECL if it does
    3334              :              correspond to one.  Either bound can be null if it's
    3335              :              unspecified (i.e., has the [*] form).  */
    3336          146 :           curbnd = vla_bound_parm_decl (curbnd);
    3337          146 :           newbnd = vla_bound_parm_decl (newbnd);
    3338              : 
    3339              :           /* Peel the current bound off CURTYP and NEWTYP, skipping
    3340              :              over any subsequent pointer types.  */
    3341          146 :           if (curtyp && TREE_CODE (curtyp) == ARRAY_TYPE)
    3342              :             {
    3343          103 :               do
    3344          103 :                 curtyp = TREE_TYPE (curtyp);
    3345          103 :               while (TREE_CODE (curtyp) == POINTER_TYPE);
    3346           93 :               if (TREE_CODE (curtyp) == ARRAY_TYPE)
    3347           40 :                 curdom = TYPE_DOMAIN (curtyp);
    3348              :               else
    3349              :                 curdom = NULL_TREE;
    3350              :             }
    3351              :           else
    3352              :             curtyp = NULL_TREE;
    3353              : 
    3354          146 :           if (newtyp && TREE_CODE (newtyp) == ARRAY_TYPE)
    3355              :             {
    3356          103 :               do
    3357          103 :                 newtyp = TREE_TYPE (newtyp);
    3358          103 :               while (TREE_CODE (newtyp) == POINTER_TYPE);
    3359           93 :               if (TREE_CODE (newtyp) == ARRAY_TYPE)
    3360           40 :                 newdom = TYPE_DOMAIN (newtyp);
    3361              :               else
    3362              :                 newdom = NULL_TREE;
    3363              :             }
    3364              :           else
    3365              :             newtyp = NULL_TREE;
    3366              : 
    3367              :           /* Move on to the next bound if this one is unspecified.  */
    3368          146 :           if (!curbnd && !newbnd)
    3369           53 :             continue;
    3370              : 
    3371              :           /* Try to find each bound in the parameter list.  */
    3372           93 :           const unsigned* const pcurbndpos = curparm2pos.get (curbnd);
    3373           93 :           const unsigned* const pnewbndpos = newparm2pos.get (newbnd);
    3374              :           /* Move on if both bounds refer to the same parameter.  */
    3375           93 :           if (pcurbndpos && pnewbndpos && *pcurbndpos == *pnewbndpos)
    3376            0 :             continue;
    3377              : 
    3378              :           /* Move on if the bounds look the same.  */
    3379          148 :           if (!pcurbndpos && !pnewbndpos
    3380           93 :               && curbnd && newbnd
    3381          171 :               && operand_equal_p (curbnd, newbnd,
    3382              :                                   OEP_DECL_NAME | OEP_LEXICOGRAPHIC))
    3383           55 :             continue;
    3384              : 
    3385           38 :           if ((curbnd && TREE_CODE (curbnd) != INTEGER_CST)
    3386           26 :               || (newbnd && TREE_CODE (newbnd) != INTEGER_CST))
    3387           38 :             opt = OPT_Wvla_parameter;
    3388              : 
    3389              :           /* Record the mismatch.  */
    3390           38 :           bndvec.safe_push (bndpos);
    3391              :           /* Underline the bounding parameter in the declaration.  */
    3392           38 :           if (curbnd && TREE_CODE (curbnd) == PARM_DECL)
    3393            0 :             noteloc.add_range (DECL_SOURCE_LOCATION (curbnd));
    3394           38 :           if (newbnd && TREE_CODE (newbnd) == PARM_DECL)
    3395            0 :             warnloc.add_range (DECL_SOURCE_LOCATION (newbnd));
    3396              :         }
    3397              : 
    3398           53 :       const unsigned nbnds = bndvec.length ();
    3399           34 :       if (!nbnds)
    3400           19 :         continue;
    3401              : 
    3402              :       /* Use attr_access to format the parameter types.  */
    3403           34 :       attr_access spec = { };
    3404           34 :       const std::string newparmstr = spec.array_as_string (TREE_TYPE (newp));
    3405           34 :       const std::string curparmstr = spec.array_as_string (TREE_TYPE (curp));
    3406              : 
    3407           34 :       if (warning_n (&warnloc, opt, nbnds,
    3408              :                      "mismatch in bound %Z of argument %u declared as %s",
    3409              :                      "mismatch in bounds %Z of argument %u declared as %s",
    3410              :                      bndvec.address (), nbnds, parmpos, newparmstr.c_str ()))
    3411           32 :         inform (&noteloc, "previously declared as %s",    curparmstr.c_str ());
    3412           53 :     }
    3413       609761 : }
    3414              : 
    3415              : /* Format EXPR if nonnull and return the formatted string.  If EXPR is
    3416              :    null return DFLT.  */
    3417              : 
    3418              : static inline const char*
    3419          310 : expr_to_str (pretty_printer &pp, tree expr, const char *dflt)
    3420              : {
    3421          310 :   if (!expr)
    3422              :     return dflt;
    3423              : 
    3424          310 :   dump_generic_node (&pp, expr, 0, TDF_VOPS | TDF_MEMSYMS, false);
    3425          310 :   return pp_formatted_text (&pp);
    3426              : }
    3427              : 
    3428              : /* Helper for warn_parms_array_mismatch.  Compare the mappings of
    3429              :    two function parameters and diagnose mismatches.  ORIGLOC is the
    3430              :    location of the first function declaration.  CURP and NEWP are the
    3431              :    parameters in the first and second function declarators,
    3432              :    respectively.  PARMPOS is the position of the parameters within the
    3433              :    list of parameter declarations.  BUILTIN is true if the function is
    3434              :    a builtin.  */
    3435              : 
    3436              : static void
    3437        99110 : warn_parm_array_mismatch (location_t origloc, rdwr_map *cur_idx,
    3438              :                           rdwr_map *new_idx, tree curp, tree newp,
    3439              :                           unsigned parmpos, bool builtin)
    3440              : {
    3441              :   /* Create an empty access specification and use it for pointers with
    3442              :      no spec of their own.  */
    3443        99110 :   attr_access ptr_spec = { };
    3444              : 
    3445              :   /* Only check pointers and C++ references.  */
    3446        99110 :   tree curptype = TREE_TYPE (curp);
    3447        99110 :   tree newptype = TREE_TYPE (newp);
    3448        99110 :   if (!POINTER_TYPE_P (curptype) || !POINTER_TYPE_P (newptype))
    3449        99050 :     return;
    3450              : 
    3451              :   /* Skip mismatches in __builtin_va_list that is commonly
    3452              :      an array but that in declarations of built-ins decays
    3453              :      to a pointer.  */
    3454        97870 :   if (builtin && TREE_TYPE (newptype) == TREE_TYPE (va_list_type_node))
    3455              :     return;
    3456              : 
    3457              :   /* Access specs for the argument on the current (previous) and
    3458              :      new (to replace the current) declarations.  Either may be null,
    3459              :      indicating the parameter is an ordinary pointer with no size
    3460              :      associated with it.  */
    3461        60999 :   attr_access *cura = cur_idx->get (parmpos);
    3462        60999 :   attr_access *newa = new_idx->get (parmpos);
    3463              : 
    3464        60999 :   if (!newa)
    3465              :     {
    3466              :       /* Continue if both parameters are pointers with no size
    3467              :          associated with them.  */
    3468        56763 :       if (!cura)
    3469              :         return;
    3470              : 
    3471              :       /* Otherwise point at PTR_SPEC and set its parameter pointer
    3472              :          and number.  */
    3473          119 :       newa = &ptr_spec;
    3474          119 :       newa->ptr = newp;
    3475          119 :       newa->ptrarg = parmpos;
    3476              :     }
    3477         4236 :   else if (!cura)
    3478              :     {
    3479           24 :       cura = &ptr_spec;
    3480           24 :       cura->ptr = curp;
    3481           24 :       cura->ptrarg = parmpos;
    3482              :     }
    3483              : 
    3484              :   /* Set if the parameter is [re]declared as a VLA.  */
    3485         4355 :   const bool cur_vla_p = cura->size || cura->minsize == HOST_WIDE_INT_M1U;
    3486         4355 :   const bool new_vla_p = newa->size || newa->minsize == HOST_WIDE_INT_M1U;
    3487              : 
    3488         4355 :   if (DECL_P (curp))
    3489         4355 :     origloc = DECL_SOURCE_LOCATION (curp);
    3490            0 :   else if (EXPR_P (curp) && EXPR_HAS_LOCATION (curp))
    3491            0 :     origloc = EXPR_LOCATION (curp);
    3492              : 
    3493              :   /* The location of the parameter in the current redeclaration.  */
    3494         4355 :   location_t newloc = DECL_SOURCE_LOCATION (newp);
    3495         4355 :   if (origloc == UNKNOWN_LOCATION)
    3496            0 :     origloc = newloc;
    3497              : 
    3498         4355 :   const std::string newparmstr = newa->array_as_string (newptype);
    3499         4355 :   const std::string curparmstr = cura->array_as_string (curptype);
    3500         4355 :   if (new_vla_p && !cur_vla_p)
    3501              :     {
    3502           30 :       if (warning_at (newloc, OPT_Wvla_parameter,
    3503              :                       "argument %u of type %s "
    3504              :                       "declared as a variable length array",
    3505              :                       parmpos + 1, newparmstr.c_str ()))
    3506           53 :         inform (origloc,
    3507              :                 (cura == &ptr_spec
    3508              :                  ? G_("previously declared as a pointer %s")
    3509              :                  : G_("previously declared as an ordinary array %s")),
    3510              :                 curparmstr.c_str ());
    3511           30 :       return;
    3512              :     }
    3513              : 
    3514         4325 :   if (newa == &ptr_spec)
    3515              :     {
    3516              :       /* The new declaration uses the pointer form.  Detect mismatches
    3517              :          between the pointer and a previous array or VLA forms.  */
    3518          119 :       if (cura->minsize == HOST_WIDE_INT_M1U)
    3519              :         {
    3520              :           /* Diagnose a pointer/VLA mismatch.  */
    3521            0 :           if (warning_at (newloc, OPT_Wvla_parameter,
    3522              :                           "argument %u of type %s declared as a pointer",
    3523              :                           parmpos + 1, newparmstr.c_str ()))
    3524            0 :             inform (origloc,
    3525              :                     "previously declared as a variable length array %s",
    3526              :                     curparmstr.c_str ());
    3527            0 :           return;
    3528              :         }
    3529              : 
    3530          119 :       if (cura->minsize && cura->minsize != HOST_WIDE_INT_M1U)
    3531              :         {
    3532              :           /* Diagnose mismatches between arrays with a constant
    3533              :              bound and pointers.  */
    3534            4 :           if (warning_at (newloc, OPT_Warray_parameter_,
    3535              :                           "argument %u of type %s declared as a pointer",
    3536              :                           parmpos + 1, newparmstr.c_str ()))
    3537            2 :             inform (origloc, "previously declared as an array %s",
    3538              :                     curparmstr.c_str ());
    3539            4 :           return;
    3540              :         }
    3541              :     }
    3542              : 
    3543         4321 :   if (!new_vla_p && cur_vla_p)
    3544              :     {
    3545            7 :       if (warning_at (newloc, OPT_Wvla_parameter,
    3546              :                       "argument %u of type %s declared as an ordinary array",
    3547              :                       parmpos + 1, newparmstr.c_str ()))
    3548            3 :         inform (origloc, "previously declared as a variable length array %s",
    3549              :                 curparmstr.c_str ());
    3550            7 :       return;
    3551              :     }
    3552              : 
    3553              :   /* Move on to the next pair of parameters if both of the current
    3554              :      pair are VLAs with a single variable bound that refers to
    3555              :      a parameter at the same position.  */
    3556          376 :   if (newa->size && cura->size
    3557          375 :       && newa->sizarg != UINT_MAX
    3558           76 :       && newa->sizarg == cura->sizarg
    3559           70 :       && newa->minsize == cura->minsize
    3560         4370 :       && !TREE_PURPOSE (newa->size) && !TREE_PURPOSE (cura->size))
    3561              :     return;
    3562              : 
    3563         4314 :   if (newa->size || cura->size)
    3564              :     {
    3565          378 :       unsigned newunspec, curunspec;
    3566          378 :       unsigned newbnds = newa->vla_bounds (&newunspec) + newunspec;
    3567          378 :       unsigned curbnds = cura->vla_bounds (&curunspec) + curunspec;
    3568              : 
    3569          378 :       if (newbnds != curbnds)
    3570              :         {
    3571            5 :           if (warning_n (newloc, OPT_Wvla_parameter, newbnds,
    3572              :                          "argument %u of type %s declared with "
    3573              :                          "%u variable bound",
    3574              :                          "argument %u of type %s declared with "
    3575              :                          "%u variable bounds",
    3576              :                          parmpos + 1, newparmstr.c_str (),
    3577              :                          newbnds))
    3578            5 :             inform_n (origloc, curbnds,
    3579              :                       "previously declared as %s with %u variable bound",
    3580              :                       "previously declared as %s with %u variable bounds",
    3581              :                       curparmstr.c_str (), curbnds);
    3582           14 :           return;
    3583              :         }
    3584              : 
    3585          373 :       if (newunspec > curunspec)
    3586              :         {
    3587            9 :           location_t warnloc = newloc, noteloc = origloc;
    3588            9 :           const char *warnparmstr = newparmstr.c_str ();
    3589            9 :           const char *noteparmstr = curparmstr.c_str ();
    3590            9 :           unsigned warnunspec = newunspec, noteunspec = curunspec;
    3591              : 
    3592            9 :           if (warning_n (warnloc, OPT_Wvla_parameter, warnunspec,
    3593              :                          "argument %u of type %s declared with "
    3594              :                          "%u unspecified variable bound",
    3595              :                          "argument %u of type %s declared with "
    3596              :                          "%u unspecified variable bounds",
    3597              :                          parmpos + 1, warnparmstr, warnunspec))
    3598              :             {
    3599            8 :               if (warnloc == newloc)
    3600            8 :                 inform_n (noteloc, noteunspec,
    3601              :                           "previously declared as %s with "
    3602              :                           "%u unspecified variable bound",
    3603              :                           "previously declared as %s with "
    3604              :                           "%u unspecified variable bounds",
    3605              :                           noteparmstr, noteunspec);
    3606              :               else
    3607              :                 inform_n (noteloc, noteunspec,
    3608              :                           "subsequently declared as %s with "
    3609              :                           "%u unspecified variable bound",
    3610              :                           "subsequently declared as %s with "
    3611              :                           "%u unspecified variable bounds",
    3612              :                           noteparmstr, noteunspec);
    3613              :             }
    3614            9 :           return;
    3615              :         }
    3616              :     }
    3617              : 
    3618              :   /* Iterate over the lists of VLA variable bounds, comparing each
    3619              :      pair for equality, and diagnosing mismatches.  */
    3620         8777 :   for (tree newvbl = newa->size, curvbl = cura->size; newvbl && curvbl;
    3621         4477 :        newvbl = TREE_CHAIN (newvbl), curvbl = TREE_CHAIN (curvbl))
    3622              :     {
    3623         4477 :       tree newpos = TREE_PURPOSE (newvbl);
    3624         4477 :       tree curpos = TREE_PURPOSE (curvbl);
    3625              : 
    3626         4477 :       tree newbnd = vla_bound_parm_decl (TREE_VALUE (newvbl));
    3627         4477 :       tree curbnd = vla_bound_parm_decl (TREE_VALUE (curvbl));
    3628              : 
    3629         4477 :       if (newpos == curpos && newbnd == curbnd)
    3630              :         /* In the expected case when both bounds either refer to
    3631              :            the same positional parameter or when neither does,
    3632              :            and both are the same expression they are necessarily
    3633              :            the same.  */
    3634         4401 :         continue;
    3635              : 
    3636          155 :       pretty_printer pp1, pp2;
    3637          155 :       const char* const newbndstr = expr_to_str (pp1, newbnd, "*");
    3638          155 :       const char* const curbndstr = expr_to_str (pp2, curbnd, "*");
    3639              : 
    3640          155 :       if (!newpos != !curpos
    3641          155 :           || (newpos && !tree_int_cst_equal (newpos, curpos)))
    3642              :         {
    3643              :           /* Diagnose a mismatch between a specified VLA bound and
    3644              :              an unspecified one.  This can only happen in the most
    3645              :              significant bound.
    3646              : 
    3647              :              Distinguish between the common case of bounds that are
    3648              :              other function parameters such as in
    3649              :                f (int n, int[n]);
    3650              :              and others.  */
    3651              : 
    3652           21 :           gcc_rich_location richloc (newloc);
    3653           21 :           bool warned;
    3654           21 :           if (newpos)
    3655              :             {
    3656              :               /* Also underline the VLA bound argument.  */
    3657            4 :               richloc.add_range (DECL_SOURCE_LOCATION (newbnd));
    3658            4 :               warned = warning_at (&richloc, OPT_Wvla_parameter,
    3659              :                                    "argument %u of type %s "
    3660              :                                    "declared with mismatched bound argument %E",
    3661              :                                    parmpos + 1, newparmstr.c_str (),
    3662              :                                    plus_one (newpos));
    3663              :             }
    3664              :           else
    3665           17 :             warned = warning_at (&richloc, OPT_Wvla_parameter,
    3666              :                                  "argument %u of type %s "
    3667              :                                  "declared with mismatched bound %qs",
    3668              :                                  parmpos + 1, newparmstr.c_str (),
    3669              :                                  newbndstr);
    3670              : 
    3671           21 :           if (warned)
    3672              :             {
    3673           21 :               gcc_rich_location richloc (origloc);
    3674           21 :               if (curpos)
    3675              :                 {
    3676              :                   /* Also underline the VLA bound argument.  */
    3677           18 :                   richloc.add_range (DECL_SOURCE_LOCATION (curbnd));
    3678           18 :                   inform (&richloc,
    3679              :                           "previously declared as %s with bound argument %E",
    3680              :                           curparmstr.c_str (), plus_one (curpos));
    3681              :                 }
    3682              :               else
    3683            3 :                 inform (&richloc,
    3684              :                         "previously declared as %s with bound %qs",
    3685              :                         curparmstr.c_str (), curbndstr);
    3686              : 
    3687           21 :               continue;
    3688           21 :             }
    3689           21 :         }
    3690              : 
    3691          134 :       if (!newpos && newbnd && curbnd)
    3692              :         {
    3693              :           /* The VLA bounds don't refer to other function parameters.
    3694              :              Compare them lexicographically to detect gross mismatches
    3695              :              such as between T[foo()] and T[bar()].  */
    3696           58 :           if (operand_equal_p (newbnd, curbnd,
    3697              :                                OEP_DECL_NAME | OEP_LEXICOGRAPHIC))
    3698           26 :             continue;
    3699              : 
    3700           32 :           if (warning_at (newloc, OPT_Wvla_parameter,
    3701              :                           "argument %u of type %s "
    3702              :                           "declared with mismatched bound %qs",
    3703              :                           parmpos + 1, newparmstr.c_str (), newbndstr))
    3704           30 :             inform (origloc, "previously declared as %s with bound %qs",
    3705              :                     curparmstr.c_str (), curbndstr);
    3706           32 :           continue;
    3707              :         }
    3708          155 :     }
    3709              : 
    3710         4300 :   if (newa->minsize == cura->minsize
    3711           86 :       || (((newa->minsize == 0 && newa->mode != access_deferred)
    3712           86 :            || (cura->minsize == 0 && cura->mode != access_deferred))
    3713            6 :           && newa != &ptr_spec
    3714            6 :           && cura != &ptr_spec))
    3715              :     return;
    3716              : 
    3717           84 :   if (!newa->static_p && !cura->static_p && warn_array_parameter < 2)
    3718              :     /* Avoid warning about mismatches in ordinary (non-static) arrays
    3719              :        at levels below 2.  */
    3720              :     return;
    3721              : 
    3722           60 :   if (warning_at (newloc, OPT_Warray_parameter_,
    3723              :                   "argument %u of type %s with mismatched bound",
    3724              :                   parmpos + 1, newparmstr.c_str ()))
    3725           60 :     inform (origloc, "previously declared as %s", curparmstr.c_str ());
    3726         4355 : }
    3727              : 
    3728              : /* Detect and diagnose a mismatch between an attribute access specification
    3729              :    on the original declaration of FNDECL and that on the parameters NEWPARMS
    3730              :    from its redeclaration.  ORIGLOC is the location of the first declaration
    3731              :    (FNDECL's is set to the location of the redeclaration).  */
    3732              : 
    3733              : void
    3734     14279803 : warn_parms_array_mismatch (location_t origloc, tree fndecl, tree newparms)
    3735              : {
    3736              :   /* The original parameter list (copied from the original declaration
    3737              :      into the current [re]declaration, FNDECL)).  The two are equal if
    3738              :      and only if FNDECL is the first declaration.  */
    3739     14279803 :   tree curparms = DECL_ARGUMENTS (fndecl);
    3740     14279803 :   if (!curparms || !newparms || curparms == newparms)
    3741     14240960 :     return;
    3742              : 
    3743       648764 :   if (TREE_CODE (curparms) != PARM_DECL
    3744       648764 :       || TREE_CODE (newparms) != PARM_DECL)
    3745              :     return;
    3746              :   /* Extract the (possibly empty) attribute access specification from
    3747              :      the declaration and its type (it doesn't yet reflect those created
    3748              :      in response to NEWPARMS).  */
    3749       648606 :   rdwr_map cur_idx;
    3750       648606 :   tree fntype = TREE_TYPE (fndecl);
    3751       648606 :   init_attr_rdwr_indices (&cur_idx, TYPE_ATTRIBUTES (fntype));
    3752              : 
    3753              :   /* Build a (possibly null) chain of access attributes corresponding
    3754              :      to NEWPARMS.  */
    3755       648606 :   const bool builtin = fndecl_built_in_p (fndecl);
    3756       648606 :   tree newattrs = build_attr_access_from_parms (newparms, builtin);
    3757              : 
    3758              :   /* Extract the (possibly empty) attribute access specification from
    3759              :      NEWATTRS.  */
    3760       648606 :   rdwr_map new_idx;
    3761       648606 :   init_attr_rdwr_indices (&new_idx, newattrs);
    3762              : 
    3763       648606 :   if (cur_idx.is_empty () && new_idx.is_empty ())
    3764              :     {
    3765              :       /* If both specs are empty check pointers to VLAs for mismatches. */
    3766       609761 :       warn_parm_ptrarray_mismatch (origloc, curparms, newparms);
    3767       609761 :       return;
    3768              :     }
    3769              :   /* ...otherwise, if at least one spec isn't empty there may be mismatches,
    3770              :      such as between f(T*) and f(T[1]), where the former mapping would be
    3771              :      empty.  */
    3772              : 
    3773              :   /* Iterate over the two lists of function parameters, comparing their
    3774              :      respective mappings and diagnosing mismatches.  */
    3775              :   unsigned parmpos = 0;
    3776       137955 :   for (tree curp = curparms, newp = newparms; curp;
    3777        99110 :        curp = TREE_CHAIN (curp), newp = TREE_CHAIN (newp), ++parmpos)
    3778              :     {
    3779        99112 :       if (!newp)
    3780              :         /* Bail on invalid redeclarations with fewer arguments.  */
    3781              :         return;
    3782              : 
    3783        99110 :       warn_parm_array_mismatch (origloc, &cur_idx, &new_idx, curp, newp, parmpos,
    3784              :                                 builtin);
    3785              :     }
    3786       648606 : }
    3787              : 
    3788              : /* Warn about divisions of two sizeof operators when the first one is applied
    3789              :    to an array and the divisor does not equal the size of the array element.
    3790              :    For instance:
    3791              : 
    3792              :      sizeof (ARR) / sizeof (OP)
    3793              : 
    3794              :    ARR is the array argument of the first sizeof, ARR_TYPE is its ARRAY_TYPE.
    3795              :    OP1 is the whole second SIZEOF_EXPR, or its argument; TYPE1 is the type
    3796              :    of the second argument.  */
    3797              : 
    3798              : void
    3799        83699 : maybe_warn_sizeof_array_div (location_t loc, tree arr, tree arr_type,
    3800              :                              tree op1, tree type1)
    3801              : {
    3802        83699 :   tree elt_type = TREE_TYPE (arr_type);
    3803              : 
    3804        83699 :   if (!warn_sizeof_array_div
    3805              :       /* Don't warn on multidimensional arrays.  */
    3806         1067 :       || TREE_CODE (elt_type) == ARRAY_TYPE)
    3807              :     return;
    3808              : 
    3809         1043 :   if (!tree_int_cst_equal (TYPE_SIZE (elt_type), TYPE_SIZE (type1)))
    3810              :     {
    3811           40 :       auto_diagnostic_group d;
    3812           40 :       if (warning_at (loc, OPT_Wsizeof_array_div,
    3813              :                       "expression does not compute the number of "
    3814              :                       "elements in this array; element type is "
    3815              :                       "%qT, not %qT", elt_type, type1))
    3816              :         {
    3817           40 :           if (EXPR_HAS_LOCATION (op1))
    3818              :             {
    3819           33 :               location_t op1_loc = EXPR_LOCATION (op1);
    3820           33 :               gcc_rich_location richloc (op1_loc);
    3821           33 :               richloc.add_fixit_insert_before (op1_loc, "(");
    3822           33 :               richloc.add_fixit_insert_after (op1_loc, ")");
    3823           33 :               inform (&richloc, "add parentheses around %qE to "
    3824              :                       "silence this warning", op1);
    3825           33 :             }
    3826              :           else
    3827            7 :             inform (loc, "add parentheses around the second %<sizeof%> "
    3828              :                     "to silence this warning");
    3829           40 :           if (DECL_P (arr))
    3830           34 :             inform (DECL_SOURCE_LOCATION (arr), "array %qD declared here", arr);
    3831              :         }
    3832           40 :     }
    3833              : }
    3834              : 
    3835              : /* Warn about C++20 [depr.array.comp] array comparisons: "Equality
    3836              :    and relational comparisons between two operands of array type are
    3837              :    deprecated."  In C++26 this is a permerror.  We also warn in C and earlier
    3838              :    C++ standards.  CODE is the code for this comparison, OP0 and OP1 are
    3839              :    the operands.  */
    3840              : 
    3841              : void
    3842          111 : do_warn_array_compare (location_t location, tree_code code, tree op0, tree op1)
    3843              : {
    3844          111 :   STRIP_NOPS (op0);
    3845          111 :   STRIP_NOPS (op1);
    3846          111 :   if (TREE_CODE (op0) == ADDR_EXPR)
    3847           14 :     op0 = TREE_OPERAND (op0, 0);
    3848          111 :   if (TREE_CODE (op1) == ADDR_EXPR)
    3849           14 :     op1 = TREE_OPERAND (op1, 0);
    3850              : 
    3851          111 :   auto_diagnostic_group d;
    3852          111 :   enum diagnostics::kind kind = diagnostics::kind::warning;
    3853          111 :   const char *msg;
    3854          111 :   if (c_dialect_cxx () && cxx_dialect >= cxx20)
    3855              :     {
    3856              :       /* P2865R5 made this comparison ill-formed in C++26.  */
    3857           72 :       if (cxx_dialect >= cxx26)
    3858              :         {
    3859              :           msg = G_("comparison between two arrays is not allowed in C++26");
    3860              :           kind = diagnostics::kind::permerror;
    3861              :         }
    3862              :       else
    3863           40 :         msg = G_("comparison between two arrays is deprecated in C++20");
    3864              :     }
    3865              :   else
    3866              :     msg = G_("comparison between two arrays");
    3867          111 :   if (emit_diagnostic (kind, location, OPT_Warray_compare, msg))
    3868              :     {
    3869              :       /* C doesn't allow +arr.  */
    3870           78 :       if (c_dialect_cxx ())
    3871          132 :         inform (location, "use unary %<+%> which decays operands to pointers "
    3872              :                 "or %<&%s%E%s[0] %s &%s%E%s[0]%> to compare the addresses",
    3873           63 :                 DECL_P (op0) ? "" : "(", op0, DECL_P (op0) ? "" : ")",
    3874              :                 op_symbol_code (code),
    3875           63 :                 DECL_P (op1) ? "" : "(", op1, DECL_P (op1) ? "" : ")");
    3876              :       else
    3877           32 :         inform (location,
    3878              :                 "use %<&%s%E%s[0] %s &%s%E%s[0]%> to compare the addresses",
    3879           15 :                 DECL_P (op0) ? "" : "(", op0, DECL_P (op0) ? "" : ")",
    3880              :                 op_symbol_code (code),
    3881           15 :                 DECL_P (op1) ? "" : "(", op1, DECL_P (op1) ? "" : ")");
    3882              :     }
    3883          111 : }
    3884              : 
    3885              : /* Given LHS_VAL ^ RHS_VAL, where LHS_LOC is the location of the LHS,
    3886              :    OPERATOR_LOC is the location of the ^, and RHS_LOC the location of the
    3887              :    RHS, complain with -Wxor-used-as-pow if it looks like the user meant
    3888              :    exponentiation rather than xor.  */
    3889              : 
    3890              : void
    3891          633 : check_for_xor_used_as_pow (location_t lhs_loc, tree lhs_val,
    3892              :                            location_t operator_loc,
    3893              :                            location_t rhs_loc, tree rhs_val)
    3894              : {
    3895              :   /* Only complain if both args are non-negative integer constants that fit
    3896              :      in uhwi.  */
    3897          633 :   if (!tree_fits_uhwi_p (lhs_val) || !tree_fits_uhwi_p (rhs_val))
    3898          555 :     return;
    3899              : 
    3900              :   /* Only complain if the LHS is 2 or 10.  */
    3901          633 :   unsigned HOST_WIDE_INT lhs_uhwi = tree_to_uhwi (lhs_val);
    3902          633 :   if (lhs_uhwi != 2 && lhs_uhwi != 10)
    3903              :     return;
    3904              : 
    3905           94 :   unsigned HOST_WIDE_INT rhs_uhwi = tree_to_uhwi (rhs_val);
    3906           94 :   unsigned HOST_WIDE_INT xor_result = lhs_uhwi ^ rhs_uhwi;
    3907           94 :   binary_op_rich_location loc (operator_loc,
    3908           94 :                                lhs_val, rhs_val, false);
    3909              : 
    3910              :   /* Reject cases where we don't have 3 distinct locations.
    3911              :      This can happen e.g. due to macro expansion with
    3912              :      -ftrack-macro-expansion=0 */
    3913           90 :   if (!(lhs_loc != operator_loc
    3914           94 :         && lhs_loc != rhs_loc
    3915              :         && operator_loc != rhs_loc))
    3916              :     return;
    3917              : 
    3918              :   /* Reject cases in which any of the locations came from a macro.  */
    3919           90 :   if (from_macro_expansion_at (lhs_loc)
    3920           78 :       || from_macro_expansion_at (operator_loc)
    3921          168 :       || from_macro_expansion_at (rhs_loc))
    3922           12 :     return;
    3923              : 
    3924              :   /* If we issue fix-it hints with the warning then we will also issue a
    3925              :      note suggesting how to suppress the warning with a different change.
    3926              :      These proposed changes are incompatible.  */
    3927           78 :   loc.fixits_cannot_be_auto_applied ();
    3928              : 
    3929           78 :   auto_diagnostic_group d;
    3930           78 :   bool warned = false;
    3931           78 :   if (lhs_uhwi == 2)
    3932              :     {
    3933              :       /* Would exponentiation fit in int, in long long, or not at all?  */
    3934           55 :       if (rhs_uhwi < (INT_TYPE_SIZE - 1))
    3935              :         {
    3936           19 :           unsigned HOST_WIDE_INT suggested_result = 1 << rhs_uhwi;
    3937           19 :           loc.add_fixit_replace (lhs_loc, "1");
    3938           19 :           loc.add_fixit_replace (operator_loc, "<<");
    3939           19 :           warned = warning_at (&loc, OPT_Wxor_used_as_pow,
    3940              :                                "result of %<%wu^%wu%> is %wu;"
    3941              :                                " did you mean %<1 << %wu%> (%wu)?",
    3942              :                                lhs_uhwi, rhs_uhwi, xor_result,
    3943              :                                rhs_uhwi, suggested_result);
    3944              :         }
    3945           36 :       else if (rhs_uhwi < (LONG_LONG_TYPE_SIZE - 1))
    3946              :         {
    3947           12 :           loc.add_fixit_replace (lhs_loc, "1LL");
    3948           12 :           loc.add_fixit_replace (operator_loc, "<<");
    3949           12 :           warned = warning_at (&loc, OPT_Wxor_used_as_pow,
    3950              :                                "result of %<%wu^%wu%> is %wu;"
    3951              :                                " did you mean %<1LL << %wu%>?",
    3952              :                                lhs_uhwi, rhs_uhwi, xor_result,
    3953              :                                rhs_uhwi);
    3954              :         }
    3955           24 :       else if (rhs_uhwi <= LONG_LONG_TYPE_SIZE)
    3956            8 :         warned = warning_at (&loc, OPT_Wxor_used_as_pow,
    3957              :                              "result of %<%wu^%wu%> is %wu;"
    3958              :                              " did you mean exponentiation?",
    3959              :                              lhs_uhwi, rhs_uhwi, xor_result);
    3960              :       /* Otherwise assume it's an xor.  */
    3961              :     }
    3962              :   else
    3963              :     {
    3964           23 :       gcc_assert (lhs_uhwi == 10);
    3965           23 :       loc.add_fixit_replace (lhs_loc, "1");
    3966           23 :       loc.add_fixit_replace (operator_loc, "e");
    3967           23 :       warned = warning_at (&loc, OPT_Wxor_used_as_pow,
    3968              :                            "result of %<%wu^%wu%> is %wu;"
    3969              :                            " did you mean %<1e%wu%>?",
    3970              :                            lhs_uhwi, rhs_uhwi, xor_result,
    3971              :                            rhs_uhwi);
    3972              :     }
    3973           62 :   if (warned)
    3974              :     {
    3975           62 :       gcc_rich_location note_loc (lhs_loc);
    3976           62 :       if (lhs_uhwi == 2)
    3977           39 :         note_loc.add_fixit_replace (lhs_loc, "0x2");
    3978              :       else
    3979              :         {
    3980           23 :           gcc_assert (lhs_uhwi == 10);
    3981           23 :           note_loc.add_fixit_replace (lhs_loc, "0xa");
    3982              :         }
    3983           62 :       note_loc.fixits_cannot_be_auto_applied ();
    3984           62 :       inform (&note_loc,
    3985              :               "you can silence this warning by using a hexadecimal constant"
    3986              :               " (%wx rather than %wd)",
    3987              :               lhs_uhwi, lhs_uhwi);
    3988           62 :     }
    3989           94 : }
        

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.