LCOV - code coverage report
Current view: top level - gcc/c-family - c-semantics.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 90.0 % 80 72
Test Date: 2026-02-28 14:20:25 Functions: 100.0 % 4 4
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* This file contains subroutine used by the C front-end to construct GENERIC.
       2              :    Copyright (C) 2000-2026 Free Software Foundation, Inc.
       3              :    Written by Benjamin Chelf (chelf@codesourcery.com).
       4              : 
       5              : This file is part of GCC.
       6              : 
       7              : GCC is free software; you can redistribute it and/or modify it under
       8              : the terms of the GNU General Public License as published by the Free
       9              : Software Foundation; either version 3, or (at your option) any later
      10              : version.
      11              : 
      12              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      13              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      14              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      15              : 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              : #include "config.h"
      22              : #include "system.h"
      23              : #include "coretypes.h"
      24              : #include "c-common.h"
      25              : #include "tree-iterator.h"
      26              : 
      27              : /* Create an empty statement tree rooted at T.  */
      28              : 
      29              : tree
      30    872533423 : push_stmt_list (void)
      31              : {
      32    872533423 :   tree t;
      33    872533423 :   t = alloc_stmt_list ();
      34    872533423 :   vec_safe_push (stmt_list_stack, t);
      35    872533423 :   return t;
      36              : }
      37              : 
      38              : /* Return TRUE if, after I, there are any nondebug stmts.  */
      39              : 
      40              : static inline bool
      41    212038463 : only_debug_stmts_after_p (tree_stmt_iterator i)
      42              : {
      43    273728654 :   for (tsi_next (&i); !tsi_end_p (i); tsi_next (&i))
      44    126414076 :     if (TREE_CODE (tsi_stmt (i)) != DEBUG_BEGIN_STMT)
      45              :       return false;
      46              :   return true;
      47              : }
      48              : 
      49              : /* Finish the statement tree rooted at T.  */
      50              : 
      51              : tree
      52    866397605 : pop_stmt_list (tree t)
      53              : {
      54    866397605 :   tree u = NULL_TREE;
      55              : 
      56              :   /* Pop statement lists until we reach the target level.  The extra
      57              :      nestings will be due to outstanding cleanups.  */
      58    872532357 :   while (1)
      59              :     {
      60    872532357 :       u = stmt_list_stack->pop ();
      61    872532357 :       if (!stmt_list_stack->is_empty ())
      62              :         {
      63    669636998 :           tree x = stmt_list_stack->last ();
      64    669636998 :           STATEMENT_LIST_HAS_LABEL (x) |= STATEMENT_LIST_HAS_LABEL (u);
      65              :         }
      66    872532357 :       if (t == u)
      67              :         break;
      68              :     }
      69              : 
      70    866397605 :   gcc_assert (u != NULL_TREE);
      71              : 
      72              :   /* If the statement list is completely empty, just return it.  This is
      73              :      just as good small as build_empty_stmt, with the advantage that
      74              :      statement lists are merged when they appended to one another.  So
      75              :      using the STATEMENT_LIST avoids pathological buildup of EMPTY_STMT_P
      76              :      statements.  */
      77    866397605 :   if (TREE_SIDE_EFFECTS (t))
      78              :     {
      79    773705525 :       tree_stmt_iterator i = tsi_start (t);
      80              : 
      81              :       /* If the statement list contained exactly one statement, then
      82              :          extract it immediately.  */
      83    773705525 :       if (tsi_one_before_end_p (i))
      84              :         {
      85    516700320 :           u = tsi_stmt (i);
      86    516700320 :           tsi_delink (&i);
      87    516700320 :           free_stmt_list (t);
      88    516700320 :           t = u;
      89              :         }
      90              :       /* If the statement list contained a debug begin stmt and a
      91              :          statement list, move the debug begin stmt into the statement
      92              :          list and return it.  */
      93    257005205 :       else if (!tsi_end_p (i)
      94    257005205 :                && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
      95              :         {
      96    212038604 :           u = tsi_stmt (i);
      97    212038604 :           tsi_next (&i);
      98    424077208 :           if (tsi_one_before_end_p (i)
      99    145584040 :               && TREE_CODE (tsi_stmt (i)) == STATEMENT_LIST)
     100              :             {
     101            0 :               tree l = tsi_stmt (i);
     102            0 :               tsi_prev (&i);
     103            0 :               tsi_delink (&i);
     104            0 :               tsi_delink (&i);
     105            0 :               i = tsi_start (l);
     106            0 :               free_stmt_list (t);
     107            0 :               t = l;
     108            0 :               tsi_link_before (&i, u, TSI_SAME_STMT);
     109              :             }
     110    215903669 :           while (!tsi_end_p (i)
     111    215903669 :                  && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
     112      3865065 :             tsi_next (&i);
     113              :           /* If there are only debug stmts in the list, without them
     114              :              we'd have an empty stmt without side effects.  If there's
     115              :              only one nondebug stmt, we'd have extracted the stmt and
     116              :              dropped the list, and we'd take TREE_SIDE_EFFECTS from
     117              :              that statement.  In either case, keep the list's
     118              :              TREE_SIDE_EFFECTS in sync.  */
     119    212038604 :           if (tsi_end_p (i))
     120          141 :             TREE_SIDE_EFFECTS (t) = 0;
     121    424076926 :           else if (only_debug_stmts_after_p (i))
     122    147314578 :             TREE_SIDE_EFFECTS (t) = TREE_SIDE_EFFECTS (tsi_stmt (i));
     123              :         }
     124              :     }
     125              : 
     126    866397605 :   return t;
     127              : }
     128              : 
     129              : /* Build a generic statement based on the given type of node and
     130              :    arguments. Similar to `build_nt', except that we set
     131              :    EXPR_LOCATION to LOC. */
     132              : /* ??? This should be obsolete with the lineno_stmt productions
     133              :    in the grammar.  */
     134              : 
     135              : tree
     136    608469900 : build_stmt (location_t loc, enum tree_code code, ...)
     137              : {
     138    608469900 :   tree ret;
     139    608469900 :   int length, i;
     140    608469900 :   va_list p;
     141    608469900 :   bool side_effects;
     142              : 
     143              :   /* This function cannot be used to construct variably-sized nodes.  */
     144    608469900 :   gcc_assert (TREE_CODE_CLASS (code) != tcc_vl_exp);
     145              : 
     146    608469900 :   va_start (p, code);
     147              : 
     148    608469900 :   ret = make_node (code);
     149    608469900 :   TREE_TYPE (ret) = void_type_node;
     150    608469900 :   length = TREE_CODE_LENGTH (code);
     151    608469900 :   SET_EXPR_LOCATION (ret, loc);
     152              : 
     153              :   /* TREE_SIDE_EFFECTS will already be set for statements with
     154              :      implicit side effects.  Here we make sure it is set for other
     155              :      expressions by checking whether the parameters have side
     156              :      effects.  */
     157              : 
     158    608469900 :   side_effects = false;
     159   1594699219 :   for (i = 0; i < length; i++)
     160              :     {
     161    986229319 :       tree t = va_arg (p, tree);
     162    986229319 :       if (t && !TYPE_P (t))
     163    556069427 :         side_effects |= TREE_SIDE_EFFECTS (t);
     164    986229319 :       TREE_OPERAND (ret, i) = t;
     165              :     }
     166              : 
     167    608469900 :   TREE_SIDE_EFFECTS (ret) |= side_effects;
     168              : 
     169    608469900 :   va_end (p);
     170    608469900 :   return ret;
     171              : }
     172              : 
     173              : /* Build a REALPART_EXPR or IMAGPART_EXPR, according to CODE, from ARG.  */
     174              : 
     175              : tree
     176       641632 : build_real_imag_expr (location_t location, enum tree_code code, tree arg)
     177              : {
     178       641632 :   tree ret;
     179       641632 :   tree arg_type = TREE_TYPE (arg);
     180              : 
     181       641632 :   gcc_assert (code == REALPART_EXPR || code == IMAGPART_EXPR);
     182              : 
     183       641632 :   if (TREE_CODE (arg_type) == COMPLEX_TYPE)
     184              :     {
     185       633849 :       ret = build1 (code, TREE_TYPE (TREE_TYPE (arg)), arg);
     186       633849 :       SET_EXPR_LOCATION (ret, location);
     187              :     }
     188         7783 :   else if (INTEGRAL_TYPE_P (arg_type) || SCALAR_FLOAT_TYPE_P (arg_type))
     189              :     {
     190         7769 :       ret = (code == REALPART_EXPR
     191         7769 :              ? arg
     192         3872 :              : omit_one_operand_loc (location, arg_type,
     193              :                                      integer_zero_node, arg));
     194              :     }
     195              :   else
     196              :     {
     197           21 :       error_at (location, "wrong type argument to %s",
     198              :                 code == REALPART_EXPR ? "__real" : "__imag");
     199           14 :       ret = error_mark_node;
     200              :     }
     201              : 
     202       641632 :   return ret;
     203              : }
        

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.