LCOV - code coverage report
Current view: top level - gcc/cp - expr.c (source / functions) Hit Total Coverage
Test: gcc.info Lines: 171 172 99.4 %
Date: 2020-03-28 11:57:23 Functions: 9 9 100.0 %
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-2020 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                 :   15813300 : cplus_expand_constant (tree cst)
      31                 :            : {
      32                 :   15813300 :   switch (TREE_CODE (cst))
      33                 :            :     {
      34                 :       5923 :     case PTRMEM_CST:
      35                 :       5923 :       {
      36                 :       5923 :         tree type = TREE_TYPE (cst);
      37                 :       5923 :         tree member;
      38                 :            : 
      39                 :            :         /* Find the member.  */
      40                 :       5923 :         member = PTRMEM_CST_MEMBER (cst);
      41                 :            : 
      42                 :            :         /* We can't lower this until the class is complete.  */
      43                 :       5923 :         if (!COMPLETE_TYPE_P (DECL_CONTEXT (member)))
      44                 :            :           return cst;
      45                 :            : 
      46                 :       5923 :         if (TREE_CODE (member) == FIELD_DECL)
      47                 :            :           {
      48                 :            :             /* Find the offset for the field.  */
      49                 :       1561 :             cst = byte_position (member);
      50                 :       3130 :             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                 :          8 :                 member = lookup_anon_field (TYPE_PTRMEM_CLASS_TYPE (type),
      57                 :          4 :                                             DECL_CONTEXT (member));
      58                 :          4 :                 cst = size_binop (PLUS_EXPR, cst, byte_position (member));
      59                 :            :               }
      60                 :       1561 :             cst = fold (build_nop (type, cst));
      61                 :            :           }
      62                 :            :         else
      63                 :            :           {
      64                 :       4362 :             tree delta;
      65                 :       4362 :             tree pfn;
      66                 :            : 
      67                 :       4362 :             expand_ptrmemfunc_cst (cst, &delta, &pfn);
      68                 :       4362 :             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                 :   10453300 :         FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (cst), idx, elt)
      78                 :    9240640 :           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                 :  828921000 : 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                 : 1657840000 :   if (expr == NULL_TREE || error_operand_p (expr))
     100                 :            :     return expr;
     101                 :            : 
     102                 :  828915000 :   if (reject_builtin && reject_gcc_builtin (expr, loc))
     103                 :         85 :     return error_mark_node;
     104                 :            : 
     105                 :  828915000 :   if (read_p)
     106                 :  821478000 :     mark_exp_read (expr);
     107                 :            : 
     108                 :  828915000 :   tree oexpr = expr;
     109                 :  828915000 :   bool recurse_op[3] = { false, false, false };
     110                 :  828915000 :   switch (TREE_CODE (expr))
     111                 :            :     {
     112                 :  172093000 :     case VAR_DECL:
     113                 :  172093000 :     case PARM_DECL:
     114                 :  172093000 :       if (rvalue_p && is_normal_capture_proxy (expr))
     115                 :            :         {
     116                 :            :           /* Look through capture by copy.  */
     117                 :     248328 :           tree cap = DECL_CAPTURED_VARIABLE (expr);
     118                 :     248328 :           if (TREE_CODE (TREE_TYPE (cap)) == TREE_CODE (TREE_TYPE (expr))
     119                 :     248328 :               && decl_constant_var_p (cap))
     120                 :            :             {
     121                 :         67 :               tree val = RECUR (cap);
     122                 :         67 :               if (!is_capture_proxy (val))
     123                 :            :                 {
     124                 :         46 :                   tree l = current_lambda_expr ();
     125                 :         46 :                   LAMBDA_EXPR_CAPTURE_OPTIMIZED (l) = true;
     126                 :            :                 }
     127                 :         67 :               return val;
     128                 :            :             }
     129                 :            :         }
     130                 :  172093000 :       if (outer_automatic_var_p (expr)
     131                 :  172093000 :           && decl_constant_var_p (expr))
     132                 :            :         {
     133                 :       7465 :           if (rvalue_p)
     134                 :            :             {
     135                 :       7456 :               tree t = maybe_constant_value (expr);
     136                 :       7456 :               if (TREE_CONSTANT (t))
     137                 :            :                 {
     138                 :  779526000 :                   expr = t;
     139                 :            :                   break;
     140                 :            :                 }
     141                 :            :             }
     142                 :         72 :           temp_override<location_t> l (input_location);
     143                 :         36 :           if (loc != UNKNOWN_LOCATION)
     144                 :         12 :             input_location = loc;
     145                 :         36 :           expr = process_outer_var_ref (expr, tf_warning_or_error, true);
     146                 :         36 :           if (!(TREE_TYPE (oexpr)
     147                 :         36 :                 && TYPE_REF_P (TREE_TYPE (oexpr))))
     148                 :         30 :             expr = convert_from_reference (expr);
     149                 :            :         }
     150                 :            :       break;
     151                 :   25041800 :     case COMPONENT_REF:
     152                 :   25041800 :     case NON_DEPENDENT_EXPR:
     153                 :   25041800 :       recurse_op[0] = true;
     154                 :   25041800 :       break;
     155                 :    1204600 :     case COMPOUND_EXPR:
     156                 :    1204600 :       recurse_op[1] = true;
     157                 :    1204600 :       break;
     158                 :    1785320 :     case COND_EXPR:
     159                 :    1785320 :       recurse_op[2] = true;
     160                 :    1785320 :       if (TREE_OPERAND (expr, 1))
     161                 :    1785320 :         recurse_op[1] = true;
     162                 :            :       break;
     163                 :   52620400 :     case INDIRECT_REF:
     164                 :   52620400 :       if (REFERENCE_REF_P (expr))
     165                 :            :         {
     166                 :            :           /* Try to look through the reference.  */
     167                 :   28942400 :           tree ref = TREE_OPERAND (expr, 0);
     168                 :   28942400 :           if (rvalue_p && is_normal_capture_proxy (ref))
     169                 :            :             {
     170                 :            :               /* Look through capture by reference.  */
     171                 :       8950 :               tree cap = DECL_CAPTURED_VARIABLE (ref);
     172                 :       8950 :               if (!TYPE_REF_P (TREE_TYPE (cap))
     173                 :       8950 :                   && decl_constant_var_p (cap))
     174                 :            :                 {
     175                 :         39 :                   tree val = RECUR (cap);
     176                 :         39 :                   if (!is_capture_proxy (val))
     177                 :            :                     {
     178                 :         39 :                       tree l = current_lambda_expr ();
     179                 :         39 :                       LAMBDA_EXPR_CAPTURE_OPTIMIZED (l) = true;
     180                 :            :                     }
     181                 :         39 :                   return val;
     182                 :            :                 }
     183                 :            :             }
     184                 :   28942400 :           tree r = mark_rvalue_use (ref, loc, reject_builtin);
     185                 :   28942400 :           if (r != ref)
     186                 :         15 :             expr = convert_from_reference (r);
     187                 :            :         }
     188                 :            :       break;
     189                 :            : 
     190                 :   52402800 :     case VIEW_CONVERT_EXPR:
     191                 :   52402800 :       if (location_wrapper_p (expr))
     192                 :            :         {
     193                 :   49389300 :           loc = EXPR_LOCATION (expr);
     194                 :   49389300 :           tree op = TREE_OPERAND (expr, 0);
     195                 :   49389300 :           tree nop = RECUR (op);
     196                 :   49389300 :           if (nop == error_mark_node)
     197                 :            :             return error_mark_node;
     198                 :   49389300 :           TREE_OPERAND (expr, 0) = nop;
     199                 :            :           /* If we're replacing a DECL with a constant, we also need to change
     200                 :            :              the TREE_CODE of the location wrapper.  */
     201                 :   49389300 :           if (op != nop && rvalue_p)
     202                 :         49 :             TREE_SET_CODE (expr, NON_LVALUE_EXPR);
     203                 :   49389300 :           return expr;
     204                 :            :         }
     205                 :   90468500 :       gcc_fallthrough();
     206                 :   90468500 :     CASE_CONVERT:
     207                 :   90468500 :       recurse_op[0] = true;
     208                 :   90468500 :       break;
     209                 :            : 
     210                 :     265130 :     case MODIFY_EXPR:
     211                 :     265130 :         {
     212                 :     265130 :           tree lhs = TREE_OPERAND (expr, 0);
     213                 :            :           /* [expr.ass] "A simple assignment whose left operand is of
     214                 :            :              a volatile-qualified type is deprecated unless the assignment
     215                 :            :              is either a discarded-value expression or appears in an
     216                 :            :              unevaluated context."  */
     217                 :     265130 :           if (read_p
     218                 :     265026 :               && !cp_unevaluated_operand
     219                 :     265005 :               && (TREE_THIS_VOLATILE (lhs)
     220                 :     529632 :                   || CP_TYPE_VOLATILE_P (TREE_TYPE (lhs)))
     221                 :     265508 :               && !TREE_THIS_VOLATILE (expr))
     222                 :            :             {
     223                 :        116 :               warning_at (location_of (expr), OPT_Wvolatile,
     224                 :            :                           "using value of simple assignment with %<volatile%>-"
     225                 :            :                           "qualified left operand is deprecated");
     226                 :            :               /* Make sure not to warn about this assignment again.  */
     227                 :        116 :               TREE_THIS_VOLATILE (expr) = true;
     228                 :            :             }
     229                 :            :           break;
     230                 :            :         }
     231                 :            : 
     232                 :            :     default:
     233                 :            :       break;
     234                 :            :     }
     235                 :            : 
     236                 : 3118100000 :   for (int i = 0; i < 3; ++i)
     237                 : 2338580000 :     if (recurse_op[i])
     238                 :            :       {
     239                 :  120286000 :         tree op = TREE_OPERAND (expr, i);
     240                 :  120286000 :         op = RECUR (op);
     241                 :  120286000 :         if (op == error_mark_node)
     242                 :          0 :           return error_mark_node;
     243                 :  120286000 :         TREE_OPERAND (expr, i) = op;
     244                 :            :       }
     245                 :            : 
     246                 :            :   return expr;
     247                 :            : #undef RECUR
     248                 :            : }
     249                 :            : 
     250                 :            : /* Called whenever the expression EXPR is used in an rvalue context.
     251                 :            :    When REJECT_BUILTIN is true the expression is checked to make sure
     252                 :            :    it doesn't make it possible to obtain the address of a GCC built-in
     253                 :            :    function with no library fallback (or any of its bits, such as in
     254                 :            :    a conversion to bool).  */
     255                 :            : 
     256                 :            : tree
     257                 :  494404000 : mark_rvalue_use (tree e,
     258                 :            :                  location_t loc /* = UNKNOWN_LOCATION */,
     259                 :            :                  bool reject_builtin /* = true */)
     260                 :            : {
     261                 :  494404000 :   return mark_use (e, true, true, loc, reject_builtin);
     262                 :            : }
     263                 :            : 
     264                 :            : /* Called whenever an expression is used in an lvalue context.  */
     265                 :            : 
     266                 :            : tree
     267                 :   61780600 : mark_lvalue_use (tree expr)
     268                 :            : {
     269                 :   61780600 :   return mark_use (expr, false, true, input_location, false);
     270                 :            : }
     271                 :            : 
     272                 :            : /* As above, but don't consider this use a read.  */
     273                 :            : 
     274                 :            : tree
     275                 :    4162900 : mark_lvalue_use_nonread (tree expr)
     276                 :            : {
     277                 :    4162900 :   return mark_use (expr, false, false, input_location, false);
     278                 :            : }
     279                 :            : 
     280                 :            : /* Called when expr appears as a discarded-value expression.  */
     281                 :            : 
     282                 :            : tree
     283                 :   12327200 : mark_discarded_use (tree expr)
     284                 :            : {
     285                 :            :   /* The lvalue-to-rvalue conversion (7.1) is applied if and only if the
     286                 :            :      expression is a glvalue of volatile-qualified type and it is one of the
     287                 :            :      following:
     288                 :            :      * ( expression ), where expression is one of these expressions,
     289                 :            :      * id-expression (8.1.4),
     290                 :            :      * subscripting (8.2.1),
     291                 :            :      * class member access (8.2.5),
     292                 :            :      * indirection (8.3.1),
     293                 :            :      * pointer-to-member operation (8.5),
     294                 :            :      * conditional expression (8.16) where both the second and the third
     295                 :            :        operands are one of these expressions, or
     296                 :            :      * comma expression (8.19) where the right operand is one of these
     297                 :            :        expressions.  */
     298                 :   12327200 :   if (expr == NULL_TREE)
     299                 :            :     return expr;
     300                 :            : 
     301                 :   12327200 :   STRIP_ANY_LOCATION_WRAPPER (expr);
     302                 :            : 
     303                 :   12327200 :   switch (TREE_CODE (expr))
     304                 :            :     {
     305                 :      37212 :     case COND_EXPR:
     306                 :      37212 :       TREE_OPERAND (expr, 2) = mark_discarded_use (TREE_OPERAND (expr, 2));
     307                 :      80944 :       gcc_fallthrough ();
     308                 :      80944 :     case COMPOUND_EXPR:
     309                 :      80944 :       TREE_OPERAND (expr, 1) = mark_discarded_use (TREE_OPERAND (expr, 1));
     310                 :      80944 :       return expr;
     311                 :            : 
     312                 :            :     case COMPONENT_REF:
     313                 :            :     case ARRAY_REF:
     314                 :            :     case INDIRECT_REF:
     315                 :            :     case MEMBER_REF:
     316                 :            :       break;
     317                 :   12082100 :     default:
     318                 :   12082100 :       if (DECL_P (expr))
     319                 :            :         break;
     320                 :            :       else
     321                 :            :         return expr;
     322                 :            :     }
     323                 :            : 
     324                 :            :   /* Like mark_rvalue_use, but don't reject built-ins.  */
     325                 :     190576 :   return mark_use (expr, true, true, input_location, false);
     326                 :            : }
     327                 :            : 
     328                 :            : /* Called whenever an expression is used in a type use context.  */
     329                 :            : 
     330                 :            : tree
     331                 :   18402800 : mark_type_use (tree expr)
     332                 :            : {
     333                 :   18402800 :   mark_exp_read (expr);
     334                 :   18402800 :   return expr;
     335                 :            : }
     336                 :            : 
     337                 :            : /* Mark EXP as read, not just set, for set but not used -Wunused
     338                 :            :    warning purposes.  */
     339                 :            : 
     340                 :            : void
     341                 :  869767000 : mark_exp_read (tree exp)
     342                 :            : {
     343                 : 1296710000 :   if (exp == NULL)
     344                 :            :     return;
     345                 :            : 
     346                 : 1296680000 :   switch (TREE_CODE (exp))
     347                 :            :     {
     348                 :   96311300 :     case VAR_DECL:
     349                 :  192623000 :       if (DECL_DECOMPOSITION_P (exp))
     350                 :      57870 :         mark_exp_read (DECL_DECOMP_BASE (exp));
     351                 :  358104000 :       gcc_fallthrough ();
     352                 :  358104000 :     case PARM_DECL:
     353                 :  358104000 :       DECL_READ_P (exp) = 1;
     354                 :  358104000 :       break;
     355                 :  422705000 :     case ARRAY_REF:
     356                 :  422705000 :     case COMPONENT_REF:
     357                 :  422705000 :     case MODIFY_EXPR:
     358                 :  422705000 :     case REALPART_EXPR:
     359                 :  422705000 :     case IMAGPART_EXPR:
     360                 :  422705000 :     CASE_CONVERT:
     361                 :  422705000 :     case ADDR_EXPR:
     362                 :  422705000 :     case INDIRECT_REF:
     363                 :  422705000 :     case FLOAT_EXPR:
     364                 :  422705000 :     case NON_DEPENDENT_EXPR:
     365                 :  422705000 :     case VIEW_CONVERT_EXPR:
     366                 :  422705000 :       mark_exp_read (TREE_OPERAND (exp, 0));
     367                 :  422705000 :       break;
     368                 :    2044030 :     case COMPOUND_EXPR:
     369                 :    2044030 :       mark_exp_read (TREE_OPERAND (exp, 1));
     370                 :    2044030 :       break;
     371                 :    2193010 :     case COND_EXPR:
     372                 :    2193010 :       if (TREE_OPERAND (exp, 1))
     373                 :    2193000 :         mark_exp_read (TREE_OPERAND (exp, 1));
     374                 :    2193010 :       if (TREE_OPERAND (exp, 2))
     375                 :    2193010 :         mark_exp_read (TREE_OPERAND (exp, 2));
     376                 :            :       break;
     377                 :            :     default:
     378                 :            :       break;
     379                 :            :     }
     380                 :            : }
     381                 :            : 
     382                 :            : /* Fold X for consideration by one of the warning functions when checking
     383                 :            :    whether an expression has a constant value.  */
     384                 :            : 
     385                 :            : tree
     386                 :   12494600 : fold_for_warn (tree x)
     387                 :            : {
     388                 :            :   /* C++ implementation.  */
     389                 :            : 
     390                 :            :   /* It's not generally safe to fully fold inside of a template, so
     391                 :            :      call fold_non_dependent_expr instead.  */
     392                 :   12494600 :   if (processing_template_decl)
     393                 :            :     {
     394                 :     267927 :       tree f = fold_non_dependent_expr (x, tf_none);
     395                 :     267927 :       if (f == error_mark_node)
     396                 :            :         return x;
     397                 :            :       else
     398                 :     267917 :         return f;
     399                 :            :     }
     400                 :   12226600 :   else if (cxx_dialect >= cxx11)
     401                 :   11920000 :     x = maybe_constant_value (x, NULL_TREE, false, true);
     402                 :            : 
     403                 :   12226600 :   return c_fully_fold (x, /*for_init*/false, /*maybe_constp*/NULL);
     404                 :            : }

Generated by: LCOV version 1.0

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 --enable-host-shared. GCC test suite is run with the built compiler.