]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/cp/expr.c
Update copyright years.
[thirdparty/gcc.git] / gcc / cp / expr.c
CommitLineData
8d08fdba
MS
1/* Convert language-specific tree expression to rtl instructions,
2 for GNU compiler.
a5544970 3 Copyright (C) 1988-2019 Free Software Foundation, Inc.
8d08fdba 4
f5adbb8d 5This file is part of GCC.
8d08fdba 6
f5adbb8d 7GCC is free software; you can redistribute it and/or modify
8d08fdba 8it under the terms of the GNU General Public License as published by
e77f031d 9the Free Software Foundation; either version 3, or (at your option)
8d08fdba
MS
10any later version.
11
f5adbb8d 12GCC is distributed in the hope that it will be useful,
8d08fdba
MS
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
e77f031d
NC
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
8d08fdba
MS
20
21
22#include "config.h"
8d052bc7 23#include "system.h"
4977bab6 24#include "coretypes.h"
8d08fdba
MS
25#include "cp-tree.h"
26
6524147c 27/* Expand C++-specific constants. Currently, this means PTRMEM_CST. */
87533b37 28
b928a651 29tree
d9b4e85e 30cplus_expand_constant (tree cst)
87533b37
MM
31{
32 switch (TREE_CODE (cst))
33 {
34 case PTRMEM_CST:
35 {
36 tree type = TREE_TYPE (cst);
37 tree member;
c8094d83 38
87533b37
MM
39 /* Find the member. */
40 member = PTRMEM_CST_MEMBER (cst);
41
deaae9d7
JM
42 /* We can't lower this until the class is complete. */
43 if (!COMPLETE_TYPE_P (DECL_CONTEXT (member)))
44 return cst;
45
c8094d83 46 if (TREE_CODE (member) == FIELD_DECL)
b3dd05b1
MM
47 {
48 /* Find the offset for the field. */
49 cst = byte_position (member);
50 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 member = lookup_anon_field (TYPE_PTRMEM_CLASS_TYPE (type),
57 DECL_CONTEXT (member));
58 cst = size_binop (PLUS_EXPR, cst, byte_position (member));
59 }
60 cst = fold (build_nop (type, cst));
61 }
87533b37
MM
62 else
63 {
530ec96d
MM
64 tree delta;
65 tree pfn;
87533b37 66
18ae7f63
AO
67 expand_ptrmemfunc_cst (cst, &delta, &pfn);
68 cst = build_ptrmemfunc1 (type, delta, pfn);
87533b37
MM
69 }
70 }
71 break;
72
2d7d7f0f
JM
73 case CONSTRUCTOR:
74 {
75 constructor_elt *elt;
76 unsigned HOST_WIDE_INT idx;
77 FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (cst), idx, elt)
78 elt->value = cplus_expand_constant (elt->value);
79 }
80
87533b37
MM
81 default:
82 /* There's nothing to do. */
83 break;
84 }
85
86 return cst;
87}
03a904b5 88
281e6c1d
JM
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
5a752e3f 92tree
281e6c1d
JM
93mark_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
84dd815f
JM
99 if (expr == NULL_TREE || expr == error_mark_node)
100 return expr;
101
281e6c1d
JM
102 if (reject_builtin && reject_gcc_builtin (expr, loc))
103 return error_mark_node;
104
105 if (read_p)
106 mark_exp_read (expr);
107
84dd815f 108 tree oexpr = expr;
281e6c1d
JM
109 bool recurse_op[3] = { false, false, false };
110 switch (TREE_CODE (expr))
111 {
112 case VAR_DECL:
84dd815f 113 case PARM_DECL:
68ad1bf7 114 if (rvalue_p && is_normal_capture_proxy (expr))
c1051bf7
JM
115 {
116 /* Look through capture by copy. */
117 tree cap = DECL_CAPTURED_VARIABLE (expr);
118 if (TREE_CODE (TREE_TYPE (cap)) == TREE_CODE (TREE_TYPE (expr))
119 && decl_constant_var_p (cap))
1577f10a
JM
120 {
121 tree val = RECUR (cap);
122 if (!is_capture_proxy (val))
123 {
124 tree l = current_lambda_expr ();
125 LAMBDA_EXPR_CAPTURE_OPTIMIZED (l) = true;
126 }
127 return val;
128 }
c1051bf7 129 }
281e6c1d
JM
130 if (outer_automatic_var_p (expr)
131 && decl_constant_var_p (expr))
132 {
133 if (rvalue_p)
134 {
135 tree t = maybe_constant_value (expr);
136 if (TREE_CONSTANT (t))
137 {
138 expr = t;
139 break;
140 }
141 }
57ea03ad
JM
142 temp_override<location_t> l (input_location);
143 if (loc != UNKNOWN_LOCATION)
144 input_location = loc;
281e6c1d 145 expr = process_outer_var_ref (expr, tf_warning_or_error, true);
84dd815f 146 if (!(TREE_TYPE (oexpr)
9f613f06 147 && TYPE_REF_P (TREE_TYPE (oexpr))))
84dd815f 148 expr = convert_from_reference (expr);
281e6c1d
JM
149 }
150 break;
151 case COMPONENT_REF:
84dd815f 152 case NON_DEPENDENT_EXPR:
281e6c1d
JM
153 recurse_op[0] = true;
154 break;
155 case COMPOUND_EXPR:
156 recurse_op[1] = true;
157 break;
158 case COND_EXPR:
159 recurse_op[2] = true;
160 if (TREE_OPERAND (expr, 1))
161 recurse_op[1] = true;
162 break;
163 case INDIRECT_REF:
164 if (REFERENCE_REF_P (expr))
165 {
166 /* Try to look through the reference. */
167 tree ref = TREE_OPERAND (expr, 0);
68ad1bf7 168 if (rvalue_p && is_normal_capture_proxy (ref))
c1051bf7
JM
169 {
170 /* Look through capture by reference. */
171 tree cap = DECL_CAPTURED_VARIABLE (ref);
9f613f06 172 if (!TYPE_REF_P (TREE_TYPE (cap))
c1051bf7 173 && decl_constant_var_p (cap))
1577f10a
JM
174 {
175 tree val = RECUR (cap);
176 if (!is_capture_proxy (val))
177 {
178 tree l = current_lambda_expr ();
179 LAMBDA_EXPR_CAPTURE_OPTIMIZED (l) = true;
180 }
181 return val;
182 }
c1051bf7 183 }
281e6c1d
JM
184 tree r = mark_rvalue_use (ref, loc, reject_builtin);
185 if (r != ref)
84dd815f 186 expr = convert_from_reference (r);
281e6c1d
JM
187 }
188 break;
94aedc1c
JM
189
190 CASE_CONVERT:
191 case VIEW_CONVERT_EXPR:
57ea03ad 192 if (location_wrapper_p (expr))
94aedc1c
JM
193 loc = EXPR_LOCATION (expr);
194 recurse_op[0] = true;
195 break;
196
197 default:
281e6c1d
JM
198 break;
199 }
200
281e6c1d
JM
201 for (int i = 0; i < 3; ++i)
202 if (recurse_op[i])
203 {
204 tree op = TREE_OPERAND (expr, i);
84dd815f
JM
205 op = RECUR (op);
206 if (op == error_mark_node)
207 return error_mark_node;
208 TREE_OPERAND (expr, i) = op;
281e6c1d
JM
209 }
210
281e6c1d
JM
211 return expr;
212#undef RECUR
213}
214
1807ffc1
MS
215/* Called whenever the expression EXPR is used in an rvalue context.
216 When REJECT_BUILTIN is true the expression is checked to make sure
217 it doesn't make it possible to obtain the address of a GCC built-in
218 function with no library fallback (or any of its bits, such as in
219 a conversion to bool). */
281e6c1d 220
03a904b5 221tree
281e6c1d 222mark_rvalue_use (tree e,
1807ffc1
MS
223 location_t loc /* = UNKNOWN_LOCATION */,
224 bool reject_builtin /* = true */)
03a904b5 225{
281e6c1d 226 return mark_use (e, true, true, loc, reject_builtin);
03a904b5
JJ
227}
228
b8461915
NS
229/* Called whenever an expression is used in an lvalue context. */
230
231tree
232mark_lvalue_use (tree expr)
233{
234 return mark_use (expr, false, true, input_location, false);
235}
236
237/* As above, but don't consider this use a read. */
238
239tree
240mark_lvalue_use_nonread (tree expr)
241{
242 return mark_use (expr, false, false, input_location, false);
243}
244
84dd815f
JM
245/* Called when expr appears as a discarded-value expression. */
246
247tree
248mark_discarded_use (tree expr)
249{
250 /* The lvalue-to-rvalue conversion (7.1) is applied if and only if the
251 expression is a glvalue of volatile-qualified type and it is one of the
252 following:
253 * ( expression ), where expression is one of these expressions,
254 * id-expression (8.1.4),
255 * subscripting (8.2.1),
256 * class member access (8.2.5),
257 * indirection (8.3.1),
258 * pointer-to-member operation (8.5),
259 * conditional expression (8.16) where both the second and the third
260 operands are one of these expressions, or
261 * comma expression (8.19) where the right operand is one of these
262 expressions. */
263 if (expr == NULL_TREE)
264 return expr;
265
dfd7fdca
DM
266 STRIP_ANY_LOCATION_WRAPPER (expr);
267
84dd815f
JM
268 switch (TREE_CODE (expr))
269 {
270 case COND_EXPR:
271 TREE_OPERAND (expr, 2) = mark_discarded_use (TREE_OPERAND (expr, 2));
272 gcc_fallthrough ();
273 case COMPOUND_EXPR:
274 TREE_OPERAND (expr, 1) = mark_discarded_use (TREE_OPERAND (expr, 1));
275 return expr;
276
277 case COMPONENT_REF:
278 case ARRAY_REF:
279 case INDIRECT_REF:
280 case MEMBER_REF:
281 break;
282 default:
283 if (DECL_P (expr))
284 break;
285 else
286 return expr;
287 }
288
289 /* Like mark_rvalue_use, but don't reject built-ins. */
290 return mark_use (expr, true, true, input_location, false);
291}
292
03a904b5
JJ
293/* Called whenever an expression is used in a type use context. */
294
295tree
296mark_type_use (tree expr)
297{
298 mark_exp_read (expr);
299 return expr;
300}
301
302/* Mark EXP as read, not just set, for set but not used -Wunused
303 warning purposes. */
304
305void
306mark_exp_read (tree exp)
307{
308 if (exp == NULL)
309 return;
310
311 switch (TREE_CODE (exp))
312 {
313 case VAR_DECL:
6fc9f7aa
JJ
314 if (DECL_DECOMPOSITION_P (exp))
315 mark_exp_read (DECL_DECOMP_BASE (exp));
5726acd7 316 gcc_fallthrough ();
03a904b5
JJ
317 case PARM_DECL:
318 DECL_READ_P (exp) = 1;
319 break;
320 case ARRAY_REF:
321 case COMPONENT_REF:
322 case MODIFY_EXPR:
323 case REALPART_EXPR:
324 case IMAGPART_EXPR:
325 CASE_CONVERT:
326 case ADDR_EXPR:
d84686d1 327 case INDIRECT_REF:
759deff3 328 case FLOAT_EXPR:
76f39440 329 case NON_DEPENDENT_EXPR:
f17a223d 330 case VIEW_CONVERT_EXPR:
03a904b5
JJ
331 mark_exp_read (TREE_OPERAND (exp, 0));
332 break;
333 case COMPOUND_EXPR:
334 mark_exp_read (TREE_OPERAND (exp, 1));
335 break;
336 case COND_EXPR:
337 if (TREE_OPERAND (exp, 1))
338 mark_exp_read (TREE_OPERAND (exp, 1));
339 if (TREE_OPERAND (exp, 2))
340 mark_exp_read (TREE_OPERAND (exp, 2));
341 break;
342 default:
343 break;
344 }
345}
346
bb9869d5
DM
347/* Fold X for consideration by one of the warning functions when checking
348 whether an expression has a constant value. */
349
350tree
351fold_for_warn (tree x)
352{
353 /* C++ implementation. */
354
355 /* It's not generally safe to fully fold inside of a template, so
356 call fold_non_dependent_expr instead. */
357 if (processing_template_decl)
e56f6629
JM
358 {
359 tree f = fold_non_dependent_expr (x, tf_none);
360 if (f == error_mark_node)
361 return x;
362 else
363 return f;
364 }
bb9869d5
DM
365
366 return c_fully_fold (x, /*for_init*/false, /*maybe_constp*/NULL);
367}