LCOV - code coverage report
Current view: top level - gcc/c-family - c-warn.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 95.4 % 1734 1655
Test Date: 2026-05-30 15:37:04 Functions: 98.3 % 60 59
Legend: Lines:     hit not hit

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