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