c-gimplify.c revision 1.11
1/* Tree lowering pass.  This pass gimplifies the tree representation built
2   by the C-based front ends.  The structure of gimplified, or
3   language-independent, trees is dictated by the grammar described in this
4   file.
5   Copyright (C) 2002-2020 Free Software Foundation, Inc.
6   Lowering of expressions contributed by Sebastian Pop <s.pop@laposte.net>
7   Re-written to support lowering of whole function trees, documentation
8   and miscellaneous cleanups by Diego Novillo <dnovillo@redhat.com>
9
10This file is part of GCC.
11
12GCC is free software; you can redistribute it and/or modify it under
13the terms of the GNU General Public License as published by the Free
14Software Foundation; either version 3, or (at your option) any later
15version.
16
17GCC is distributed in the hope that it will be useful, but WITHOUT ANY
18WARRANTY; without even the implied warranty of MERCHANTABILITY or
19FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20for more details.
21
22You should have received a copy of the GNU General Public License
23along with GCC; see the file COPYING3.  If not see
24<http://www.gnu.org/licenses/>.  */
25
26#include "config.h"
27#include "system.h"
28#include "coretypes.h"
29#include "tm.h"
30#include "function.h"
31#include "basic-block.h"
32#include "tree.h"
33#include "gimple.h"
34#include "cgraph.h"
35#include "c-pretty-print.h"
36#include "gimplify.h"
37#include "langhooks.h"
38#include "dumpfile.h"
39#include "c-ubsan.h"
40
41/*  The gimplification pass converts the language-dependent trees
42    (ld-trees) emitted by the parser into language-independent trees
43    (li-trees) that are the target of SSA analysis and transformations.
44
45    Language-independent trees are based on the SIMPLE intermediate
46    representation used in the McCAT compiler framework:
47
48    "Designing the McCAT Compiler Based on a Family of Structured
49    Intermediate Representations,"
50    L. Hendren, C. Donawa, M. Emami, G. Gao, Justiani, and B. Sridharan,
51    Proceedings of the 5th International Workshop on Languages and
52    Compilers for Parallel Computing, no. 757 in Lecture Notes in
53    Computer Science, New Haven, Connecticut, pp. 406-420,
54    Springer-Verlag, August 3-5, 1992.
55
56    http://www-acaps.cs.mcgill.ca/info/McCAT/McCAT.html
57
58    Basically, we walk down gimplifying the nodes that we encounter.  As we
59    walk back up, we check that they fit our constraints, and copy them
60    into temporaries if not.  */
61
62/* Callback for c_genericize.  */
63
64static tree
65ubsan_walk_array_refs_r (tree *tp, int *walk_subtrees, void *data)
66{
67  hash_set<tree> *pset = (hash_set<tree> *) data;
68
69  if (TREE_CODE (*tp) == BIND_EXPR)
70    {
71      /* Since walk_tree doesn't call the callback function on the decls
72	 in BIND_EXPR_VARS, we have to walk them manually, so we can avoid
73	 instrumenting DECL_INITIAL of TREE_STATIC vars.  */
74      *walk_subtrees = 0;
75      for (tree decl = BIND_EXPR_VARS (*tp); decl; decl = DECL_CHAIN (decl))
76	{
77	  if (TREE_STATIC (decl))
78	    continue;
79	  walk_tree (&DECL_INITIAL (decl), ubsan_walk_array_refs_r, pset,
80		     pset);
81	  walk_tree (&DECL_SIZE (decl), ubsan_walk_array_refs_r, pset, pset);
82	  walk_tree (&DECL_SIZE_UNIT (decl), ubsan_walk_array_refs_r, pset,
83		     pset);
84	}
85      walk_tree (&BIND_EXPR_BODY (*tp), ubsan_walk_array_refs_r, pset, pset);
86    }
87  else if (TREE_CODE (*tp) == ADDR_EXPR
88	   && TREE_CODE (TREE_OPERAND (*tp, 0)) == ARRAY_REF)
89    {
90      ubsan_maybe_instrument_array_ref (&TREE_OPERAND (*tp, 0), true);
91      /* Make sure ubsan_maybe_instrument_array_ref is not called again
92	 on the ARRAY_REF, the above call might not instrument anything
93	 as the index might be constant or masked, so ensure it is not
94	 walked again and walk its subtrees manually.  */
95      tree aref = TREE_OPERAND (*tp, 0);
96      pset->add (aref);
97      *walk_subtrees = 0;
98      walk_tree (&TREE_OPERAND (aref, 0), ubsan_walk_array_refs_r, pset, pset);
99      walk_tree (&TREE_OPERAND (aref, 1), ubsan_walk_array_refs_r, pset, pset);
100      walk_tree (&TREE_OPERAND (aref, 2), ubsan_walk_array_refs_r, pset, pset);
101      walk_tree (&TREE_OPERAND (aref, 3), ubsan_walk_array_refs_r, pset, pset);
102    }
103  else if (TREE_CODE (*tp) == ARRAY_REF)
104    ubsan_maybe_instrument_array_ref (tp, false);
105  return NULL_TREE;
106}
107
108/* Gimplification of statement trees.  */
109
110/* Convert the tree representation of FNDECL from C frontend trees to
111   GENERIC.  */
112
113void
114c_genericize (tree fndecl)
115{
116  FILE *dump_orig;
117  dump_flags_t local_dump_flags;
118  struct cgraph_node *cgn;
119
120  if (flag_sanitize & SANITIZE_BOUNDS)
121    {
122      hash_set<tree> pset;
123      walk_tree (&DECL_SAVED_TREE (fndecl), ubsan_walk_array_refs_r, &pset,
124		 &pset);
125    }
126
127  if (warn_duplicated_branches)
128    walk_tree_without_duplicates (&DECL_SAVED_TREE (fndecl),
129				  do_warn_duplicated_branches_r, NULL);
130
131  /* Dump the C-specific tree IR.  */
132  dump_orig = get_dump_info (TDI_original, &local_dump_flags);
133  if (dump_orig)
134    {
135      fprintf (dump_orig, "\n;; Function %s",
136	       lang_hooks.decl_printable_name (fndecl, 2));
137      fprintf (dump_orig, " (%s)\n",
138	       (!DECL_ASSEMBLER_NAME_SET_P (fndecl) ? "null"
139		: IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl))));
140      fprintf (dump_orig, ";; enabled by -%s\n", dump_flag_name (TDI_original));
141      fprintf (dump_orig, "\n");
142
143      if (local_dump_flags & TDF_RAW)
144	dump_node (DECL_SAVED_TREE (fndecl),
145		   TDF_SLIM | local_dump_flags, dump_orig);
146      else
147	print_c_tree (dump_orig, DECL_SAVED_TREE (fndecl));
148      fprintf (dump_orig, "\n");
149    }
150
151  /* Dump all nested functions now.  */
152  cgn = cgraph_node::get_create (fndecl);
153  for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested)
154    c_genericize (cgn->decl);
155}
156
157static void
158add_block_to_enclosing (tree block)
159{
160  unsigned i;
161  tree enclosing;
162  gbind *bind;
163  vec<gbind *> stack = gimple_bind_expr_stack ();
164
165  FOR_EACH_VEC_ELT (stack, i, bind)
166    if (gimple_bind_block (bind))
167      break;
168
169  enclosing = gimple_bind_block (bind);
170  BLOCK_SUBBLOCKS (enclosing) = chainon (BLOCK_SUBBLOCKS (enclosing), block);
171}
172
173/* Genericize a scope by creating a new BIND_EXPR.
174   BLOCK is either a BLOCK representing the scope or a chain of _DECLs.
175     In the latter case, we need to create a new BLOCK and add it to the
176     BLOCK_SUBBLOCKS of the enclosing block.
177   BODY is a chain of C _STMT nodes for the contents of the scope, to be
178     genericized.  */
179
180tree
181c_build_bind_expr (location_t loc, tree block, tree body)
182{
183  tree decls, bind;
184
185  if (block == NULL_TREE)
186    decls = NULL_TREE;
187  else if (TREE_CODE (block) == BLOCK)
188    decls = BLOCK_VARS (block);
189  else
190    {
191      decls = block;
192      if (DECL_ARTIFICIAL (decls))
193	block = NULL_TREE;
194      else
195	{
196	  block = make_node (BLOCK);
197	  BLOCK_VARS (block) = decls;
198	  add_block_to_enclosing (block);
199	}
200    }
201
202  if (!body)
203    body = build_empty_stmt (loc);
204  if (decls || block)
205    {
206      bind = build3 (BIND_EXPR, void_type_node, decls, body, block);
207      TREE_SIDE_EFFECTS (bind) = 1;
208      SET_EXPR_LOCATION (bind, loc);
209    }
210  else
211    bind = body;
212
213  return bind;
214}
215
216/* Gimplification of expression trees.  */
217
218/* Do C-specific gimplification on *EXPR_P.  PRE_P and POST_P are as in
219   gimplify_expr.  */
220
221int
222c_gimplify_expr (tree *expr_p, gimple_seq *pre_p ATTRIBUTE_UNUSED,
223		 gimple_seq *post_p ATTRIBUTE_UNUSED)
224{
225  enum tree_code code = TREE_CODE (*expr_p);
226
227  switch (code)
228    {
229    case LSHIFT_EXPR:
230    case RSHIFT_EXPR:
231    case LROTATE_EXPR:
232    case RROTATE_EXPR:
233      {
234	/* We used to convert the right operand of a shift-expression
235	   to an integer_type_node in the FEs.  But it is unnecessary
236	   and not desirable for diagnostics and sanitizers.  We keep
237	   this here to not pessimize the code, but we convert to an
238	   unsigned type, because negative shift counts are undefined
239	   anyway.
240	   We should get rid of this conversion when we have a proper
241	   type demotion/promotion pass.  */
242	tree *op1_p = &TREE_OPERAND (*expr_p, 1);
243	if (!VECTOR_TYPE_P (TREE_TYPE (*op1_p))
244	    && !types_compatible_p (TYPE_MAIN_VARIANT (TREE_TYPE (*op1_p)),
245				    unsigned_type_node)
246	    && !types_compatible_p (TYPE_MAIN_VARIANT (TREE_TYPE (*op1_p)),
247				    integer_type_node))
248	  /* Make sure to unshare the result, tree sharing is invalid
249	     during gimplification.  */
250	  *op1_p = unshare_expr (convert (unsigned_type_node, *op1_p));
251	break;
252      }
253
254    case DECL_EXPR:
255      /* This is handled mostly by gimplify.c, but we have to deal with
256	 not warning about int x = x; as it is a GCC extension to turn off
257	 this warning but only if warn_init_self is zero.  */
258      if (VAR_P (DECL_EXPR_DECL (*expr_p))
259	  && !DECL_EXTERNAL (DECL_EXPR_DECL (*expr_p))
260	  && !TREE_STATIC (DECL_EXPR_DECL (*expr_p))
261	  && (DECL_INITIAL (DECL_EXPR_DECL (*expr_p)) == DECL_EXPR_DECL (*expr_p))
262	  && !warn_init_self)
263	TREE_NO_WARNING (DECL_EXPR_DECL (*expr_p)) = 1;
264      break;
265
266    case PREINCREMENT_EXPR:
267    case PREDECREMENT_EXPR:
268    case POSTINCREMENT_EXPR:
269    case POSTDECREMENT_EXPR:
270      {
271	tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 0));
272	if (INTEGRAL_TYPE_P (type) && c_promoting_integer_type_p (type))
273	  {
274	    if (!TYPE_OVERFLOW_WRAPS (type))
275	      type = unsigned_type_for (type);
276	    return gimplify_self_mod_expr (expr_p, pre_p, post_p, 1, type);
277	  }
278	break;
279      }
280
281    default:;
282    }
283
284  return GS_UNHANDLED;
285}
286