c-gimplify.c revision 1.5
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-2016 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 "cilk.h"
40#include "c-ubsan.h"
41
42/*  The gimplification pass converts the language-dependent trees
43    (ld-trees) emitted by the parser into language-independent trees
44    (li-trees) that are the target of SSA analysis and transformations.
45
46    Language-independent trees are based on the SIMPLE intermediate
47    representation used in the McCAT compiler framework:
48
49    "Designing the McCAT Compiler Based on a Family of Structured
50    Intermediate Representations,"
51    L. Hendren, C. Donawa, M. Emami, G. Gao, Justiani, and B. Sridharan,
52    Proceedings of the 5th International Workshop on Languages and
53    Compilers for Parallel Computing, no. 757 in Lecture Notes in
54    Computer Science, New Haven, Connecticut, pp. 406-420,
55    Springer-Verlag, August 3-5, 1992.
56
57    http://www-acaps.cs.mcgill.ca/info/McCAT/McCAT.html
58
59    Basically, we walk down gimplifying the nodes that we encounter.  As we
60    walk back up, we check that they fit our constraints, and copy them
61    into temporaries if not.  */
62
63/* Callback for c_genericize.  */
64
65static tree
66ubsan_walk_array_refs_r (tree *tp, int *walk_subtrees, void *data)
67{
68  hash_set<tree> *pset = (hash_set<tree> *) data;
69
70  if (TREE_CODE (*tp) == BIND_EXPR)
71    {
72      /* Since walk_tree doesn't call the callback function on the decls
73	 in BIND_EXPR_VARS, we have to walk them manually, so we can avoid
74	 instrumenting DECL_INITIAL of TREE_STATIC vars.  */
75      *walk_subtrees = 0;
76      for (tree decl = BIND_EXPR_VARS (*tp); decl; decl = DECL_CHAIN (decl))
77	{
78	  if (TREE_STATIC (decl))
79	    continue;
80	  walk_tree (&DECL_INITIAL (decl), ubsan_walk_array_refs_r, pset,
81		     pset);
82	  walk_tree (&DECL_SIZE (decl), ubsan_walk_array_refs_r, pset, pset);
83	  walk_tree (&DECL_SIZE_UNIT (decl), ubsan_walk_array_refs_r, pset,
84		     pset);
85	}
86      walk_tree (&BIND_EXPR_BODY (*tp), ubsan_walk_array_refs_r, pset, pset);
87    }
88  else if (TREE_CODE (*tp) == ADDR_EXPR
89	   && TREE_CODE (TREE_OPERAND (*tp, 0)) == ARRAY_REF)
90    {
91      ubsan_maybe_instrument_array_ref (&TREE_OPERAND (*tp, 0), true);
92      /* Make sure ubsan_maybe_instrument_array_ref is not called again
93	 on the ARRAY_REF, the above call might not instrument anything
94	 as the index might be constant or masked, so ensure it is not
95	 walked again and walk its subtrees manually.  */
96      tree aref = TREE_OPERAND (*tp, 0);
97      pset->add (aref);
98      *walk_subtrees = 0;
99      walk_tree (&TREE_OPERAND (aref, 0), ubsan_walk_array_refs_r, pset, pset);
100      walk_tree (&TREE_OPERAND (aref, 1), ubsan_walk_array_refs_r, pset, pset);
101      walk_tree (&TREE_OPERAND (aref, 2), ubsan_walk_array_refs_r, pset, pset);
102      walk_tree (&TREE_OPERAND (aref, 3), ubsan_walk_array_refs_r, pset, pset);
103    }
104  else if (TREE_CODE (*tp) == ARRAY_REF)
105    ubsan_maybe_instrument_array_ref (tp, false);
106  return NULL_TREE;
107}
108
109/* Gimplification of statement trees.  */
110
111/* Convert the tree representation of FNDECL from C frontend trees to
112   GENERIC.  */
113
114void
115c_genericize (tree fndecl)
116{
117  FILE *dump_orig;
118  int local_dump_flags;
119  struct cgraph_node *cgn;
120
121  if (flag_sanitize & SANITIZE_BOUNDS)
122    {
123      hash_set<tree> pset;
124      walk_tree (&DECL_SAVED_TREE (fndecl), ubsan_walk_array_refs_r, &pset,
125		 &pset);
126    }
127
128  /* Dump the C-specific tree IR.  */
129  dump_orig = get_dump_info (TDI_original, &local_dump_flags);
130  if (dump_orig)
131    {
132      fprintf (dump_orig, "\n;; Function %s",
133	       lang_hooks.decl_printable_name (fndecl, 2));
134      fprintf (dump_orig, " (%s)\n",
135	       (!DECL_ASSEMBLER_NAME_SET_P (fndecl) ? "null"
136		: IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl))));
137      fprintf (dump_orig, ";; enabled by -%s\n", dump_flag_name (TDI_original));
138      fprintf (dump_orig, "\n");
139
140      if (local_dump_flags & TDF_RAW)
141	dump_node (DECL_SAVED_TREE (fndecl),
142		   TDF_SLIM | local_dump_flags, dump_orig);
143      else
144	print_c_tree (dump_orig, DECL_SAVED_TREE (fndecl));
145      fprintf (dump_orig, "\n");
146    }
147
148  /* Dump all nested functions now.  */
149  cgn = cgraph_node::get_create (fndecl);
150  for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested)
151    c_genericize (cgn->decl);
152}
153
154static void
155add_block_to_enclosing (tree block)
156{
157  unsigned i;
158  tree enclosing;
159  gbind *bind;
160  vec<gbind *> stack = gimple_bind_expr_stack ();
161
162  FOR_EACH_VEC_ELT (stack, i, bind)
163    if (gimple_bind_block (bind))
164      break;
165
166  enclosing = gimple_bind_block (bind);
167  BLOCK_SUBBLOCKS (enclosing) = chainon (BLOCK_SUBBLOCKS (enclosing), block);
168}
169
170/* Genericize a scope by creating a new BIND_EXPR.
171   BLOCK is either a BLOCK representing the scope or a chain of _DECLs.
172     In the latter case, we need to create a new BLOCK and add it to the
173     BLOCK_SUBBLOCKS of the enclosing block.
174   BODY is a chain of C _STMT nodes for the contents of the scope, to be
175     genericized.  */
176
177tree
178c_build_bind_expr (location_t loc, tree block, tree body)
179{
180  tree decls, bind;
181
182  if (block == NULL_TREE)
183    decls = NULL_TREE;
184  else if (TREE_CODE (block) == BLOCK)
185    decls = BLOCK_VARS (block);
186  else
187    {
188      decls = block;
189      if (DECL_ARTIFICIAL (decls))
190	block = NULL_TREE;
191      else
192	{
193	  block = make_node (BLOCK);
194	  BLOCK_VARS (block) = decls;
195	  add_block_to_enclosing (block);
196	}
197    }
198
199  if (!body)
200    body = build_empty_stmt (loc);
201  if (decls || block)
202    {
203      bind = build3 (BIND_EXPR, void_type_node, decls, body, block);
204      TREE_SIDE_EFFECTS (bind) = 1;
205      SET_EXPR_LOCATION (bind, loc);
206    }
207  else
208    bind = body;
209
210  return bind;
211}
212
213/* Gimplification of expression trees.  */
214
215/* Do C-specific gimplification on *EXPR_P.  PRE_P and POST_P are as in
216   gimplify_expr.  */
217
218int
219c_gimplify_expr (tree *expr_p, gimple_seq *pre_p ATTRIBUTE_UNUSED,
220		 gimple_seq *post_p ATTRIBUTE_UNUSED)
221{
222  enum tree_code code = TREE_CODE (*expr_p);
223
224  switch (code)
225    {
226    case LSHIFT_EXPR:
227    case RSHIFT_EXPR:
228      {
229	/* We used to convert the right operand of a shift-expression
230	   to an integer_type_node in the FEs.  But it is unnecessary
231	   and not desirable for diagnostics and sanitizers.  We keep
232	   this here to not pessimize the code, but we convert to an
233	   unsigned type, because negative shift counts are undefined
234	   anyway.
235	   We should get rid of this conversion when we have a proper
236	   type demotion/promotion pass.  */
237	tree *op1_p = &TREE_OPERAND (*expr_p, 1);
238	if (!VECTOR_TYPE_P (TREE_TYPE (*op1_p))
239	    && !types_compatible_p (TYPE_MAIN_VARIANT (TREE_TYPE (*op1_p)),
240				    unsigned_type_node)
241	    && !types_compatible_p (TYPE_MAIN_VARIANT (TREE_TYPE (*op1_p)),
242				    integer_type_node))
243	  *op1_p = convert (unsigned_type_node, *op1_p);
244	break;
245      }
246
247    case DECL_EXPR:
248      /* This is handled mostly by gimplify.c, but we have to deal with
249	 not warning about int x = x; as it is a GCC extension to turn off
250	 this warning but only if warn_init_self is zero.  */
251      if (VAR_P (DECL_EXPR_DECL (*expr_p))
252	  && !DECL_EXTERNAL (DECL_EXPR_DECL (*expr_p))
253	  && !TREE_STATIC (DECL_EXPR_DECL (*expr_p))
254	  && (DECL_INITIAL (DECL_EXPR_DECL (*expr_p)) == DECL_EXPR_DECL (*expr_p))
255	  && !warn_init_self)
256	TREE_NO_WARNING (DECL_EXPR_DECL (*expr_p)) = 1;
257      break;
258
259    case PREINCREMENT_EXPR:
260    case PREDECREMENT_EXPR:
261    case POSTINCREMENT_EXPR:
262    case POSTDECREMENT_EXPR:
263      {
264	tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 0));
265	if (INTEGRAL_TYPE_P (type) && c_promoting_integer_type_p (type))
266	  {
267	    if (!TYPE_OVERFLOW_WRAPS (type))
268	      type = unsigned_type_for (type);
269	    return gimplify_self_mod_expr (expr_p, pre_p, post_p, 1, type);
270	  }
271	break;
272      }
273
274    case CILK_SPAWN_STMT:
275      gcc_assert(fn_contains_cilk_spawn_p (cfun)
276		 && cilk_detect_spawn_and_unwrap (expr_p));
277
278      if (!seen_error ())
279	{
280	  cilk_gimplify_call_params_in_spawned_fn (expr_p, pre_p);
281	  return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
282	}
283      return GS_ERROR;
284
285    case MODIFY_EXPR:
286    case INIT_EXPR:
287    case CALL_EXPR:
288      if (fn_contains_cilk_spawn_p (cfun)
289	  && cilk_detect_spawn_and_unwrap (expr_p)
290	  /* If an error is found, the spawn wrapper is removed and the
291	     original expression (MODIFY/INIT/CALL_EXPR) is processes as
292	     it is supposed to be.  */
293	  && !seen_error ())
294	{
295	  cilk_gimplify_call_params_in_spawned_fn (expr_p, pre_p);
296	  return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
297	}
298
299    default:;
300    }
301
302  return GS_UNHANDLED;
303}
304