2014-07-29 Ed Smith-Rowland <3dw4rd@verizon.net>
[official-gcc.git] / gcc / c-family / c-gimplify.c
blob2b5ce5ba86f998f84ac4d4fd34dc671ac17eac60
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-2014 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>
10 This file is part of GCC.
12 GCC is free software; you can redistribute it and/or modify it under
13 the terms of the GNU General Public License as published by the Free
14 Software Foundation; either version 3, or (at your option) any later
15 version.
17 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
18 WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 for more details.
22 You should have received a copy of the GNU General Public License
23 along with GCC; see the file COPYING3. If not see
24 <http://www.gnu.org/licenses/>. */
26 #include "config.h"
27 #include "system.h"
28 #include "coretypes.h"
29 #include "tm.h"
30 #include "tree.h"
31 #include "c-common.h"
32 #include "basic-block.h"
33 #include "tree-ssa-alias.h"
34 #include "internal-fn.h"
35 #include "gimple-expr.h"
36 #include "is-a.h"
37 #include "gimple.h"
38 #include "gimplify.h"
39 #include "tree-inline.h"
40 #include "diagnostic-core.h"
41 #include "langhooks.h"
42 #include "langhooks-def.h"
43 #include "flags.h"
44 #include "dumpfile.h"
45 #include "c-pretty-print.h"
46 #include "cgraph.h"
47 #include "cilk.h"
48 #include "c-ubsan.h"
49 #include "pointer-set.h"
51 /* The gimplification pass converts the language-dependent trees
52 (ld-trees) emitted by the parser into language-independent trees
53 (li-trees) that are the target of SSA analysis and transformations.
55 Language-independent trees are based on the SIMPLE intermediate
56 representation used in the McCAT compiler framework:
58 "Designing the McCAT Compiler Based on a Family of Structured
59 Intermediate Representations,"
60 L. Hendren, C. Donawa, M. Emami, G. Gao, Justiani, and B. Sridharan,
61 Proceedings of the 5th International Workshop on Languages and
62 Compilers for Parallel Computing, no. 757 in Lecture Notes in
63 Computer Science, New Haven, Connecticut, pp. 406-420,
64 Springer-Verlag, August 3-5, 1992.
66 http://www-acaps.cs.mcgill.ca/info/McCAT/McCAT.html
68 Basically, we walk down gimplifying the nodes that we encounter. As we
69 walk back up, we check that they fit our constraints, and copy them
70 into temporaries if not. */
72 /* Callback for c_genericize. */
74 static tree
75 ubsan_walk_array_refs_r (tree *tp, int *walk_subtrees, void *data)
77 struct pointer_set_t *pset = (struct pointer_set_t *) data;
79 /* Since walk_tree doesn't call the callback function on the decls
80 in BIND_EXPR_VARS, we have to walk them manually. */
81 if (TREE_CODE (*tp) == BIND_EXPR)
83 for (tree decl = BIND_EXPR_VARS (*tp); decl; decl = DECL_CHAIN (decl))
85 if (TREE_STATIC (decl))
87 *walk_subtrees = 0;
88 continue;
90 walk_tree (&DECL_INITIAL (decl), ubsan_walk_array_refs_r, pset,
91 pset);
92 walk_tree (&DECL_SIZE (decl), ubsan_walk_array_refs_r, pset, pset);
93 walk_tree (&DECL_SIZE_UNIT (decl), ubsan_walk_array_refs_r, pset,
94 pset);
97 else if (TREE_CODE (*tp) == ADDR_EXPR
98 && TREE_CODE (TREE_OPERAND (*tp, 0)) == ARRAY_REF)
99 ubsan_maybe_instrument_array_ref (&TREE_OPERAND (*tp, 0), true);
100 else if (TREE_CODE (*tp) == ARRAY_REF)
101 ubsan_maybe_instrument_array_ref (tp, false);
102 return NULL_TREE;
105 /* Gimplification of statement trees. */
107 /* Convert the tree representation of FNDECL from C frontend trees to
108 GENERIC. */
110 void
111 c_genericize (tree fndecl)
113 FILE *dump_orig;
114 int local_dump_flags;
115 struct cgraph_node *cgn;
117 if (flag_sanitize & SANITIZE_BOUNDS)
119 struct pointer_set_t *pset = pointer_set_create ();
120 walk_tree (&DECL_SAVED_TREE (fndecl), ubsan_walk_array_refs_r, pset,
121 pset);
122 pointer_set_destroy (pset);
125 /* Dump the C-specific tree IR. */
126 dump_orig = get_dump_info (TDI_original, &local_dump_flags);
127 if (dump_orig)
129 fprintf (dump_orig, "\n;; Function %s",
130 lang_hooks.decl_printable_name (fndecl, 2));
131 fprintf (dump_orig, " (%s)\n",
132 (!DECL_ASSEMBLER_NAME_SET_P (fndecl) ? "null"
133 : IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl))));
134 fprintf (dump_orig, ";; enabled by -%s\n", dump_flag_name (TDI_original));
135 fprintf (dump_orig, "\n");
137 if (local_dump_flags & TDF_RAW)
138 dump_node (DECL_SAVED_TREE (fndecl),
139 TDF_SLIM | local_dump_flags, dump_orig);
140 else
141 print_c_tree (dump_orig, DECL_SAVED_TREE (fndecl));
142 fprintf (dump_orig, "\n");
145 /* Dump all nested functions now. */
146 cgn = cgraph_node::get_create (fndecl);
147 for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested)
148 c_genericize (cgn->decl);
151 static void
152 add_block_to_enclosing (tree block)
154 unsigned i;
155 tree enclosing;
156 gimple bind;
157 vec<gimple> stack = gimple_bind_expr_stack ();
159 FOR_EACH_VEC_ELT (stack, i, bind)
160 if (gimple_bind_block (bind))
161 break;
163 enclosing = gimple_bind_block (bind);
164 BLOCK_SUBBLOCKS (enclosing) = chainon (BLOCK_SUBBLOCKS (enclosing), block);
167 /* Genericize a scope by creating a new BIND_EXPR.
168 BLOCK is either a BLOCK representing the scope or a chain of _DECLs.
169 In the latter case, we need to create a new BLOCK and add it to the
170 BLOCK_SUBBLOCKS of the enclosing block.
171 BODY is a chain of C _STMT nodes for the contents of the scope, to be
172 genericized. */
174 tree
175 c_build_bind_expr (location_t loc, tree block, tree body)
177 tree decls, bind;
179 if (block == NULL_TREE)
180 decls = NULL_TREE;
181 else if (TREE_CODE (block) == BLOCK)
182 decls = BLOCK_VARS (block);
183 else
185 decls = block;
186 if (DECL_ARTIFICIAL (decls))
187 block = NULL_TREE;
188 else
190 block = make_node (BLOCK);
191 BLOCK_VARS (block) = decls;
192 add_block_to_enclosing (block);
196 if (!body)
197 body = build_empty_stmt (loc);
198 if (decls || block)
200 bind = build3 (BIND_EXPR, void_type_node, decls, body, block);
201 TREE_SIDE_EFFECTS (bind) = 1;
202 SET_EXPR_LOCATION (bind, loc);
204 else
205 bind = body;
207 return bind;
210 /* Gimplification of expression trees. */
212 /* Do C-specific gimplification on *EXPR_P. PRE_P and POST_P are as in
213 gimplify_expr. */
216 c_gimplify_expr (tree *expr_p, gimple_seq *pre_p ATTRIBUTE_UNUSED,
217 gimple_seq *post_p ATTRIBUTE_UNUSED)
219 enum tree_code code = TREE_CODE (*expr_p);
221 switch (code)
223 case DECL_EXPR:
224 /* This is handled mostly by gimplify.c, but we have to deal with
225 not warning about int x = x; as it is a GCC extension to turn off
226 this warning but only if warn_init_self is zero. */
227 if (TREE_CODE (DECL_EXPR_DECL (*expr_p)) == VAR_DECL
228 && !DECL_EXTERNAL (DECL_EXPR_DECL (*expr_p))
229 && !TREE_STATIC (DECL_EXPR_DECL (*expr_p))
230 && (DECL_INITIAL (DECL_EXPR_DECL (*expr_p)) == DECL_EXPR_DECL (*expr_p))
231 && !warn_init_self)
232 TREE_NO_WARNING (DECL_EXPR_DECL (*expr_p)) = 1;
233 break;
235 case PREINCREMENT_EXPR:
236 case PREDECREMENT_EXPR:
237 case POSTINCREMENT_EXPR:
238 case POSTDECREMENT_EXPR:
240 tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 0));
241 if (INTEGRAL_TYPE_P (type) && c_promoting_integer_type_p (type))
243 if (!TYPE_OVERFLOW_WRAPS (type))
244 type = unsigned_type_for (type);
245 return gimplify_self_mod_expr (expr_p, pre_p, post_p, 1, type);
247 break;
250 case CILK_SPAWN_STMT:
251 gcc_assert
252 (fn_contains_cilk_spawn_p (cfun)
253 && cilk_detect_spawn_and_unwrap (expr_p));
255 /* If errors are seen, then just process it as a CALL_EXPR. */
256 if (!seen_error ())
257 return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
259 case MODIFY_EXPR:
260 case INIT_EXPR:
261 case CALL_EXPR:
262 if (fn_contains_cilk_spawn_p (cfun)
263 && cilk_detect_spawn_and_unwrap (expr_p)
264 /* If an error is found, the spawn wrapper is removed and the
265 original expression (MODIFY/INIT/CALL_EXPR) is processes as
266 it is supposed to be. */
267 && !seen_error ())
268 return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
270 default:;
273 return GS_UNHANDLED;