LCOV - code coverage report
Current view: top level - gcc/cp - expr.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 99.4 % 175 174
Test Date: 2024-04-20 14:03:02 Functions: 100.0 % 9 9
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Convert language-specific tree expression to rtl instructions,
       2                 :             :    for GNU compiler.
       3                 :             :    Copyright (C) 1988-2024 Free Software Foundation, Inc.
       4                 :             : 
       5                 :             : This file is part of GCC.
       6                 :             : 
       7                 :             : GCC is free software; you can redistribute it and/or modify
       8                 :             : it under the terms of the GNU General Public License as published by
       9                 :             : the Free Software Foundation; either version 3, or (at your option)
      10                 :             : any later version.
      11                 :             : 
      12                 :             : GCC is distributed in the hope that it will be useful,
      13                 :             : but WITHOUT ANY WARRANTY; without even the implied warranty of
      14                 :             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15                 :             : GNU General Public License for more details.
      16                 :             : 
      17                 :             : You should have received a copy of the GNU General Public License
      18                 :             : along with GCC; see the file COPYING3.  If not see
      19                 :             : <http://www.gnu.org/licenses/>.  */
      20                 :             : 
      21                 :             : 
      22                 :             : #include "config.h"
      23                 :             : #include "system.h"
      24                 :             : #include "coretypes.h"
      25                 :             : #include "cp-tree.h"
      26                 :             : 
      27                 :             : /* Expand C++-specific constants.  Currently, this means PTRMEM_CST.  */
      28                 :             : 
      29                 :             : tree
      30                 :    38245068 : cplus_expand_constant (tree cst)
      31                 :             : {
      32                 :    38245068 :   switch (TREE_CODE (cst))
      33                 :             :     {
      34                 :       35743 :     case PTRMEM_CST:
      35                 :       35743 :       {
      36                 :       35743 :         tree type = TREE_TYPE (cst);
      37                 :       35743 :         tree member;
      38                 :             : 
      39                 :             :         /* Find the member.  */
      40                 :       35743 :         member = PTRMEM_CST_MEMBER (cst);
      41                 :             : 
      42                 :             :         /* We can't lower this until the class is complete.  */
      43                 :       35743 :         if (!COMPLETE_TYPE_P (DECL_CONTEXT (member)))
      44                 :             :           return cst;
      45                 :             : 
      46                 :       35711 :         if (TREE_CODE (member) == FIELD_DECL)
      47                 :             :           {
      48                 :             :             /* Find the offset for the field.  */
      49                 :        3311 :             cst = byte_position (member);
      50                 :        6677 :             while (!same_type_p (DECL_CONTEXT (member),
      51                 :             :                                  TYPE_PTRMEM_CLASS_TYPE (type)))
      52                 :             :               {
      53                 :             :                 /* The MEMBER must have been nestled within an
      54                 :             :                    anonymous aggregate contained in TYPE.  Find the
      55                 :             :                    anonymous aggregate.  */
      56                 :          55 :                 member = lookup_anon_field (TYPE_PTRMEM_CLASS_TYPE (type),
      57                 :          55 :                                             DECL_CONTEXT (member));
      58                 :          55 :                 cst = size_binop (PLUS_EXPR, cst, byte_position (member));
      59                 :             :               }
      60                 :        3311 :             cst = fold (build_nop (type, cst));
      61                 :             :           }
      62                 :             :         else
      63                 :             :           {
      64                 :       32400 :             tree delta;
      65                 :       32400 :             tree pfn;
      66                 :             : 
      67                 :       32400 :             expand_ptrmemfunc_cst (cst, &delta, &pfn);
      68                 :       32400 :             cst = build_ptrmemfunc1 (type, delta, pfn);
      69                 :             :           }
      70                 :             :       }
      71                 :             :       break;
      72                 :             : 
      73                 :             :     case CONSTRUCTOR:
      74                 :             :       {
      75                 :             :         constructor_elt *elt;
      76                 :             :         unsigned HOST_WIDE_INT idx;
      77                 :    27407577 :         FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (cst), idx, elt)
      78                 :    23788043 :           elt->value = cplus_expand_constant (elt->value);
      79                 :             :       }
      80                 :             : 
      81                 :             :     default:
      82                 :             :       /* There's nothing to do.  */
      83                 :             :       break;
      84                 :             :     }
      85                 :             : 
      86                 :             :   return cst;
      87                 :             : }
      88                 :             : 
      89                 :             : /* We've seen an actual use of EXPR.  Possibly replace an outer variable
      90                 :             :    reference inside with its constant value or a lambda capture.  */
      91                 :             : 
      92                 :             : tree
      93                 :  4702440287 : mark_use (tree expr, bool rvalue_p, bool read_p,
      94                 :             :           location_t loc /* = UNKNOWN_LOCATION */,
      95                 :             :           bool reject_builtin /* = true */)
      96                 :             : {
      97                 :             : #define RECUR(t) mark_use ((t), rvalue_p, read_p, loc, reject_builtin)
      98                 :             : 
      99                 :  4702440287 :   if (expr == NULL_TREE || error_operand_p (expr))
     100                 :             :     return expr;
     101                 :             : 
     102                 :  4702435641 :   if (reject_builtin && reject_gcc_builtin (expr, loc))
     103                 :          85 :     return error_mark_node;
     104                 :             : 
     105                 :  4702435556 :   if (read_p)
     106                 :  4644739598 :     mark_exp_read (expr);
     107                 :             : 
     108                 :  4702435556 :   tree oexpr = expr;
     109                 :  4702435556 :   bool recurse_op[3] = { false, false, false };
     110                 :  4702435556 :   switch (TREE_CODE (expr))
     111                 :             :     {
     112                 :  1164482198 :     case VAR_DECL:
     113                 :  1164482198 :     case PARM_DECL:
     114                 :  1164482198 :       if (rvalue_p && is_normal_capture_proxy (expr))
     115                 :             :         {
     116                 :             :           /* Look through capture by copy.  */
     117                 :     5189381 :           tree cap = DECL_CAPTURED_VARIABLE (expr);
     118                 :     5189381 :           if (TREE_CODE (TREE_TYPE (cap)) == TREE_CODE (TREE_TYPE (expr))
     119                 :     5189381 :               && decl_constant_var_p (cap))
     120                 :             :             {
     121                 :         106 :               tree val = RECUR (cap);
     122                 :         106 :               if (!is_capture_proxy (val))
     123                 :             :                 {
     124                 :          67 :                   tree l = current_lambda_expr ();
     125                 :          67 :                   LAMBDA_EXPR_CAPTURE_OPTIMIZED (l) = true;
     126                 :             :                 }
     127                 :         106 :               return val;
     128                 :             :             }
     129                 :             :         }
     130                 :  1164482092 :       if (outer_automatic_var_p (expr)
     131                 :  1164482092 :           && decl_constant_var_p (expr))
     132                 :             :         {
     133                 :      120602 :           if (rvalue_p)
     134                 :             :             {
     135                 :      120593 :               tree t = maybe_constant_value (expr);
     136                 :      120593 :               if (TREE_CONSTANT (t))
     137                 :             :                 {
     138                 :             :                   expr = t;
     139                 :  4308211631 :                   break;
     140                 :             :                 }
     141                 :             :             }
     142                 :          54 :           iloc_sentinel l (loc);
     143                 :          54 :           expr = process_outer_var_ref (expr, tf_warning_or_error, true);
     144                 :          54 :           if (!(TREE_TYPE (oexpr)
     145                 :          54 :                 && TYPE_REF_P (TREE_TYPE (oexpr))))
     146                 :          42 :             expr = convert_from_reference (expr);
     147                 :          54 :         }
     148                 :             :       break;
     149                 :   107420409 :     case COMPONENT_REF:
     150                 :   107420409 :       recurse_op[0] = true;
     151                 :   107420409 :       break;
     152                 :     6266103 :     case COMPOUND_EXPR:
     153                 :     6266103 :       recurse_op[1] = true;
     154                 :     6266103 :       break;
     155                 :    13900406 :     case COND_EXPR:
     156                 :    13900406 :       recurse_op[2] = true;
     157                 :    13900406 :       if (TREE_OPERAND (expr, 1))
     158                 :    13900352 :         recurse_op[1] = true;
     159                 :             :       break;
     160                 :   220555087 :     case INDIRECT_REF:
     161                 :   220555087 :       if (REFERENCE_REF_P (expr))
     162                 :             :         {
     163                 :             :           /* Try to look through the reference.  */
     164                 :   108869639 :           tree ref = TREE_OPERAND (expr, 0);
     165                 :   108869639 :           if (rvalue_p && is_normal_capture_proxy (ref))
     166                 :             :             {
     167                 :             :               /* Look through capture by reference.  */
     168                 :      924763 :               tree cap = DECL_CAPTURED_VARIABLE (ref);
     169                 :      924763 :               if (!TYPE_REF_P (TREE_TYPE (cap))
     170                 :      924763 :                   && decl_constant_var_p (cap))
     171                 :             :                 {
     172                 :         838 :                   tree val = RECUR (cap);
     173                 :         838 :                   if (!is_capture_proxy (val))
     174                 :             :                     {
     175                 :         838 :                       tree l = current_lambda_expr ();
     176                 :         838 :                       LAMBDA_EXPR_CAPTURE_OPTIMIZED (l) = true;
     177                 :             :                     }
     178                 :         838 :                   return val;
     179                 :             :                 }
     180                 :             :             }
     181                 :   108868801 :           tree r = mark_rvalue_use (ref, loc, reject_builtin);
     182                 :   108868801 :           if (r != ref)
     183                 :          15 :             expr = convert_from_reference (r);
     184                 :             :         }
     185                 :             :       break;
     186                 :             : 
     187                 :   401863916 :     case VIEW_CONVERT_EXPR:
     188                 :   401863916 :       if (location_wrapper_p (expr))
     189                 :             :         {
     190                 :   394222981 :           loc = EXPR_LOCATION (expr);
     191                 :   394222981 :           tree op = TREE_OPERAND (expr, 0);
     192                 :   394222981 :           tree nop = RECUR (op);
     193                 :   394222981 :           if (nop == error_mark_node)
     194                 :             :             return error_mark_node;
     195                 :   394222972 :           else if (op == nop)
     196                 :             :             /* No change.  */;
     197                 :         236 :           else if (DECL_P (nop) || CONSTANT_CLASS_P (nop))
     198                 :             :             {
     199                 :             :               /* Reuse the location wrapper.  */
     200                 :         225 :               TREE_OPERAND (expr, 0) = nop;
     201                 :             :               /* If we're replacing a DECL with a constant, we also need to
     202                 :             :                  change the TREE_CODE of the location wrapper.  */
     203                 :         225 :               if (rvalue_p)
     204                 :         225 :                 TREE_SET_CODE (expr, NON_LVALUE_EXPR);
     205                 :             :             }
     206                 :             :           else
     207                 :             :             {
     208                 :             :               /* Drop the location wrapper.  */
     209                 :          11 :               expr = nop;
     210                 :          11 :               protected_set_expr_location (expr, loc);
     211                 :             :             }
     212                 :   394222972 :           return expr;
     213                 :             :         }
     214                 :   477986588 :       gcc_fallthrough();
     215                 :   477986588 :     CASE_CONVERT:
     216                 :   477986588 :       recurse_op[0] = true;
     217                 :   477986588 :       break;
     218                 :             : 
     219                 :     3429578 :     case MODIFY_EXPR:
     220                 :     3429578 :         {
     221                 :     3429578 :           tree lhs = TREE_OPERAND (expr, 0);
     222                 :             :           /* [expr.ass] "An assignment whose left operand is of
     223                 :             :              a volatile-qualified type is deprecated unless the assignment
     224                 :             :              is either a discarded-value expression or appears in an
     225                 :             :              unevaluated context."  */
     226                 :     3429578 :           if (!cp_unevaluated_operand
     227                 :     3429554 :               && (TREE_THIS_VOLATILE (lhs)
     228                 :     3429020 :                   || CP_TYPE_VOLATILE_P (TREE_TYPE (lhs)))
     229                 :     3430112 :               && !TREE_THIS_VOLATILE (expr))
     230                 :             :             {
     231                 :         362 :               if (warning_at (location_of (expr), OPT_Wvolatile,
     232                 :             :                               "using value of assignment with "
     233                 :             :                               "%<volatile%>-qualified left operand is "
     234                 :             :                               "deprecated"))
     235                 :             :                 /* Make sure not to warn about this assignment again.  */
     236                 :          52 :                 TREE_THIS_VOLATILE (expr) = true;
     237                 :             :             }
     238                 :             :           break;
     239                 :             :         }
     240                 :             : 
     241                 :             :     default:
     242                 :             :       break;
     243                 :             :     }
     244                 :             : 
     245                 : 17232846524 :   for (int i = 0; i < 3; ++i)
     246                 : 12924634893 :     if (recurse_op[i])
     247                 :             :       {
     248                 :   619473858 :         tree op = TREE_OPERAND (expr, i);
     249                 :   619473858 :         op = RECUR (op);
     250                 :   619473858 :         if (op == error_mark_node)
     251                 :           0 :           return error_mark_node;
     252                 :   619473858 :         TREE_OPERAND (expr, i) = op;
     253                 :             :       }
     254                 :             : 
     255                 :             :   return expr;
     256                 :             : #undef RECUR
     257                 :             : }
     258                 :             : 
     259                 :             : /* Called whenever the expression EXPR is used in an rvalue context.
     260                 :             :    When REJECT_BUILTIN is true the expression is checked to make sure
     261                 :             :    it doesn't make it possible to obtain the address of a GCC built-in
     262                 :             :    function with no library fallback (or any of its bits, such as in
     263                 :             :    a conversion to bool).  */
     264                 :             : 
     265                 :             : tree
     266                 :  2853866123 : mark_rvalue_use (tree e,
     267                 :             :                  location_t loc /* = UNKNOWN_LOCATION */,
     268                 :             :                  bool reject_builtin /* = true */)
     269                 :             : {
     270                 :  2853866123 :   return mark_use (e, true, true, loc, reject_builtin);
     271                 :             : }
     272                 :             : 
     273                 :             : /* Called whenever an expression is used in an lvalue context.  */
     274                 :             : 
     275                 :             : tree
     276                 :   275333141 : mark_lvalue_use (tree expr)
     277                 :             : {
     278                 :   275333141 :   return mark_use (expr, false, true, input_location, false);
     279                 :             : }
     280                 :             : 
     281                 :             : /* As above, but don't consider this use a read.  */
     282                 :             : 
     283                 :             : tree
     284                 :    30531607 : mark_lvalue_use_nonread (tree expr)
     285                 :             : {
     286                 :    30531607 :   return mark_use (expr, false, false, input_location, false);
     287                 :             : }
     288                 :             : 
     289                 :             : /* Called when expr appears as a discarded-value expression.  */
     290                 :             : 
     291                 :             : tree
     292                 :    75532071 : mark_discarded_use (tree expr)
     293                 :             : {
     294                 :             :   /* The lvalue-to-rvalue conversion (7.1) is applied if and only if the
     295                 :             :      expression is a glvalue of volatile-qualified type and it is one of the
     296                 :             :      following:
     297                 :             :      * ( expression ), where expression is one of these expressions,
     298                 :             :      * id-expression (8.1.4),
     299                 :             :      * subscripting (8.2.1),
     300                 :             :      * class member access (8.2.5),
     301                 :             :      * indirection (8.3.1),
     302                 :             :      * pointer-to-member operation (8.5),
     303                 :             :      * conditional expression (8.16) where both the second and the third
     304                 :             :        operands are one of these expressions, or
     305                 :             :      * comma expression (8.19) where the right operand is one of these
     306                 :             :        expressions.  */
     307                 :    75532071 :   if (expr == NULL_TREE)
     308                 :             :     return expr;
     309                 :             : 
     310                 :    75532067 :   STRIP_ANY_LOCATION_WRAPPER (expr);
     311                 :             : 
     312                 :    75532067 :   switch (TREE_CODE (expr))
     313                 :             :     {
     314                 :      115449 :     case COND_EXPR:
     315                 :      115449 :       TREE_OPERAND (expr, 2) = mark_discarded_use (TREE_OPERAND (expr, 2));
     316                 :      466642 :       gcc_fallthrough ();
     317                 :      466642 :     case COMPOUND_EXPR:
     318                 :      466642 :       TREE_OPERAND (expr, 1) = mark_discarded_use (TREE_OPERAND (expr, 1));
     319                 :      466642 :       return expr;
     320                 :             : 
     321                 :             :     case COMPONENT_REF:
     322                 :             :     case ARRAY_REF:
     323                 :             :     case INDIRECT_REF:
     324                 :             :     case MEMBER_REF:
     325                 :             :       break;
     326                 :    71715653 :     default:
     327                 :    71715653 :       if (DECL_P (expr))
     328                 :             :         break;
     329                 :             :       else
     330                 :             :         return expr;
     331                 :             :     }
     332                 :             : 
     333                 :             :   /* Like mark_rvalue_use, but don't reject built-ins.  */
     334                 :     3381094 :   return mark_use (expr, true, true, input_location, false);
     335                 :             : }
     336                 :             : 
     337                 :             : /* Called whenever an expression is used in a type use context.  */
     338                 :             : 
     339                 :             : tree
     340                 :    84846391 : mark_type_use (tree expr)
     341                 :             : {
     342                 :    84846391 :   mark_exp_read (expr);
     343                 :    84846391 :   return expr;
     344                 :             : }
     345                 :             : 
     346                 :             : /* Mark EXP as read, not just set, for set but not used -Wunused
     347                 :             :    warning purposes.  */
     348                 :             : 
     349                 :             : void
     350                 :  5014704376 : mark_exp_read (tree exp)
     351                 :             : {
     352                 :  7296516835 :   if (exp == NULL)
     353                 :             :     return;
     354                 :             : 
     355                 :  7294744987 :   switch (TREE_CODE (exp))
     356                 :             :     {
     357                 :   861194354 :     case VAR_DECL:
     358                 :   861194354 :       if (DECL_DECOMPOSITION_P (exp))
     359                 :     3142234 :         mark_exp_read (DECL_DECOMP_BASE (exp));
     360                 :  2330485099 :       gcc_fallthrough ();
     361                 :  2330485099 :     case PARM_DECL:
     362                 :  2330485099 :       DECL_READ_P (exp) = 1;
     363                 :  2330485099 :       break;
     364                 :  2254793753 :     case ARRAY_REF:
     365                 :  2254793753 :     case COMPONENT_REF:
     366                 :  2254793753 :     case MODIFY_EXPR:
     367                 :  2254793753 :     case REALPART_EXPR:
     368                 :  2254793753 :     case IMAGPART_EXPR:
     369                 :  2254793753 :     CASE_CONVERT:
     370                 :  2254793753 :     case ADDR_EXPR:
     371                 :  2254793753 :     case INDIRECT_REF:
     372                 :  2254793753 :     case FLOAT_EXPR:
     373                 :  2254793753 :     case VIEW_CONVERT_EXPR:
     374                 :  2254793753 :       mark_exp_read (TREE_OPERAND (exp, 0));
     375                 :  2254793753 :       break;
     376                 :     7530618 :     case COMPOUND_EXPR:
     377                 :     7530618 :       mark_exp_read (TREE_OPERAND (exp, 1));
     378                 :     7530618 :       break;
     379                 :    19488088 :     case COND_EXPR:
     380                 :    19488088 :       if (TREE_OPERAND (exp, 1))
     381                 :    19488020 :         mark_exp_read (TREE_OPERAND (exp, 1));
     382                 :    19488088 :       if (TREE_OPERAND (exp, 2))
     383                 :    19488088 :         mark_exp_read (TREE_OPERAND (exp, 2));
     384                 :             :       break;
     385                 :             :     default:
     386                 :             :       break;
     387                 :             :     }
     388                 :             : }
     389                 :             : 
     390                 :             : /* Fold X for consideration by one of the warning functions when checking
     391                 :             :    whether an expression has a constant value.  */
     392                 :             : 
     393                 :             : tree
     394                 :    60604211 : fold_for_warn (tree x)
     395                 :             : {
     396                 :             :   /* C++ implementation.  */
     397                 :             : 
     398                 :    60604211 :   if (cp_unevaluated_operand)
     399                 :             :     /* In an unevaluated context we don't care about the reduced value
     400                 :             :        of an expression, so neither should any warnings.  */
     401                 :             :     return x;
     402                 :             : 
     403                 :             :   /* Prevent warning-dependent constexpr evaluation from changing
     404                 :             :      DECL_UID (which breaks -fcompare-debug) and from instantiating
     405                 :             :      templates.  */
     406                 :    60427338 :   uid_sensitive_constexpr_evaluation_sentinel s;
     407                 :             : 
     408                 :             :   /* It's not generally safe to fully fold inside of a template, so
     409                 :             :      call fold_non_dependent_expr instead.  */
     410                 :    60427338 :   if (processing_template_decl)
     411                 :             :     {
     412                 :     2909660 :       tree f = fold_non_dependent_expr (x, tf_none);
     413                 :     2909660 :       if (f == error_mark_node)
     414                 :             :         return x;
     415                 :             :       else
     416                 :     2909657 :         return f;
     417                 :             :     }
     418                 :    57517678 :   else if (cxx_dialect >= cxx11)
     419                 :    57089054 :     x = maybe_constant_value (x);
     420                 :             : 
     421                 :    57517678 :   return c_fully_fold (x, /*for_init*/false, /*maybe_constp*/NULL);
     422                 :    60427338 : }
        

Generated by: LCOV version 2.1-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.