annotate gcc/cp/cvt.c @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 84e7813d76e9
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /* Language-level data type conversion for GNU C++.
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2 Copyright (C) 1987-2020 Free Software Foundation, Inc.
111
kono
parents:
diff changeset
3 Hacked by Michael Tiemann (tiemann@cygnus.com)
kono
parents:
diff changeset
4
kono
parents:
diff changeset
5 This file is part of GCC.
kono
parents:
diff changeset
6
kono
parents:
diff changeset
7 GCC is free software; you can redistribute it and/or modify
kono
parents:
diff changeset
8 it under the terms of the GNU General Public License as published by
kono
parents:
diff changeset
9 the Free Software Foundation; either version 3, or (at your option)
kono
parents:
diff changeset
10 any later version.
kono
parents:
diff changeset
11
kono
parents:
diff changeset
12 GCC is distributed in the hope that it will be useful,
kono
parents:
diff changeset
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
kono
parents:
diff changeset
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
kono
parents:
diff changeset
15 GNU General Public License for more details.
kono
parents:
diff changeset
16
kono
parents:
diff changeset
17 You should have received a copy of the GNU General Public License
kono
parents:
diff changeset
18 along with GCC; see the file COPYING3. If not see
kono
parents:
diff changeset
19 <http://www.gnu.org/licenses/>. */
kono
parents:
diff changeset
20
kono
parents:
diff changeset
21
kono
parents:
diff changeset
22 /* This file contains the functions for converting C++ expressions
kono
parents:
diff changeset
23 to different data types. The only entry point is `convert'.
kono
parents:
diff changeset
24 Every language front end must have a `convert' function
kono
parents:
diff changeset
25 but what kind of conversions it does will depend on the language. */
kono
parents:
diff changeset
26
kono
parents:
diff changeset
27 #include "config.h"
kono
parents:
diff changeset
28 #include "system.h"
kono
parents:
diff changeset
29 #include "coretypes.h"
kono
parents:
diff changeset
30 #include "target.h"
kono
parents:
diff changeset
31 #include "cp-tree.h"
kono
parents:
diff changeset
32 #include "stor-layout.h"
kono
parents:
diff changeset
33 #include "flags.h"
kono
parents:
diff changeset
34 #include "intl.h"
kono
parents:
diff changeset
35 #include "convert.h"
kono
parents:
diff changeset
36 #include "stringpool.h"
kono
parents:
diff changeset
37 #include "attribs.h"
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
38 #include "escaped_string.h"
111
kono
parents:
diff changeset
39
kono
parents:
diff changeset
40 static tree convert_to_pointer_force (tree, tree, tsubst_flags_t);
kono
parents:
diff changeset
41 static tree build_type_conversion (tree, tree);
kono
parents:
diff changeset
42 static tree build_up_reference (tree, tree, int, tree, tsubst_flags_t);
kono
parents:
diff changeset
43 static void diagnose_ref_binding (location_t, tree, tree, tree);
kono
parents:
diff changeset
44
kono
parents:
diff changeset
45 /* Change of width--truncation and extension of integers or reals--
kono
parents:
diff changeset
46 is represented with NOP_EXPR. Proper functioning of many things
kono
parents:
diff changeset
47 assumes that no other conversions can be NOP_EXPRs.
kono
parents:
diff changeset
48
kono
parents:
diff changeset
49 Conversion between integer and pointer is represented with CONVERT_EXPR.
kono
parents:
diff changeset
50 Converting integer to real uses FLOAT_EXPR
kono
parents:
diff changeset
51 and real to integer uses FIX_TRUNC_EXPR.
kono
parents:
diff changeset
52
kono
parents:
diff changeset
53 Here is a list of all the functions that assume that widening and
kono
parents:
diff changeset
54 narrowing is always done with a NOP_EXPR:
kono
parents:
diff changeset
55 In convert.c, convert_to_integer[_maybe_fold].
kono
parents:
diff changeset
56 In c-typeck.c, build_binary_op_nodefault (boolean ops),
kono
parents:
diff changeset
57 and c_common_truthvalue_conversion.
kono
parents:
diff changeset
58 In expr.c: expand_expr, for operands of a MULT_EXPR.
kono
parents:
diff changeset
59 In fold-const.c: fold.
kono
parents:
diff changeset
60 In tree.c: get_narrower and get_unwidened.
kono
parents:
diff changeset
61
kono
parents:
diff changeset
62 C++: in multiple-inheritance, converting between pointers may involve
kono
parents:
diff changeset
63 adjusting them by a delta stored within the class definition. */
kono
parents:
diff changeset
64
kono
parents:
diff changeset
65 /* Subroutines of `convert'. */
kono
parents:
diff changeset
66
kono
parents:
diff changeset
67 /* if converting pointer to pointer
kono
parents:
diff changeset
68 if dealing with classes, check for derived->base or vice versa
kono
parents:
diff changeset
69 else if dealing with method pointers, delegate
kono
parents:
diff changeset
70 else convert blindly
kono
parents:
diff changeset
71 else if converting class, pass off to build_type_conversion
kono
parents:
diff changeset
72 else try C-style pointer conversion. */
kono
parents:
diff changeset
73
kono
parents:
diff changeset
74 static tree
kono
parents:
diff changeset
75 cp_convert_to_pointer (tree type, tree expr, bool dofold,
kono
parents:
diff changeset
76 tsubst_flags_t complain)
kono
parents:
diff changeset
77 {
kono
parents:
diff changeset
78 tree intype = TREE_TYPE (expr);
kono
parents:
diff changeset
79 enum tree_code form;
kono
parents:
diff changeset
80 tree rval;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
81 location_t loc = cp_expr_loc_or_input_loc (expr);
111
kono
parents:
diff changeset
82
kono
parents:
diff changeset
83 if (intype == error_mark_node)
kono
parents:
diff changeset
84 return error_mark_node;
kono
parents:
diff changeset
85
kono
parents:
diff changeset
86 if (MAYBE_CLASS_TYPE_P (intype))
kono
parents:
diff changeset
87 {
kono
parents:
diff changeset
88 intype = complete_type (intype);
kono
parents:
diff changeset
89 if (!COMPLETE_TYPE_P (intype))
kono
parents:
diff changeset
90 {
kono
parents:
diff changeset
91 if (complain & tf_error)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
92 error_at (loc, "cannot convert from incomplete type %qH to %qI",
111
kono
parents:
diff changeset
93 intype, type);
kono
parents:
diff changeset
94 return error_mark_node;
kono
parents:
diff changeset
95 }
kono
parents:
diff changeset
96
kono
parents:
diff changeset
97 rval = build_type_conversion (type, expr);
kono
parents:
diff changeset
98 if (rval)
kono
parents:
diff changeset
99 {
kono
parents:
diff changeset
100 if ((complain & tf_error)
kono
parents:
diff changeset
101 && rval == error_mark_node)
kono
parents:
diff changeset
102 error_at (loc, "conversion of %qE from %qH to %qI is ambiguous",
kono
parents:
diff changeset
103 expr, intype, type);
kono
parents:
diff changeset
104 return rval;
kono
parents:
diff changeset
105 }
kono
parents:
diff changeset
106 }
kono
parents:
diff changeset
107
kono
parents:
diff changeset
108 /* Handle anachronistic conversions from (::*)() to cv void* or (*)(). */
kono
parents:
diff changeset
109 if (TYPE_PTR_P (type)
kono
parents:
diff changeset
110 && (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE
kono
parents:
diff changeset
111 || VOID_TYPE_P (TREE_TYPE (type))))
kono
parents:
diff changeset
112 {
kono
parents:
diff changeset
113 if (TYPE_PTRMEMFUNC_P (intype)
kono
parents:
diff changeset
114 || TREE_CODE (intype) == METHOD_TYPE)
kono
parents:
diff changeset
115 return convert_member_func_to_ptr (type, expr, complain);
kono
parents:
diff changeset
116 if (TYPE_PTR_P (TREE_TYPE (expr)))
kono
parents:
diff changeset
117 return build_nop (type, expr);
kono
parents:
diff changeset
118 intype = TREE_TYPE (expr);
kono
parents:
diff changeset
119 }
kono
parents:
diff changeset
120
kono
parents:
diff changeset
121 if (expr == error_mark_node)
kono
parents:
diff changeset
122 return error_mark_node;
kono
parents:
diff changeset
123
kono
parents:
diff changeset
124 form = TREE_CODE (intype);
kono
parents:
diff changeset
125
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
126 if (INDIRECT_TYPE_P (intype))
111
kono
parents:
diff changeset
127 {
kono
parents:
diff changeset
128 intype = TYPE_MAIN_VARIANT (intype);
kono
parents:
diff changeset
129
kono
parents:
diff changeset
130 if (TYPE_MAIN_VARIANT (type) != intype
kono
parents:
diff changeset
131 && TYPE_PTR_P (type)
kono
parents:
diff changeset
132 && TREE_CODE (TREE_TYPE (type)) == RECORD_TYPE
kono
parents:
diff changeset
133 && MAYBE_CLASS_TYPE_P (TREE_TYPE (type))
kono
parents:
diff changeset
134 && MAYBE_CLASS_TYPE_P (TREE_TYPE (intype))
kono
parents:
diff changeset
135 && TREE_CODE (TREE_TYPE (intype)) == RECORD_TYPE)
kono
parents:
diff changeset
136 {
kono
parents:
diff changeset
137 enum tree_code code = PLUS_EXPR;
kono
parents:
diff changeset
138 tree binfo;
kono
parents:
diff changeset
139 tree intype_class;
kono
parents:
diff changeset
140 tree type_class;
kono
parents:
diff changeset
141 bool same_p;
kono
parents:
diff changeset
142
kono
parents:
diff changeset
143 intype_class = TREE_TYPE (intype);
kono
parents:
diff changeset
144 type_class = TREE_TYPE (type);
kono
parents:
diff changeset
145
kono
parents:
diff changeset
146 same_p = same_type_p (TYPE_MAIN_VARIANT (intype_class),
kono
parents:
diff changeset
147 TYPE_MAIN_VARIANT (type_class));
kono
parents:
diff changeset
148 binfo = NULL_TREE;
kono
parents:
diff changeset
149 /* Try derived to base conversion. */
kono
parents:
diff changeset
150 if (!same_p)
kono
parents:
diff changeset
151 binfo = lookup_base (intype_class, type_class, ba_check,
kono
parents:
diff changeset
152 NULL, complain);
kono
parents:
diff changeset
153 if (!same_p && !binfo)
kono
parents:
diff changeset
154 {
kono
parents:
diff changeset
155 /* Try base to derived conversion. */
kono
parents:
diff changeset
156 binfo = lookup_base (type_class, intype_class, ba_check,
kono
parents:
diff changeset
157 NULL, complain);
kono
parents:
diff changeset
158 code = MINUS_EXPR;
kono
parents:
diff changeset
159 }
kono
parents:
diff changeset
160 if (binfo == error_mark_node)
kono
parents:
diff changeset
161 return error_mark_node;
kono
parents:
diff changeset
162 if (binfo || same_p)
kono
parents:
diff changeset
163 {
kono
parents:
diff changeset
164 if (binfo)
kono
parents:
diff changeset
165 expr = build_base_path (code, expr, binfo, 0, complain);
kono
parents:
diff changeset
166 /* Add any qualifier conversions. */
kono
parents:
diff changeset
167 return build_nop (type, expr);
kono
parents:
diff changeset
168 }
kono
parents:
diff changeset
169 }
kono
parents:
diff changeset
170
kono
parents:
diff changeset
171 if (TYPE_PTRMEMFUNC_P (type))
kono
parents:
diff changeset
172 {
kono
parents:
diff changeset
173 if (complain & tf_error)
kono
parents:
diff changeset
174 error_at (loc, "cannot convert %qE from type %qH to type %qI",
kono
parents:
diff changeset
175 expr, intype, type);
kono
parents:
diff changeset
176 return error_mark_node;
kono
parents:
diff changeset
177 }
kono
parents:
diff changeset
178
kono
parents:
diff changeset
179 return build_nop (type, expr);
kono
parents:
diff changeset
180 }
kono
parents:
diff changeset
181 else if ((TYPE_PTRDATAMEM_P (type) && TYPE_PTRDATAMEM_P (intype))
kono
parents:
diff changeset
182 || (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype)))
kono
parents:
diff changeset
183 return convert_ptrmem (type, expr, /*allow_inverse_p=*/false,
kono
parents:
diff changeset
184 /*c_cast_p=*/false, complain);
kono
parents:
diff changeset
185 else if (TYPE_PTRMEMFUNC_P (intype))
kono
parents:
diff changeset
186 {
kono
parents:
diff changeset
187 if (!warn_pmf2ptr)
kono
parents:
diff changeset
188 {
kono
parents:
diff changeset
189 if (TREE_CODE (expr) == PTRMEM_CST)
kono
parents:
diff changeset
190 return cp_convert_to_pointer (type, PTRMEM_CST_MEMBER (expr),
kono
parents:
diff changeset
191 dofold, complain);
kono
parents:
diff changeset
192 else if (TREE_CODE (expr) == OFFSET_REF)
kono
parents:
diff changeset
193 {
kono
parents:
diff changeset
194 tree object = TREE_OPERAND (expr, 0);
kono
parents:
diff changeset
195 return get_member_function_from_ptrfunc (&object,
kono
parents:
diff changeset
196 TREE_OPERAND (expr, 1),
kono
parents:
diff changeset
197 complain);
kono
parents:
diff changeset
198 }
kono
parents:
diff changeset
199 }
kono
parents:
diff changeset
200 if (complain & tf_error)
kono
parents:
diff changeset
201 error_at (loc, "cannot convert %qE from type %qH to type %qI",
kono
parents:
diff changeset
202 expr, intype, type);
kono
parents:
diff changeset
203 return error_mark_node;
kono
parents:
diff changeset
204 }
kono
parents:
diff changeset
205
kono
parents:
diff changeset
206 if (null_ptr_cst_p (expr))
kono
parents:
diff changeset
207 {
kono
parents:
diff changeset
208 if (TYPE_PTRMEMFUNC_P (type))
kono
parents:
diff changeset
209 return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr, 0,
kono
parents:
diff changeset
210 /*c_cast_p=*/false, complain);
kono
parents:
diff changeset
211
kono
parents:
diff changeset
212 if (complain & tf_warning)
kono
parents:
diff changeset
213 maybe_warn_zero_as_null_pointer_constant (expr, loc);
kono
parents:
diff changeset
214
kono
parents:
diff changeset
215 /* A NULL pointer-to-data-member is represented by -1, not by
kono
parents:
diff changeset
216 zero. */
kono
parents:
diff changeset
217 tree val = (TYPE_PTRDATAMEM_P (type)
kono
parents:
diff changeset
218 ? build_int_cst_type (type, -1)
kono
parents:
diff changeset
219 : build_int_cst (type, 0));
kono
parents:
diff changeset
220
kono
parents:
diff changeset
221 return (TREE_SIDE_EFFECTS (expr)
kono
parents:
diff changeset
222 ? build2 (COMPOUND_EXPR, type, expr, val) : val);
kono
parents:
diff changeset
223 }
kono
parents:
diff changeset
224 else if (TYPE_PTRMEM_P (type) && INTEGRAL_CODE_P (form))
kono
parents:
diff changeset
225 {
kono
parents:
diff changeset
226 if (complain & tf_error)
kono
parents:
diff changeset
227 error_at (loc, "invalid conversion from %qH to %qI", intype, type);
kono
parents:
diff changeset
228 return error_mark_node;
kono
parents:
diff changeset
229 }
kono
parents:
diff changeset
230
kono
parents:
diff changeset
231 if (INTEGRAL_CODE_P (form))
kono
parents:
diff changeset
232 {
kono
parents:
diff changeset
233 if (TYPE_PRECISION (intype) == POINTER_SIZE)
kono
parents:
diff changeset
234 return build1 (CONVERT_EXPR, type, expr);
kono
parents:
diff changeset
235 expr = cp_convert (c_common_type_for_size (POINTER_SIZE, 0), expr,
kono
parents:
diff changeset
236 complain);
kono
parents:
diff changeset
237 /* Modes may be different but sizes should be the same. There
kono
parents:
diff changeset
238 is supposed to be some integral type that is the same width
kono
parents:
diff changeset
239 as a pointer. */
kono
parents:
diff changeset
240 gcc_assert (GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (TREE_TYPE (expr)))
kono
parents:
diff changeset
241 == GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (type)));
kono
parents:
diff changeset
242
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
243 /* FIXME needed because convert_to_pointer_maybe_fold still folds
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
244 conversion of constants. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
245 if (!dofold)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
246 return build1 (CONVERT_EXPR, type, expr);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
247
111
kono
parents:
diff changeset
248 return convert_to_pointer_maybe_fold (type, expr, dofold);
kono
parents:
diff changeset
249 }
kono
parents:
diff changeset
250
kono
parents:
diff changeset
251 if (type_unknown_p (expr))
kono
parents:
diff changeset
252 return instantiate_type (type, expr, complain);
kono
parents:
diff changeset
253
kono
parents:
diff changeset
254 if (complain & tf_error)
kono
parents:
diff changeset
255 error_at (loc, "cannot convert %qE from type %qH to type %qI",
kono
parents:
diff changeset
256 expr, intype, type);
kono
parents:
diff changeset
257 return error_mark_node;
kono
parents:
diff changeset
258 }
kono
parents:
diff changeset
259
kono
parents:
diff changeset
260 /* Like convert, except permit conversions to take place which
kono
parents:
diff changeset
261 are not normally allowed due to access restrictions
kono
parents:
diff changeset
262 (such as conversion from sub-type to private super-type). */
kono
parents:
diff changeset
263
kono
parents:
diff changeset
264 static tree
kono
parents:
diff changeset
265 convert_to_pointer_force (tree type, tree expr, tsubst_flags_t complain)
kono
parents:
diff changeset
266 {
kono
parents:
diff changeset
267 tree intype = TREE_TYPE (expr);
kono
parents:
diff changeset
268 enum tree_code form = TREE_CODE (intype);
kono
parents:
diff changeset
269
kono
parents:
diff changeset
270 if (form == POINTER_TYPE)
kono
parents:
diff changeset
271 {
kono
parents:
diff changeset
272 intype = TYPE_MAIN_VARIANT (intype);
kono
parents:
diff changeset
273
kono
parents:
diff changeset
274 if (TYPE_MAIN_VARIANT (type) != intype
kono
parents:
diff changeset
275 && TREE_CODE (TREE_TYPE (type)) == RECORD_TYPE
kono
parents:
diff changeset
276 && MAYBE_CLASS_TYPE_P (TREE_TYPE (type))
kono
parents:
diff changeset
277 && MAYBE_CLASS_TYPE_P (TREE_TYPE (intype))
kono
parents:
diff changeset
278 && TREE_CODE (TREE_TYPE (intype)) == RECORD_TYPE)
kono
parents:
diff changeset
279 {
kono
parents:
diff changeset
280 enum tree_code code = PLUS_EXPR;
kono
parents:
diff changeset
281 tree binfo;
kono
parents:
diff changeset
282
kono
parents:
diff changeset
283 binfo = lookup_base (TREE_TYPE (intype), TREE_TYPE (type),
kono
parents:
diff changeset
284 ba_unique, NULL, complain);
kono
parents:
diff changeset
285 if (!binfo)
kono
parents:
diff changeset
286 {
kono
parents:
diff changeset
287 binfo = lookup_base (TREE_TYPE (type), TREE_TYPE (intype),
kono
parents:
diff changeset
288 ba_unique, NULL, complain);
kono
parents:
diff changeset
289 code = MINUS_EXPR;
kono
parents:
diff changeset
290 }
kono
parents:
diff changeset
291 if (binfo == error_mark_node)
kono
parents:
diff changeset
292 return error_mark_node;
kono
parents:
diff changeset
293 if (binfo)
kono
parents:
diff changeset
294 {
kono
parents:
diff changeset
295 expr = build_base_path (code, expr, binfo, 0, complain);
kono
parents:
diff changeset
296 if (expr == error_mark_node)
kono
parents:
diff changeset
297 return error_mark_node;
kono
parents:
diff changeset
298 /* Add any qualifier conversions. */
kono
parents:
diff changeset
299 if (!same_type_p (TREE_TYPE (TREE_TYPE (expr)),
kono
parents:
diff changeset
300 TREE_TYPE (type)))
kono
parents:
diff changeset
301 expr = build_nop (type, expr);
kono
parents:
diff changeset
302 return expr;
kono
parents:
diff changeset
303 }
kono
parents:
diff changeset
304 }
kono
parents:
diff changeset
305 }
kono
parents:
diff changeset
306
kono
parents:
diff changeset
307 return cp_convert_to_pointer (type, expr, /*fold*/false, complain);
kono
parents:
diff changeset
308 }
kono
parents:
diff changeset
309
kono
parents:
diff changeset
310 /* We are passing something to a function which requires a reference.
kono
parents:
diff changeset
311 The type we are interested in is in TYPE. The initial
kono
parents:
diff changeset
312 value we have to begin with is in ARG.
kono
parents:
diff changeset
313
kono
parents:
diff changeset
314 FLAGS controls how we manage access checking.
kono
parents:
diff changeset
315 DIRECT_BIND in FLAGS controls how any temporaries are generated.
kono
parents:
diff changeset
316 If DIRECT_BIND is set, DECL is the reference we're binding to. */
kono
parents:
diff changeset
317
kono
parents:
diff changeset
318 static tree
kono
parents:
diff changeset
319 build_up_reference (tree type, tree arg, int flags, tree decl,
kono
parents:
diff changeset
320 tsubst_flags_t complain)
kono
parents:
diff changeset
321 {
kono
parents:
diff changeset
322 tree rval;
kono
parents:
diff changeset
323 tree argtype = TREE_TYPE (arg);
kono
parents:
diff changeset
324 tree target_type = TREE_TYPE (type);
kono
parents:
diff changeset
325
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
326 gcc_assert (TYPE_REF_P (type));
111
kono
parents:
diff changeset
327
kono
parents:
diff changeset
328 if ((flags & DIRECT_BIND) && ! lvalue_p (arg))
kono
parents:
diff changeset
329 {
kono
parents:
diff changeset
330 /* Create a new temporary variable. We can't just use a TARGET_EXPR
kono
parents:
diff changeset
331 here because it needs to live as long as DECL. */
kono
parents:
diff changeset
332 tree targ = arg;
kono
parents:
diff changeset
333
kono
parents:
diff changeset
334 arg = make_temporary_var_for_ref_to_temp (decl, target_type);
kono
parents:
diff changeset
335
kono
parents:
diff changeset
336 /* Process the initializer for the declaration. */
kono
parents:
diff changeset
337 DECL_INITIAL (arg) = targ;
kono
parents:
diff changeset
338 cp_finish_decl (arg, targ, /*init_const_expr_p=*/false, NULL_TREE,
kono
parents:
diff changeset
339 LOOKUP_ONLYCONVERTING|DIRECT_BIND);
kono
parents:
diff changeset
340 }
kono
parents:
diff changeset
341 else if (!(flags & DIRECT_BIND) && ! obvalue_p (arg))
kono
parents:
diff changeset
342 return get_target_expr_sfinae (arg, complain);
kono
parents:
diff changeset
343
kono
parents:
diff changeset
344 /* If we had a way to wrap this up, and say, if we ever needed its
kono
parents:
diff changeset
345 address, transform all occurrences of the register, into a memory
kono
parents:
diff changeset
346 reference we could win better. */
kono
parents:
diff changeset
347 rval = cp_build_addr_expr (arg, complain);
kono
parents:
diff changeset
348 if (rval == error_mark_node)
kono
parents:
diff changeset
349 return error_mark_node;
kono
parents:
diff changeset
350
kono
parents:
diff changeset
351 if ((flags & LOOKUP_PROTECT)
kono
parents:
diff changeset
352 && TYPE_MAIN_VARIANT (argtype) != TYPE_MAIN_VARIANT (target_type)
kono
parents:
diff changeset
353 && MAYBE_CLASS_TYPE_P (argtype)
kono
parents:
diff changeset
354 && MAYBE_CLASS_TYPE_P (target_type))
kono
parents:
diff changeset
355 {
kono
parents:
diff changeset
356 /* We go through lookup_base for the access control. */
kono
parents:
diff changeset
357 tree binfo = lookup_base (argtype, target_type, ba_check,
kono
parents:
diff changeset
358 NULL, complain);
kono
parents:
diff changeset
359 if (binfo == error_mark_node)
kono
parents:
diff changeset
360 return error_mark_node;
kono
parents:
diff changeset
361 if (binfo == NULL_TREE)
kono
parents:
diff changeset
362 return error_not_base_type (target_type, argtype);
kono
parents:
diff changeset
363 rval = build_base_path (PLUS_EXPR, rval, binfo, 1, complain);
kono
parents:
diff changeset
364 }
kono
parents:
diff changeset
365 else
kono
parents:
diff changeset
366 rval
kono
parents:
diff changeset
367 = convert_to_pointer_force (build_pointer_type (target_type),
kono
parents:
diff changeset
368 rval, complain);
kono
parents:
diff changeset
369 return build_nop (type, rval);
kono
parents:
diff changeset
370 }
kono
parents:
diff changeset
371
kono
parents:
diff changeset
372 /* Subroutine of convert_to_reference. REFTYPE is the target reference type.
kono
parents:
diff changeset
373 INTYPE is the original rvalue type and DECL is an optional _DECL node
kono
parents:
diff changeset
374 for diagnostics.
kono
parents:
diff changeset
375
kono
parents:
diff changeset
376 [dcl.init.ref] says that if an rvalue is used to
kono
parents:
diff changeset
377 initialize a reference, then the reference must be to a
kono
parents:
diff changeset
378 non-volatile const type. */
kono
parents:
diff changeset
379
kono
parents:
diff changeset
380 static void
kono
parents:
diff changeset
381 diagnose_ref_binding (location_t loc, tree reftype, tree intype, tree decl)
kono
parents:
diff changeset
382 {
kono
parents:
diff changeset
383 tree ttl = TREE_TYPE (reftype);
kono
parents:
diff changeset
384
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
385 if (!TYPE_REF_IS_RVALUE (reftype)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
386 && !CP_TYPE_CONST_NON_VOLATILE_P (ttl))
111
kono
parents:
diff changeset
387 {
kono
parents:
diff changeset
388 const char *msg;
kono
parents:
diff changeset
389
kono
parents:
diff changeset
390 if (CP_TYPE_VOLATILE_P (ttl) && decl)
kono
parents:
diff changeset
391 msg = G_("initialization of volatile reference type %q#T from "
kono
parents:
diff changeset
392 "rvalue of type %qT");
kono
parents:
diff changeset
393 else if (CP_TYPE_VOLATILE_P (ttl))
kono
parents:
diff changeset
394 msg = G_("conversion to volatile reference type %q#T "
kono
parents:
diff changeset
395 "from rvalue of type %qT");
kono
parents:
diff changeset
396 else if (decl)
kono
parents:
diff changeset
397 msg = G_("initialization of non-const reference type %q#T from "
kono
parents:
diff changeset
398 "rvalue of type %qT");
kono
parents:
diff changeset
399 else
kono
parents:
diff changeset
400 msg = G_("conversion to non-const reference type %q#T from "
kono
parents:
diff changeset
401 "rvalue of type %qT");
kono
parents:
diff changeset
402
kono
parents:
diff changeset
403 permerror (loc, msg, reftype, intype);
kono
parents:
diff changeset
404 }
kono
parents:
diff changeset
405 }
kono
parents:
diff changeset
406
kono
parents:
diff changeset
407 /* For C++: Only need to do one-level references, but cannot
kono
parents:
diff changeset
408 get tripped up on signed/unsigned differences.
kono
parents:
diff changeset
409
kono
parents:
diff changeset
410 DECL is either NULL_TREE or the _DECL node for a reference that is being
kono
parents:
diff changeset
411 initialized. It can be error_mark_node if we don't know the _DECL but
kono
parents:
diff changeset
412 we know it's an initialization. */
kono
parents:
diff changeset
413
kono
parents:
diff changeset
414 tree
kono
parents:
diff changeset
415 convert_to_reference (tree reftype, tree expr, int convtype,
kono
parents:
diff changeset
416 int flags, tree decl, tsubst_flags_t complain)
kono
parents:
diff changeset
417 {
kono
parents:
diff changeset
418 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (reftype));
kono
parents:
diff changeset
419 tree intype;
kono
parents:
diff changeset
420 tree rval = NULL_TREE;
kono
parents:
diff changeset
421 tree rval_as_conversion = NULL_TREE;
kono
parents:
diff changeset
422 bool can_convert_intype_to_type;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
423 location_t loc = cp_expr_loc_or_input_loc (expr);
111
kono
parents:
diff changeset
424
kono
parents:
diff changeset
425 if (TREE_CODE (type) == FUNCTION_TYPE
kono
parents:
diff changeset
426 && TREE_TYPE (expr) == unknown_type_node)
kono
parents:
diff changeset
427 expr = instantiate_type (type, expr, complain);
kono
parents:
diff changeset
428
kono
parents:
diff changeset
429 if (expr == error_mark_node)
kono
parents:
diff changeset
430 return error_mark_node;
kono
parents:
diff changeset
431
kono
parents:
diff changeset
432 intype = TREE_TYPE (expr);
kono
parents:
diff changeset
433
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
434 gcc_assert (!TYPE_REF_P (intype));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
435 gcc_assert (TYPE_REF_P (reftype));
111
kono
parents:
diff changeset
436
kono
parents:
diff changeset
437 intype = TYPE_MAIN_VARIANT (intype);
kono
parents:
diff changeset
438
kono
parents:
diff changeset
439 can_convert_intype_to_type = can_convert_standard (type, intype, complain);
kono
parents:
diff changeset
440
kono
parents:
diff changeset
441 if (!can_convert_intype_to_type
kono
parents:
diff changeset
442 && (convtype & CONV_IMPLICIT) && MAYBE_CLASS_TYPE_P (intype)
kono
parents:
diff changeset
443 && ! (flags & LOOKUP_NO_CONVERSION))
kono
parents:
diff changeset
444 {
kono
parents:
diff changeset
445 /* Look for a user-defined conversion to lvalue that we can use. */
kono
parents:
diff changeset
446
kono
parents:
diff changeset
447 rval_as_conversion
kono
parents:
diff changeset
448 = build_type_conversion (reftype, expr);
kono
parents:
diff changeset
449
kono
parents:
diff changeset
450 if (rval_as_conversion && rval_as_conversion != error_mark_node
kono
parents:
diff changeset
451 && lvalue_p (rval_as_conversion))
kono
parents:
diff changeset
452 {
kono
parents:
diff changeset
453 expr = rval_as_conversion;
kono
parents:
diff changeset
454 rval_as_conversion = NULL_TREE;
kono
parents:
diff changeset
455 intype = type;
kono
parents:
diff changeset
456 can_convert_intype_to_type = 1;
kono
parents:
diff changeset
457 }
kono
parents:
diff changeset
458 }
kono
parents:
diff changeset
459
kono
parents:
diff changeset
460 if (((convtype & CONV_STATIC)
kono
parents:
diff changeset
461 && can_convert_standard (intype, type, complain))
kono
parents:
diff changeset
462 || ((convtype & CONV_IMPLICIT) && can_convert_intype_to_type))
kono
parents:
diff changeset
463 {
kono
parents:
diff changeset
464 {
kono
parents:
diff changeset
465 tree ttl = TREE_TYPE (reftype);
kono
parents:
diff changeset
466 tree ttr = lvalue_type (expr);
kono
parents:
diff changeset
467
kono
parents:
diff changeset
468 if ((complain & tf_error)
kono
parents:
diff changeset
469 && ! lvalue_p (expr))
kono
parents:
diff changeset
470 diagnose_ref_binding (loc, reftype, intype, decl);
kono
parents:
diff changeset
471
kono
parents:
diff changeset
472 if (! (convtype & CONV_CONST)
kono
parents:
diff changeset
473 && !at_least_as_qualified_p (ttl, ttr))
kono
parents:
diff changeset
474 {
kono
parents:
diff changeset
475 if (complain & tf_error)
kono
parents:
diff changeset
476 permerror (loc, "conversion from %qH to %qI discards qualifiers",
kono
parents:
diff changeset
477 ttr, reftype);
kono
parents:
diff changeset
478 else
kono
parents:
diff changeset
479 return error_mark_node;
kono
parents:
diff changeset
480 }
kono
parents:
diff changeset
481 }
kono
parents:
diff changeset
482
kono
parents:
diff changeset
483 return build_up_reference (reftype, expr, flags, decl, complain);
kono
parents:
diff changeset
484 }
kono
parents:
diff changeset
485 else if ((convtype & CONV_REINTERPRET) && obvalue_p (expr))
kono
parents:
diff changeset
486 {
kono
parents:
diff changeset
487 /* When casting an lvalue to a reference type, just convert into
kono
parents:
diff changeset
488 a pointer to the new type and deference it. This is allowed
kono
parents:
diff changeset
489 by San Diego WP section 5.2.9 paragraph 12, though perhaps it
kono
parents:
diff changeset
490 should be done directly (jason). (int &)ri ---> *(int*)&ri */
kono
parents:
diff changeset
491
kono
parents:
diff changeset
492 /* B* bp; A& ar = (A&)bp; is valid, but it's probably not what they
kono
parents:
diff changeset
493 meant. */
kono
parents:
diff changeset
494 if ((complain & tf_warning)
kono
parents:
diff changeset
495 && TYPE_PTR_P (intype)
kono
parents:
diff changeset
496 && (comptypes (TREE_TYPE (intype), type,
kono
parents:
diff changeset
497 COMPARE_BASE | COMPARE_DERIVED)))
kono
parents:
diff changeset
498 warning_at (loc, 0, "casting %qT to %qT does not dereference pointer",
kono
parents:
diff changeset
499 intype, reftype);
kono
parents:
diff changeset
500
kono
parents:
diff changeset
501 rval = cp_build_addr_expr (expr, complain);
kono
parents:
diff changeset
502 if (rval != error_mark_node)
kono
parents:
diff changeset
503 rval = convert_force (build_pointer_type (TREE_TYPE (reftype)),
kono
parents:
diff changeset
504 rval, 0, complain);
kono
parents:
diff changeset
505 if (rval != error_mark_node)
kono
parents:
diff changeset
506 rval = build1 (NOP_EXPR, reftype, rval);
kono
parents:
diff changeset
507 }
kono
parents:
diff changeset
508 else
kono
parents:
diff changeset
509 {
kono
parents:
diff changeset
510 rval = convert_for_initialization (NULL_TREE, type, expr, flags,
kono
parents:
diff changeset
511 ICR_CONVERTING, 0, 0, complain);
kono
parents:
diff changeset
512 if (rval == NULL_TREE || rval == error_mark_node)
kono
parents:
diff changeset
513 return rval;
kono
parents:
diff changeset
514 if (complain & tf_error)
kono
parents:
diff changeset
515 diagnose_ref_binding (loc, reftype, intype, decl);
kono
parents:
diff changeset
516 rval = build_up_reference (reftype, rval, flags, decl, complain);
kono
parents:
diff changeset
517 }
kono
parents:
diff changeset
518
kono
parents:
diff changeset
519 if (rval)
kono
parents:
diff changeset
520 {
kono
parents:
diff changeset
521 /* If we found a way to convert earlier, then use it. */
kono
parents:
diff changeset
522 return rval;
kono
parents:
diff changeset
523 }
kono
parents:
diff changeset
524
kono
parents:
diff changeset
525 if (complain & tf_error)
kono
parents:
diff changeset
526 error_at (loc, "cannot convert type %qH to type %qI", intype, reftype);
kono
parents:
diff changeset
527
kono
parents:
diff changeset
528 return error_mark_node;
kono
parents:
diff changeset
529 }
kono
parents:
diff changeset
530
kono
parents:
diff changeset
531 /* We are using a reference VAL for its value. Bash that reference all the
kono
parents:
diff changeset
532 way down to its lowest form. */
kono
parents:
diff changeset
533
kono
parents:
diff changeset
534 tree
kono
parents:
diff changeset
535 convert_from_reference (tree val)
kono
parents:
diff changeset
536 {
kono
parents:
diff changeset
537 if (TREE_TYPE (val)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
538 && TYPE_REF_P (TREE_TYPE (val)))
111
kono
parents:
diff changeset
539 {
kono
parents:
diff changeset
540 tree t = TREE_TYPE (TREE_TYPE (val));
kono
parents:
diff changeset
541 tree ref = build1 (INDIRECT_REF, t, val);
kono
parents:
diff changeset
542
kono
parents:
diff changeset
543 mark_exp_read (val);
kono
parents:
diff changeset
544 /* We *must* set TREE_READONLY when dereferencing a pointer to const,
kono
parents:
diff changeset
545 so that we get the proper error message if the result is used
kono
parents:
diff changeset
546 to assign to. Also, &* is supposed to be a no-op. */
kono
parents:
diff changeset
547 TREE_READONLY (ref) = CP_TYPE_CONST_P (t);
kono
parents:
diff changeset
548 TREE_THIS_VOLATILE (ref) = CP_TYPE_VOLATILE_P (t);
kono
parents:
diff changeset
549 TREE_SIDE_EFFECTS (ref)
kono
parents:
diff changeset
550 = (TREE_THIS_VOLATILE (ref) || TREE_SIDE_EFFECTS (val));
kono
parents:
diff changeset
551 val = ref;
kono
parents:
diff changeset
552 }
kono
parents:
diff changeset
553
kono
parents:
diff changeset
554 return val;
kono
parents:
diff changeset
555 }
kono
parents:
diff changeset
556
kono
parents:
diff changeset
557 /* Really perform an lvalue-to-rvalue conversion, including copying an
kono
parents:
diff changeset
558 argument of class type into a temporary. */
kono
parents:
diff changeset
559
kono
parents:
diff changeset
560 tree
kono
parents:
diff changeset
561 force_rvalue (tree expr, tsubst_flags_t complain)
kono
parents:
diff changeset
562 {
kono
parents:
diff changeset
563 tree type = TREE_TYPE (expr);
kono
parents:
diff changeset
564 if (MAYBE_CLASS_TYPE_P (type) && TREE_CODE (expr) != TARGET_EXPR)
kono
parents:
diff changeset
565 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
566 releasing_vec args (make_tree_vector_single (expr));
111
kono
parents:
diff changeset
567 expr = build_special_member_call (NULL_TREE, complete_ctor_identifier,
kono
parents:
diff changeset
568 &args, type, LOOKUP_NORMAL, complain);
kono
parents:
diff changeset
569 expr = build_cplus_new (type, expr, complain);
kono
parents:
diff changeset
570 }
kono
parents:
diff changeset
571 else
kono
parents:
diff changeset
572 expr = decay_conversion (expr, complain);
kono
parents:
diff changeset
573
kono
parents:
diff changeset
574 return expr;
kono
parents:
diff changeset
575 }
kono
parents:
diff changeset
576
kono
parents:
diff changeset
577
kono
parents:
diff changeset
578 /* If EXPR and ORIG are INTEGER_CSTs, return a version of EXPR that has
kono
parents:
diff changeset
579 TREE_OVERFLOW set only if it is set in ORIG. Otherwise, return EXPR
kono
parents:
diff changeset
580 unchanged. */
kono
parents:
diff changeset
581
kono
parents:
diff changeset
582 static tree
kono
parents:
diff changeset
583 ignore_overflows (tree expr, tree orig)
kono
parents:
diff changeset
584 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
585 tree stripped_expr = tree_strip_any_location_wrapper (expr);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
586 tree stripped_orig = tree_strip_any_location_wrapper (orig);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
587
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
588 if (TREE_CODE (stripped_expr) == INTEGER_CST
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
589 && TREE_CODE (stripped_orig) == INTEGER_CST
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
590 && TREE_OVERFLOW (stripped_expr) != TREE_OVERFLOW (stripped_orig))
111
kono
parents:
diff changeset
591 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
592 gcc_assert (!TREE_OVERFLOW (stripped_orig));
111
kono
parents:
diff changeset
593 /* Ensure constant sharing. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
594 stripped_expr = wide_int_to_tree (TREE_TYPE (stripped_expr),
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
595 wi::to_wide (stripped_expr));
111
kono
parents:
diff changeset
596 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
597
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
598 return preserve_any_location_wrapper (stripped_expr, expr);
111
kono
parents:
diff changeset
599 }
kono
parents:
diff changeset
600
kono
parents:
diff changeset
601 /* Fold away simple conversions, but make sure TREE_OVERFLOW is set
kono
parents:
diff changeset
602 properly. */
kono
parents:
diff changeset
603
kono
parents:
diff changeset
604 tree
kono
parents:
diff changeset
605 cp_fold_convert (tree type, tree expr)
kono
parents:
diff changeset
606 {
kono
parents:
diff changeset
607 tree conv;
kono
parents:
diff changeset
608 if (TREE_TYPE (expr) == type)
kono
parents:
diff changeset
609 conv = expr;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
610 else if (TREE_CODE (expr) == PTRMEM_CST
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
611 && same_type_p (TYPE_PTRMEM_CLASS_TYPE (type),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
612 PTRMEM_CST_CLASS (expr)))
111
kono
parents:
diff changeset
613 {
kono
parents:
diff changeset
614 /* Avoid wrapping a PTRMEM_CST in NOP_EXPR. */
kono
parents:
diff changeset
615 conv = copy_node (expr);
kono
parents:
diff changeset
616 TREE_TYPE (conv) = type;
kono
parents:
diff changeset
617 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
618 else if (TYPE_PTRMEM_P (type))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
619 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
620 conv = convert_ptrmem (type, expr, true, false,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
621 tf_warning_or_error);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
622 conv = cp_fully_fold (conv);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
623 }
111
kono
parents:
diff changeset
624 else
kono
parents:
diff changeset
625 {
kono
parents:
diff changeset
626 conv = fold_convert (type, expr);
kono
parents:
diff changeset
627 conv = ignore_overflows (conv, expr);
kono
parents:
diff changeset
628 }
kono
parents:
diff changeset
629 return conv;
kono
parents:
diff changeset
630 }
kono
parents:
diff changeset
631
kono
parents:
diff changeset
632 /* C++ conversions, preference to static cast conversions. */
kono
parents:
diff changeset
633
kono
parents:
diff changeset
634 tree
kono
parents:
diff changeset
635 cp_convert (tree type, tree expr, tsubst_flags_t complain)
kono
parents:
diff changeset
636 {
kono
parents:
diff changeset
637 return ocp_convert (type, expr, CONV_OLD_CONVERT, LOOKUP_NORMAL, complain);
kono
parents:
diff changeset
638 }
kono
parents:
diff changeset
639
kono
parents:
diff changeset
640 /* C++ equivalent of convert_and_check but using cp_convert as the
kono
parents:
diff changeset
641 conversion function.
kono
parents:
diff changeset
642
kono
parents:
diff changeset
643 Convert EXPR to TYPE, warning about conversion problems with constants.
kono
parents:
diff changeset
644 Invoke this function on every expression that is converted implicitly,
kono
parents:
diff changeset
645 i.e. because of language rules and not because of an explicit cast. */
kono
parents:
diff changeset
646
kono
parents:
diff changeset
647 tree
kono
parents:
diff changeset
648 cp_convert_and_check (tree type, tree expr, tsubst_flags_t complain)
kono
parents:
diff changeset
649 {
kono
parents:
diff changeset
650 tree result;
kono
parents:
diff changeset
651
kono
parents:
diff changeset
652 if (TREE_TYPE (expr) == type)
kono
parents:
diff changeset
653 return expr;
kono
parents:
diff changeset
654 if (expr == error_mark_node)
kono
parents:
diff changeset
655 return expr;
kono
parents:
diff changeset
656 result = cp_convert (type, expr, complain);
kono
parents:
diff changeset
657
kono
parents:
diff changeset
658 if ((complain & tf_warning)
kono
parents:
diff changeset
659 && c_inhibit_evaluation_warnings == 0)
kono
parents:
diff changeset
660 {
kono
parents:
diff changeset
661 tree folded = cp_fully_fold (expr);
kono
parents:
diff changeset
662 tree folded_result;
kono
parents:
diff changeset
663 if (folded == expr)
kono
parents:
diff changeset
664 folded_result = result;
kono
parents:
diff changeset
665 else
kono
parents:
diff changeset
666 {
kono
parents:
diff changeset
667 /* Avoid bogus -Wparentheses warnings. */
kono
parents:
diff changeset
668 warning_sentinel w (warn_parentheses);
kono
parents:
diff changeset
669 warning_sentinel c (warn_int_in_bool_context);
kono
parents:
diff changeset
670 folded_result = cp_convert (type, folded, tf_none);
kono
parents:
diff changeset
671 }
kono
parents:
diff changeset
672 folded_result = fold_simple (folded_result);
kono
parents:
diff changeset
673 if (!TREE_OVERFLOW_P (folded)
kono
parents:
diff changeset
674 && folded_result != error_mark_node)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
675 warnings_for_convert_and_check (cp_expr_loc_or_input_loc (expr),
111
kono
parents:
diff changeset
676 type, folded, folded_result);
kono
parents:
diff changeset
677 }
kono
parents:
diff changeset
678
kono
parents:
diff changeset
679 return result;
kono
parents:
diff changeset
680 }
kono
parents:
diff changeset
681
kono
parents:
diff changeset
682 /* Conversion...
kono
parents:
diff changeset
683
kono
parents:
diff changeset
684 FLAGS indicates how we should behave. */
kono
parents:
diff changeset
685
kono
parents:
diff changeset
686 tree
kono
parents:
diff changeset
687 ocp_convert (tree type, tree expr, int convtype, int flags,
kono
parents:
diff changeset
688 tsubst_flags_t complain)
kono
parents:
diff changeset
689 {
kono
parents:
diff changeset
690 tree e = expr;
kono
parents:
diff changeset
691 enum tree_code code = TREE_CODE (type);
kono
parents:
diff changeset
692 const char *invalid_conv_diag;
kono
parents:
diff changeset
693 tree e1;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
694 location_t loc = cp_expr_loc_or_input_loc (expr);
111
kono
parents:
diff changeset
695 bool dofold = (convtype & CONV_FOLD);
kono
parents:
diff changeset
696
kono
parents:
diff changeset
697 if (error_operand_p (e) || type == error_mark_node)
kono
parents:
diff changeset
698 return error_mark_node;
kono
parents:
diff changeset
699
kono
parents:
diff changeset
700 complete_type (type);
kono
parents:
diff changeset
701 complete_type (TREE_TYPE (expr));
kono
parents:
diff changeset
702
kono
parents:
diff changeset
703 if ((invalid_conv_diag
kono
parents:
diff changeset
704 = targetm.invalid_conversion (TREE_TYPE (expr), type)))
kono
parents:
diff changeset
705 {
kono
parents:
diff changeset
706 if (complain & tf_error)
kono
parents:
diff changeset
707 error (invalid_conv_diag);
kono
parents:
diff changeset
708 return error_mark_node;
kono
parents:
diff changeset
709 }
kono
parents:
diff changeset
710
kono
parents:
diff changeset
711 /* FIXME remove when moving to c_fully_fold model. */
kono
parents:
diff changeset
712 if (!CLASS_TYPE_P (type))
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
713 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
714 e = mark_rvalue_use (e);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
715 e = scalar_constant_value (e);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
716 }
111
kono
parents:
diff changeset
717 if (error_operand_p (e))
kono
parents:
diff changeset
718 return error_mark_node;
kono
parents:
diff changeset
719
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
720 if (NULLPTR_TYPE_P (type) && null_ptr_cst_p (e))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
721 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
722 if (complain & tf_warning)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
723 maybe_warn_zero_as_null_pointer_constant (e, loc);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
724
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
725 if (!TREE_SIDE_EFFECTS (e))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
726 return nullptr_node;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
727 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
728
111
kono
parents:
diff changeset
729 if (MAYBE_CLASS_TYPE_P (type) && (convtype & CONV_FORCE_TEMP))
kono
parents:
diff changeset
730 /* We need a new temporary; don't take this shortcut. */;
kono
parents:
diff changeset
731 else if (same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (e)))
kono
parents:
diff changeset
732 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
733 tree etype = TREE_TYPE (e);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
734 if (same_type_p (type, etype))
111
kono
parents:
diff changeset
735 /* The call to fold will not always remove the NOP_EXPR as
kono
parents:
diff changeset
736 might be expected, since if one of the types is a typedef;
kono
parents:
diff changeset
737 the comparison in fold is just equality of pointers, not a
kono
parents:
diff changeset
738 call to comptypes. We don't call fold in this case because
kono
parents:
diff changeset
739 that can result in infinite recursion; fold will call
kono
parents:
diff changeset
740 convert, which will call ocp_convert, etc. */
kono
parents:
diff changeset
741 return e;
kono
parents:
diff changeset
742 /* For complex data types, we need to perform componentwise
kono
parents:
diff changeset
743 conversion. */
kono
parents:
diff changeset
744 else if (TREE_CODE (type) == COMPLEX_TYPE)
kono
parents:
diff changeset
745 return convert_to_complex_maybe_fold (type, e, dofold);
kono
parents:
diff changeset
746 else if (VECTOR_TYPE_P (type))
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
747 return convert_to_vector (type, rvalue (e));
111
kono
parents:
diff changeset
748 else if (TREE_CODE (e) == TARGET_EXPR)
kono
parents:
diff changeset
749 {
kono
parents:
diff changeset
750 /* Don't build a NOP_EXPR of class type. Instead, change the
kono
parents:
diff changeset
751 type of the temporary. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
752 gcc_assert (same_type_ignoring_top_level_qualifiers_p (type, etype));
111
kono
parents:
diff changeset
753 TREE_TYPE (e) = TREE_TYPE (TARGET_EXPR_SLOT (e)) = type;
kono
parents:
diff changeset
754 return e;
kono
parents:
diff changeset
755 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
756 else if (TREE_CODE (e) == CONSTRUCTOR)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
757 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
758 gcc_assert (same_type_ignoring_top_level_qualifiers_p (type, etype));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
759 TREE_TYPE (e) = type;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
760 return e;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
761 }
111
kono
parents:
diff changeset
762 else
kono
parents:
diff changeset
763 {
kono
parents:
diff changeset
764 /* We shouldn't be treating objects of ADDRESSABLE type as
kono
parents:
diff changeset
765 rvalues. */
kono
parents:
diff changeset
766 gcc_assert (!TREE_ADDRESSABLE (type));
kono
parents:
diff changeset
767 return build_nop (type, e);
kono
parents:
diff changeset
768 }
kono
parents:
diff changeset
769 }
kono
parents:
diff changeset
770
kono
parents:
diff changeset
771 e1 = targetm.convert_to_type (type, e);
kono
parents:
diff changeset
772 if (e1)
kono
parents:
diff changeset
773 return e1;
kono
parents:
diff changeset
774
kono
parents:
diff changeset
775 if (code == VOID_TYPE && (convtype & CONV_STATIC))
kono
parents:
diff changeset
776 {
kono
parents:
diff changeset
777 e = convert_to_void (e, ICV_CAST, complain);
kono
parents:
diff changeset
778 return e;
kono
parents:
diff changeset
779 }
kono
parents:
diff changeset
780
kono
parents:
diff changeset
781 if (INTEGRAL_CODE_P (code))
kono
parents:
diff changeset
782 {
kono
parents:
diff changeset
783 tree intype = TREE_TYPE (e);
kono
parents:
diff changeset
784 tree converted;
kono
parents:
diff changeset
785
kono
parents:
diff changeset
786 if (TREE_CODE (type) == ENUMERAL_TYPE)
kono
parents:
diff changeset
787 {
kono
parents:
diff changeset
788 /* enum = enum, enum = int, enum = float, (enum)pointer are all
kono
parents:
diff changeset
789 errors. */
kono
parents:
diff changeset
790 if (((INTEGRAL_OR_ENUMERATION_TYPE_P (intype)
kono
parents:
diff changeset
791 || TREE_CODE (intype) == REAL_TYPE)
kono
parents:
diff changeset
792 && ! (convtype & CONV_STATIC))
kono
parents:
diff changeset
793 || TYPE_PTR_P (intype))
kono
parents:
diff changeset
794 {
kono
parents:
diff changeset
795 if (complain & tf_error)
kono
parents:
diff changeset
796 permerror (loc, "conversion from %q#T to %q#T", intype, type);
kono
parents:
diff changeset
797 else
kono
parents:
diff changeset
798 return error_mark_node;
kono
parents:
diff changeset
799 }
kono
parents:
diff changeset
800
kono
parents:
diff changeset
801 /* [expr.static.cast]
kono
parents:
diff changeset
802
kono
parents:
diff changeset
803 8. A value of integral or enumeration type can be explicitly
kono
parents:
diff changeset
804 converted to an enumeration type. The value is unchanged if
kono
parents:
diff changeset
805 the original value is within the range of the enumeration
kono
parents:
diff changeset
806 values. Otherwise, the resulting enumeration value is
kono
parents:
diff changeset
807 unspecified. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
808 tree val = fold_for_warn (e);
111
kono
parents:
diff changeset
809 if ((complain & tf_warning)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
810 && TREE_CODE (val) == INTEGER_CST
111
kono
parents:
diff changeset
811 && ENUM_UNDERLYING_TYPE (type)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
812 && !int_fits_type_p (val, ENUM_UNDERLYING_TYPE (type)))
111
kono
parents:
diff changeset
813 warning_at (loc, OPT_Wconversion,
kono
parents:
diff changeset
814 "the result of the conversion is unspecified because "
kono
parents:
diff changeset
815 "%qE is outside the range of type %qT",
kono
parents:
diff changeset
816 expr, type);
kono
parents:
diff changeset
817 }
kono
parents:
diff changeset
818 if (MAYBE_CLASS_TYPE_P (intype))
kono
parents:
diff changeset
819 {
kono
parents:
diff changeset
820 tree rval;
kono
parents:
diff changeset
821 rval = build_type_conversion (type, e);
kono
parents:
diff changeset
822 if (rval)
kono
parents:
diff changeset
823 return rval;
kono
parents:
diff changeset
824 if (complain & tf_error)
kono
parents:
diff changeset
825 error_at (loc, "%q#T used where a %qT was expected", intype, type);
kono
parents:
diff changeset
826 return error_mark_node;
kono
parents:
diff changeset
827 }
kono
parents:
diff changeset
828 if (code == BOOLEAN_TYPE)
kono
parents:
diff changeset
829 {
kono
parents:
diff changeset
830 if (VOID_TYPE_P (intype))
kono
parents:
diff changeset
831 {
kono
parents:
diff changeset
832 if (complain & tf_error)
kono
parents:
diff changeset
833 error_at (loc,
kono
parents:
diff changeset
834 "could not convert %qE from %<void%> to %<bool%>",
kono
parents:
diff changeset
835 expr);
kono
parents:
diff changeset
836 return error_mark_node;
kono
parents:
diff changeset
837 }
kono
parents:
diff changeset
838
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
839 if (VECTOR_TYPE_P (intype) && !gnu_vector_type_p (intype))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
840 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
841 if (complain & tf_error)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
842 error_at (loc, "could not convert %qE from %qH to %qI", expr,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
843 TREE_TYPE (expr), type);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
844 return error_mark_node;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
845 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
846
111
kono
parents:
diff changeset
847 /* We can't implicitly convert a scoped enum to bool, so convert
kono
parents:
diff changeset
848 to the underlying type first. */
kono
parents:
diff changeset
849 if (SCOPED_ENUM_P (intype) && (convtype & CONV_STATIC))
kono
parents:
diff changeset
850 e = build_nop (ENUM_UNDERLYING_TYPE (intype), e);
kono
parents:
diff changeset
851 if (complain & tf_warning)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
852 return cp_truthvalue_conversion (e, complain);
111
kono
parents:
diff changeset
853 else
kono
parents:
diff changeset
854 {
kono
parents:
diff changeset
855 /* Prevent bogus -Wint-in-bool-context warnings coming
kono
parents:
diff changeset
856 from c_common_truthvalue_conversion down the line. */
kono
parents:
diff changeset
857 warning_sentinel w (warn_int_in_bool_context);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
858 warning_sentinel c (warn_sign_compare);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
859 return cp_truthvalue_conversion (e, complain);
111
kono
parents:
diff changeset
860 }
kono
parents:
diff changeset
861 }
kono
parents:
diff changeset
862
kono
parents:
diff changeset
863 converted = convert_to_integer_maybe_fold (type, e, dofold);
kono
parents:
diff changeset
864
kono
parents:
diff changeset
865 /* Ignore any integer overflow caused by the conversion. */
kono
parents:
diff changeset
866 return ignore_overflows (converted, e);
kono
parents:
diff changeset
867 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
868 if (INDIRECT_TYPE_P (type) || TYPE_PTRMEM_P (type))
111
kono
parents:
diff changeset
869 return cp_convert_to_pointer (type, e, dofold, complain);
kono
parents:
diff changeset
870 if (code == VECTOR_TYPE)
kono
parents:
diff changeset
871 {
kono
parents:
diff changeset
872 tree in_vtype = TREE_TYPE (e);
kono
parents:
diff changeset
873 if (MAYBE_CLASS_TYPE_P (in_vtype))
kono
parents:
diff changeset
874 {
kono
parents:
diff changeset
875 tree ret_val;
kono
parents:
diff changeset
876 ret_val = build_type_conversion (type, e);
kono
parents:
diff changeset
877 if (ret_val)
kono
parents:
diff changeset
878 return ret_val;
kono
parents:
diff changeset
879 if (complain & tf_error)
kono
parents:
diff changeset
880 error_at (loc, "%q#T used where a %qT was expected",
kono
parents:
diff changeset
881 in_vtype, type);
kono
parents:
diff changeset
882 return error_mark_node;
kono
parents:
diff changeset
883 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
884 return convert_to_vector (type, rvalue (e));
111
kono
parents:
diff changeset
885 }
kono
parents:
diff changeset
886 if (code == REAL_TYPE || code == COMPLEX_TYPE)
kono
parents:
diff changeset
887 {
kono
parents:
diff changeset
888 if (MAYBE_CLASS_TYPE_P (TREE_TYPE (e)))
kono
parents:
diff changeset
889 {
kono
parents:
diff changeset
890 tree rval;
kono
parents:
diff changeset
891 rval = build_type_conversion (type, e);
kono
parents:
diff changeset
892 if (rval)
kono
parents:
diff changeset
893 return rval;
kono
parents:
diff changeset
894 else if (complain & tf_error)
kono
parents:
diff changeset
895 error_at (loc,
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
896 "%q#T used where a floating-point value was expected",
111
kono
parents:
diff changeset
897 TREE_TYPE (e));
kono
parents:
diff changeset
898 }
kono
parents:
diff changeset
899 if (code == REAL_TYPE)
kono
parents:
diff changeset
900 return convert_to_real_maybe_fold (type, e, dofold);
kono
parents:
diff changeset
901 else if (code == COMPLEX_TYPE)
kono
parents:
diff changeset
902 return convert_to_complex_maybe_fold (type, e, dofold);
kono
parents:
diff changeset
903 }
kono
parents:
diff changeset
904
kono
parents:
diff changeset
905 /* New C++ semantics: since assignment is now based on
kono
parents:
diff changeset
906 memberwise copying, if the rhs type is derived from the
kono
parents:
diff changeset
907 lhs type, then we may still do a conversion. */
kono
parents:
diff changeset
908 if (RECORD_OR_UNION_CODE_P (code))
kono
parents:
diff changeset
909 {
kono
parents:
diff changeset
910 tree dtype = TREE_TYPE (e);
kono
parents:
diff changeset
911 tree ctor = NULL_TREE;
kono
parents:
diff changeset
912
kono
parents:
diff changeset
913 dtype = TYPE_MAIN_VARIANT (dtype);
kono
parents:
diff changeset
914
kono
parents:
diff changeset
915 /* Conversion between aggregate types. New C++ semantics allow
kono
parents:
diff changeset
916 objects of derived type to be cast to objects of base type.
kono
parents:
diff changeset
917 Old semantics only allowed this between pointers.
kono
parents:
diff changeset
918
kono
parents:
diff changeset
919 There may be some ambiguity between using a constructor
kono
parents:
diff changeset
920 vs. using a type conversion operator when both apply. */
kono
parents:
diff changeset
921
kono
parents:
diff changeset
922 ctor = e;
kono
parents:
diff changeset
923
kono
parents:
diff changeset
924 if (abstract_virtuals_error_sfinae (NULL_TREE, type, complain))
kono
parents:
diff changeset
925 return error_mark_node;
kono
parents:
diff changeset
926
kono
parents:
diff changeset
927 if (BRACE_ENCLOSED_INITIALIZER_P (ctor))
kono
parents:
diff changeset
928 ctor = perform_implicit_conversion (type, ctor, complain);
kono
parents:
diff changeset
929 else if ((flags & LOOKUP_ONLYCONVERTING)
kono
parents:
diff changeset
930 && ! (CLASS_TYPE_P (dtype) && DERIVED_FROM_P (type, dtype)))
kono
parents:
diff changeset
931 /* For copy-initialization, first we create a temp of the proper type
kono
parents:
diff changeset
932 with a user-defined conversion sequence, then we direct-initialize
kono
parents:
diff changeset
933 the target with the temp (see [dcl.init]). */
kono
parents:
diff changeset
934 ctor = build_user_type_conversion (type, ctor, flags, complain);
kono
parents:
diff changeset
935 else
kono
parents:
diff changeset
936 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
937 releasing_vec ctor_vec (make_tree_vector_single (ctor));
111
kono
parents:
diff changeset
938 ctor = build_special_member_call (NULL_TREE,
kono
parents:
diff changeset
939 complete_ctor_identifier,
kono
parents:
diff changeset
940 &ctor_vec,
kono
parents:
diff changeset
941 type, flags, complain);
kono
parents:
diff changeset
942 }
kono
parents:
diff changeset
943 if (ctor)
kono
parents:
diff changeset
944 return build_cplus_new (type, ctor, complain);
kono
parents:
diff changeset
945 }
kono
parents:
diff changeset
946
kono
parents:
diff changeset
947 if (complain & tf_error)
kono
parents:
diff changeset
948 {
kono
parents:
diff changeset
949 /* If the conversion failed and expr was an invalid use of pointer to
kono
parents:
diff changeset
950 member function, try to report a meaningful error. */
kono
parents:
diff changeset
951 if (invalid_nonstatic_memfn_p (loc, expr, complain))
kono
parents:
diff changeset
952 /* We displayed the error message. */;
kono
parents:
diff changeset
953 else
kono
parents:
diff changeset
954 error_at (loc, "conversion from %qH to non-scalar type %qI requested",
kono
parents:
diff changeset
955 TREE_TYPE (expr), type);
kono
parents:
diff changeset
956 }
kono
parents:
diff changeset
957 return error_mark_node;
kono
parents:
diff changeset
958 }
kono
parents:
diff changeset
959
kono
parents:
diff changeset
960 /* If CALL is a call, return the callee; otherwise null. */
kono
parents:
diff changeset
961
kono
parents:
diff changeset
962 tree
kono
parents:
diff changeset
963 cp_get_callee (tree call)
kono
parents:
diff changeset
964 {
kono
parents:
diff changeset
965 if (call == NULL_TREE)
kono
parents:
diff changeset
966 return call;
kono
parents:
diff changeset
967 else if (TREE_CODE (call) == CALL_EXPR)
kono
parents:
diff changeset
968 return CALL_EXPR_FN (call);
kono
parents:
diff changeset
969 else if (TREE_CODE (call) == AGGR_INIT_EXPR)
kono
parents:
diff changeset
970 return AGGR_INIT_EXPR_FN (call);
kono
parents:
diff changeset
971 return NULL_TREE;
kono
parents:
diff changeset
972 }
kono
parents:
diff changeset
973
kono
parents:
diff changeset
974 /* FN is the callee of a CALL_EXPR or AGGR_INIT_EXPR; return the FUNCTION_DECL
kono
parents:
diff changeset
975 if we can. */
kono
parents:
diff changeset
976
kono
parents:
diff changeset
977 tree
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
978 cp_get_fndecl_from_callee (tree fn, bool fold /* = true */)
111
kono
parents:
diff changeset
979 {
kono
parents:
diff changeset
980 if (fn == NULL_TREE)
kono
parents:
diff changeset
981 return fn;
kono
parents:
diff changeset
982 if (TREE_CODE (fn) == FUNCTION_DECL)
kono
parents:
diff changeset
983 return fn;
kono
parents:
diff changeset
984 tree type = TREE_TYPE (fn);
kono
parents:
diff changeset
985 if (type == unknown_type_node)
kono
parents:
diff changeset
986 return NULL_TREE;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
987 gcc_assert (INDIRECT_TYPE_P (type));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
988 if (fold)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
989 fn = maybe_constant_init (fn);
111
kono
parents:
diff changeset
990 STRIP_NOPS (fn);
kono
parents:
diff changeset
991 if (TREE_CODE (fn) == ADDR_EXPR)
kono
parents:
diff changeset
992 {
kono
parents:
diff changeset
993 fn = TREE_OPERAND (fn, 0);
kono
parents:
diff changeset
994 if (TREE_CODE (fn) == FUNCTION_DECL)
kono
parents:
diff changeset
995 return fn;
kono
parents:
diff changeset
996 }
kono
parents:
diff changeset
997 return NULL_TREE;
kono
parents:
diff changeset
998 }
kono
parents:
diff changeset
999
kono
parents:
diff changeset
1000 /* Like get_callee_fndecl, but handles AGGR_INIT_EXPR as well and uses the
kono
parents:
diff changeset
1001 constexpr machinery. */
kono
parents:
diff changeset
1002
kono
parents:
diff changeset
1003 tree
kono
parents:
diff changeset
1004 cp_get_callee_fndecl (tree call)
kono
parents:
diff changeset
1005 {
kono
parents:
diff changeset
1006 return cp_get_fndecl_from_callee (cp_get_callee (call));
kono
parents:
diff changeset
1007 }
kono
parents:
diff changeset
1008
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1009 /* As above, but not using the constexpr machinery. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1010
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1011 tree
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1012 cp_get_callee_fndecl_nofold (tree call)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1013 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1014 return cp_get_fndecl_from_callee (cp_get_callee (call), false);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1015 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1016
111
kono
parents:
diff changeset
1017 /* Subroutine of convert_to_void. Warn if we're discarding something with
kono
parents:
diff changeset
1018 attribute [[nodiscard]]. */
kono
parents:
diff changeset
1019
kono
parents:
diff changeset
1020 static void
kono
parents:
diff changeset
1021 maybe_warn_nodiscard (tree expr, impl_conv_void implicit)
kono
parents:
diff changeset
1022 {
kono
parents:
diff changeset
1023 tree call = expr;
kono
parents:
diff changeset
1024 if (TREE_CODE (expr) == TARGET_EXPR)
kono
parents:
diff changeset
1025 call = TARGET_EXPR_INITIAL (expr);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1026 location_t loc = cp_expr_loc_or_input_loc (call);
111
kono
parents:
diff changeset
1027 tree callee = cp_get_callee (call);
kono
parents:
diff changeset
1028 if (!callee)
kono
parents:
diff changeset
1029 return;
kono
parents:
diff changeset
1030
kono
parents:
diff changeset
1031 tree type = TREE_TYPE (callee);
kono
parents:
diff changeset
1032 if (TYPE_PTRMEMFUNC_P (type))
kono
parents:
diff changeset
1033 type = TYPE_PTRMEMFUNC_FN_TYPE (type);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1034 if (INDIRECT_TYPE_P (type))
111
kono
parents:
diff changeset
1035 type = TREE_TYPE (type);
kono
parents:
diff changeset
1036
kono
parents:
diff changeset
1037 tree rettype = TREE_TYPE (type);
kono
parents:
diff changeset
1038 tree fn = cp_get_fndecl_from_callee (callee);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1039 tree attr;
111
kono
parents:
diff changeset
1040 if (implicit != ICV_CAST && fn
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1041 && (attr = lookup_attribute ("nodiscard", DECL_ATTRIBUTES (fn))))
111
kono
parents:
diff changeset
1042 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1043 escaped_string msg;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1044 tree args = TREE_VALUE (attr);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1045 if (args)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1046 msg.escape (TREE_STRING_POINTER (TREE_VALUE (args)));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1047 const char *format
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1048 = (msg
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1049 ? G_("ignoring return value of %qD, "
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1050 "declared with attribute %<nodiscard%>: %<%s%>")
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1051 : G_("ignoring return value of %qD, "
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1052 "declared with attribute %<nodiscard%>%s"));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1053 const char *raw_msg = msg ? (const char *) msg : "";
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1054 auto_diagnostic_group d;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1055 if (warning_at (loc, OPT_Wunused_result, format, fn, raw_msg))
111
kono
parents:
diff changeset
1056 inform (DECL_SOURCE_LOCATION (fn), "declared here");
kono
parents:
diff changeset
1057 }
kono
parents:
diff changeset
1058 else if (implicit != ICV_CAST
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1059 && (attr = lookup_attribute ("nodiscard", TYPE_ATTRIBUTES (rettype))))
111
kono
parents:
diff changeset
1060 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1061 escaped_string msg;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1062 tree args = TREE_VALUE (attr);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1063 if (args)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1064 msg.escape (TREE_STRING_POINTER (TREE_VALUE (args)));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1065 const char *format
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1066 = (msg
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1067 ? G_("ignoring returned value of type %qT, "
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1068 "declared with attribute %<nodiscard%>: %<%s%>")
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1069 : G_("ignoring returned value of type %qT, "
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1070 "declared with attribute %<nodiscard%>%s"));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1071 const char *raw_msg = msg ? (const char *) msg : "";
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1072 auto_diagnostic_group d;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1073 if (warning_at (loc, OPT_Wunused_result, format, rettype, raw_msg))
111
kono
parents:
diff changeset
1074 {
kono
parents:
diff changeset
1075 if (fn)
kono
parents:
diff changeset
1076 inform (DECL_SOURCE_LOCATION (fn),
kono
parents:
diff changeset
1077 "in call to %qD, declared here", fn);
kono
parents:
diff changeset
1078 inform (DECL_SOURCE_LOCATION (TYPE_NAME (rettype)),
kono
parents:
diff changeset
1079 "%qT declared here", rettype);
kono
parents:
diff changeset
1080 }
kono
parents:
diff changeset
1081 }
kono
parents:
diff changeset
1082 else if (TREE_CODE (expr) == TARGET_EXPR
kono
parents:
diff changeset
1083 && lookup_attribute ("warn_unused_result", TYPE_ATTRIBUTES (type)))
kono
parents:
diff changeset
1084 {
kono
parents:
diff changeset
1085 /* The TARGET_EXPR confuses do_warn_unused_result into thinking that the
kono
parents:
diff changeset
1086 result is used, so handle that case here. */
kono
parents:
diff changeset
1087 if (fn)
kono
parents:
diff changeset
1088 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1089 auto_diagnostic_group d;
111
kono
parents:
diff changeset
1090 if (warning_at (loc, OPT_Wunused_result,
kono
parents:
diff changeset
1091 "ignoring return value of %qD, "
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1092 "declared with attribute %<warn_unused_result%>",
111
kono
parents:
diff changeset
1093 fn))
kono
parents:
diff changeset
1094 inform (DECL_SOURCE_LOCATION (fn), "declared here");
kono
parents:
diff changeset
1095 }
kono
parents:
diff changeset
1096 else
kono
parents:
diff changeset
1097 warning_at (loc, OPT_Wunused_result,
kono
parents:
diff changeset
1098 "ignoring return value of function "
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1099 "declared with attribute %<warn_unused_result%>");
111
kono
parents:
diff changeset
1100 }
kono
parents:
diff changeset
1101 }
kono
parents:
diff changeset
1102
kono
parents:
diff changeset
1103 /* When an expression is used in a void context, its value is discarded and
kono
parents:
diff changeset
1104 no lvalue-rvalue and similar conversions happen [expr.static.cast/4,
kono
parents:
diff changeset
1105 stmt.expr/1, expr.comma/1]. This permits dereferencing an incomplete type
kono
parents:
diff changeset
1106 in a void context. The C++ standard does not define what an `access' to an
kono
parents:
diff changeset
1107 object is, but there is reason to believe that it is the lvalue to rvalue
kono
parents:
diff changeset
1108 conversion -- if it were not, `*&*p = 1' would violate [expr]/4 in that it
kono
parents:
diff changeset
1109 accesses `*p' not to calculate the value to be stored. But, dcl.type.cv/8
kono
parents:
diff changeset
1110 indicates that volatile semantics should be the same between C and C++
kono
parents:
diff changeset
1111 where ever possible. C leaves it implementation defined as to what
kono
parents:
diff changeset
1112 constitutes an access to a volatile. So, we interpret `*vp' as a read of
kono
parents:
diff changeset
1113 the volatile object `vp' points to, unless that is an incomplete type. For
kono
parents:
diff changeset
1114 volatile references we do not do this interpretation, because that would
kono
parents:
diff changeset
1115 make it impossible to ignore the reference return value from functions. We
kono
parents:
diff changeset
1116 issue warnings in the confusing cases.
kono
parents:
diff changeset
1117
kono
parents:
diff changeset
1118 The IMPLICIT is ICV_CAST when the user is explicitly converting an expression
kono
parents:
diff changeset
1119 to void via a cast. If an expression is being implicitly converted, IMPLICIT
kono
parents:
diff changeset
1120 indicates the context of the implicit conversion. */
kono
parents:
diff changeset
1121
kono
parents:
diff changeset
1122 tree
kono
parents:
diff changeset
1123 convert_to_void (tree expr, impl_conv_void implicit, tsubst_flags_t complain)
kono
parents:
diff changeset
1124 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1125 location_t loc = cp_expr_loc_or_input_loc (expr);
111
kono
parents:
diff changeset
1126
kono
parents:
diff changeset
1127 if (expr == error_mark_node
kono
parents:
diff changeset
1128 || TREE_TYPE (expr) == error_mark_node)
kono
parents:
diff changeset
1129 return error_mark_node;
kono
parents:
diff changeset
1130
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1131 expr = maybe_undo_parenthesized_ref (expr);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1132
111
kono
parents:
diff changeset
1133 expr = mark_discarded_use (expr);
kono
parents:
diff changeset
1134 if (implicit == ICV_CAST)
kono
parents:
diff changeset
1135 /* An explicit cast to void avoids all -Wunused-but-set* warnings. */
kono
parents:
diff changeset
1136 mark_exp_read (expr);
kono
parents:
diff changeset
1137
kono
parents:
diff changeset
1138 if (!TREE_TYPE (expr))
kono
parents:
diff changeset
1139 return expr;
kono
parents:
diff changeset
1140 if (invalid_nonstatic_memfn_p (loc, expr, complain))
kono
parents:
diff changeset
1141 return error_mark_node;
kono
parents:
diff changeset
1142 if (TREE_CODE (expr) == PSEUDO_DTOR_EXPR)
kono
parents:
diff changeset
1143 {
kono
parents:
diff changeset
1144 if (complain & tf_error)
kono
parents:
diff changeset
1145 error_at (loc, "pseudo-destructor is not called");
kono
parents:
diff changeset
1146 return error_mark_node;
kono
parents:
diff changeset
1147 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1148
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1149 /* Explicitly evaluate void-converted concept checks since their
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1150 satisfaction may produce ill-formed programs. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1151 if (concept_check_p (expr))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1152 expr = evaluate_concept_check (expr, tf_warning_or_error);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1153
111
kono
parents:
diff changeset
1154 if (VOID_TYPE_P (TREE_TYPE (expr)))
kono
parents:
diff changeset
1155 return expr;
kono
parents:
diff changeset
1156 switch (TREE_CODE (expr))
kono
parents:
diff changeset
1157 {
kono
parents:
diff changeset
1158 case COND_EXPR:
kono
parents:
diff changeset
1159 {
kono
parents:
diff changeset
1160 /* The two parts of a cond expr might be separate lvalues. */
kono
parents:
diff changeset
1161 tree op1 = TREE_OPERAND (expr,1);
kono
parents:
diff changeset
1162 tree op2 = TREE_OPERAND (expr,2);
kono
parents:
diff changeset
1163 bool side_effects = ((op1 && TREE_SIDE_EFFECTS (op1))
kono
parents:
diff changeset
1164 || TREE_SIDE_EFFECTS (op2));
kono
parents:
diff changeset
1165 tree new_op1, new_op2;
kono
parents:
diff changeset
1166 new_op1 = NULL_TREE;
kono
parents:
diff changeset
1167 if (implicit != ICV_CAST && !side_effects)
kono
parents:
diff changeset
1168 {
kono
parents:
diff changeset
1169 if (op1)
kono
parents:
diff changeset
1170 new_op1 = convert_to_void (op1, ICV_SECOND_OF_COND, complain);
kono
parents:
diff changeset
1171 new_op2 = convert_to_void (op2, ICV_THIRD_OF_COND, complain);
kono
parents:
diff changeset
1172 }
kono
parents:
diff changeset
1173 else
kono
parents:
diff changeset
1174 {
kono
parents:
diff changeset
1175 if (op1)
kono
parents:
diff changeset
1176 new_op1 = convert_to_void (op1, ICV_CAST, complain);
kono
parents:
diff changeset
1177 new_op2 = convert_to_void (op2, ICV_CAST, complain);
kono
parents:
diff changeset
1178 }
kono
parents:
diff changeset
1179
kono
parents:
diff changeset
1180 expr = build3 (COND_EXPR, TREE_TYPE (new_op2),
kono
parents:
diff changeset
1181 TREE_OPERAND (expr, 0), new_op1, new_op2);
kono
parents:
diff changeset
1182 break;
kono
parents:
diff changeset
1183 }
kono
parents:
diff changeset
1184
kono
parents:
diff changeset
1185 case COMPOUND_EXPR:
kono
parents:
diff changeset
1186 {
kono
parents:
diff changeset
1187 /* The second part of a compound expr contains the value. */
kono
parents:
diff changeset
1188 tree op1 = TREE_OPERAND (expr,1);
kono
parents:
diff changeset
1189 tree new_op1;
kono
parents:
diff changeset
1190 if (implicit != ICV_CAST && !TREE_NO_WARNING (expr))
kono
parents:
diff changeset
1191 new_op1 = convert_to_void (op1, ICV_RIGHT_OF_COMMA, complain);
kono
parents:
diff changeset
1192 else
kono
parents:
diff changeset
1193 new_op1 = convert_to_void (op1, ICV_CAST, complain);
kono
parents:
diff changeset
1194
kono
parents:
diff changeset
1195 if (new_op1 != op1)
kono
parents:
diff changeset
1196 {
kono
parents:
diff changeset
1197 tree t = build2 (COMPOUND_EXPR, TREE_TYPE (new_op1),
kono
parents:
diff changeset
1198 TREE_OPERAND (expr, 0), new_op1);
kono
parents:
diff changeset
1199 expr = t;
kono
parents:
diff changeset
1200 }
kono
parents:
diff changeset
1201
kono
parents:
diff changeset
1202 break;
kono
parents:
diff changeset
1203 }
kono
parents:
diff changeset
1204
kono
parents:
diff changeset
1205 case NON_LVALUE_EXPR:
kono
parents:
diff changeset
1206 case NOP_EXPR:
kono
parents:
diff changeset
1207 /* These have already decayed to rvalue. */
kono
parents:
diff changeset
1208 break;
kono
parents:
diff changeset
1209
kono
parents:
diff changeset
1210 case CALL_EXPR: /* We have a special meaning for volatile void fn(). */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1211 /* cdtors may return this or void, depending on
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1212 targetm.cxx.cdtor_returns_this, but this shouldn't affect our
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1213 decisions here: neither nodiscard warnings (nodiscard cdtors
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1214 are nonsensical), nor should any constexpr or template
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1215 instantiations be affected by an ABI property that is, or at
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1216 least ought to be transparent to the language. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1217 if (tree fn = cp_get_callee_fndecl_nofold (expr))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1218 if (DECL_DESTRUCTOR_P (fn))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1219 return expr;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1220
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1221 if (complain & tf_warning)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1222 maybe_warn_nodiscard (expr, implicit);
111
kono
parents:
diff changeset
1223 break;
kono
parents:
diff changeset
1224
kono
parents:
diff changeset
1225 case INDIRECT_REF:
kono
parents:
diff changeset
1226 {
kono
parents:
diff changeset
1227 tree type = TREE_TYPE (expr);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1228 int is_reference = TYPE_REF_P (TREE_TYPE (TREE_OPERAND (expr, 0)));
111
kono
parents:
diff changeset
1229 int is_volatile = TYPE_VOLATILE (type);
kono
parents:
diff changeset
1230 int is_complete = COMPLETE_TYPE_P (complete_type (type));
kono
parents:
diff changeset
1231
kono
parents:
diff changeset
1232 /* Can't load the value if we don't know the type. */
kono
parents:
diff changeset
1233 if (is_volatile && !is_complete)
kono
parents:
diff changeset
1234 {
kono
parents:
diff changeset
1235 if (complain & tf_warning)
kono
parents:
diff changeset
1236 switch (implicit)
kono
parents:
diff changeset
1237 {
kono
parents:
diff changeset
1238 case ICV_CAST:
kono
parents:
diff changeset
1239 warning_at (loc, 0, "conversion to void will not access "
kono
parents:
diff changeset
1240 "object of incomplete type %qT", type);
kono
parents:
diff changeset
1241 break;
kono
parents:
diff changeset
1242 case ICV_SECOND_OF_COND:
kono
parents:
diff changeset
1243 warning_at (loc, 0, "indirection will not access object of "
kono
parents:
diff changeset
1244 "incomplete type %qT in second operand "
kono
parents:
diff changeset
1245 "of conditional expression", type);
kono
parents:
diff changeset
1246 break;
kono
parents:
diff changeset
1247 case ICV_THIRD_OF_COND:
kono
parents:
diff changeset
1248 warning_at (loc, 0, "indirection will not access object of "
kono
parents:
diff changeset
1249 "incomplete type %qT in third operand "
kono
parents:
diff changeset
1250 "of conditional expression", type);
kono
parents:
diff changeset
1251 break;
kono
parents:
diff changeset
1252 case ICV_RIGHT_OF_COMMA:
kono
parents:
diff changeset
1253 warning_at (loc, 0, "indirection will not access object of "
kono
parents:
diff changeset
1254 "incomplete type %qT in right operand of "
kono
parents:
diff changeset
1255 "comma operator", type);
kono
parents:
diff changeset
1256 break;
kono
parents:
diff changeset
1257 case ICV_LEFT_OF_COMMA:
kono
parents:
diff changeset
1258 warning_at (loc, 0, "indirection will not access object of "
kono
parents:
diff changeset
1259 "incomplete type %qT in left operand of "
kono
parents:
diff changeset
1260 "comma operator", type);
kono
parents:
diff changeset
1261 break;
kono
parents:
diff changeset
1262 case ICV_STATEMENT:
kono
parents:
diff changeset
1263 warning_at (loc, 0, "indirection will not access object of "
kono
parents:
diff changeset
1264 "incomplete type %qT in statement", type);
kono
parents:
diff changeset
1265 break;
kono
parents:
diff changeset
1266 case ICV_THIRD_IN_FOR:
kono
parents:
diff changeset
1267 warning_at (loc, 0, "indirection will not access object of "
kono
parents:
diff changeset
1268 "incomplete type %qT in for increment "
kono
parents:
diff changeset
1269 "expression", type);
kono
parents:
diff changeset
1270 break;
kono
parents:
diff changeset
1271 default:
kono
parents:
diff changeset
1272 gcc_unreachable ();
kono
parents:
diff changeset
1273 }
kono
parents:
diff changeset
1274 }
kono
parents:
diff changeset
1275 /* Don't load the value if this is an implicit dereference, or if
kono
parents:
diff changeset
1276 the type needs to be handled by ctors/dtors. */
kono
parents:
diff changeset
1277 else if (is_volatile && is_reference)
kono
parents:
diff changeset
1278 {
kono
parents:
diff changeset
1279 if (complain & tf_warning)
kono
parents:
diff changeset
1280 switch (implicit)
kono
parents:
diff changeset
1281 {
kono
parents:
diff changeset
1282 case ICV_CAST:
kono
parents:
diff changeset
1283 warning_at (loc, 0, "conversion to void will not access "
kono
parents:
diff changeset
1284 "object of type %qT", type);
kono
parents:
diff changeset
1285 break;
kono
parents:
diff changeset
1286 case ICV_SECOND_OF_COND:
kono
parents:
diff changeset
1287 warning_at (loc, 0, "implicit dereference will not access "
kono
parents:
diff changeset
1288 "object of type %qT in second operand of "
kono
parents:
diff changeset
1289 "conditional expression", type);
kono
parents:
diff changeset
1290 break;
kono
parents:
diff changeset
1291 case ICV_THIRD_OF_COND:
kono
parents:
diff changeset
1292 warning_at (loc, 0, "implicit dereference will not access "
kono
parents:
diff changeset
1293 "object of type %qT in third operand of "
kono
parents:
diff changeset
1294 "conditional expression", type);
kono
parents:
diff changeset
1295 break;
kono
parents:
diff changeset
1296 case ICV_RIGHT_OF_COMMA:
kono
parents:
diff changeset
1297 warning_at (loc, 0, "implicit dereference will not access "
kono
parents:
diff changeset
1298 "object of type %qT in right operand of "
kono
parents:
diff changeset
1299 "comma operator", type);
kono
parents:
diff changeset
1300 break;
kono
parents:
diff changeset
1301 case ICV_LEFT_OF_COMMA:
kono
parents:
diff changeset
1302 warning_at (loc, 0, "implicit dereference will not access "
kono
parents:
diff changeset
1303 "object of type %qT in left operand of comma "
kono
parents:
diff changeset
1304 "operator", type);
kono
parents:
diff changeset
1305 break;
kono
parents:
diff changeset
1306 case ICV_STATEMENT:
kono
parents:
diff changeset
1307 warning_at (loc, 0, "implicit dereference will not access "
kono
parents:
diff changeset
1308 "object of type %qT in statement", type);
kono
parents:
diff changeset
1309 break;
kono
parents:
diff changeset
1310 case ICV_THIRD_IN_FOR:
kono
parents:
diff changeset
1311 warning_at (loc, 0, "implicit dereference will not access "
kono
parents:
diff changeset
1312 "object of type %qT in for increment expression",
kono
parents:
diff changeset
1313 type);
kono
parents:
diff changeset
1314 break;
kono
parents:
diff changeset
1315 default:
kono
parents:
diff changeset
1316 gcc_unreachable ();
kono
parents:
diff changeset
1317 }
kono
parents:
diff changeset
1318 }
kono
parents:
diff changeset
1319 else if (is_volatile && TREE_ADDRESSABLE (type))
kono
parents:
diff changeset
1320 {
kono
parents:
diff changeset
1321 if (complain & tf_warning)
kono
parents:
diff changeset
1322 switch (implicit)
kono
parents:
diff changeset
1323 {
kono
parents:
diff changeset
1324 case ICV_CAST:
kono
parents:
diff changeset
1325 warning_at (loc, 0, "conversion to void will not access "
kono
parents:
diff changeset
1326 "object of non-trivially-copyable type %qT",
kono
parents:
diff changeset
1327 type);
kono
parents:
diff changeset
1328 break;
kono
parents:
diff changeset
1329 case ICV_SECOND_OF_COND:
kono
parents:
diff changeset
1330 warning_at (loc, 0, "indirection will not access object of "
kono
parents:
diff changeset
1331 "non-trivially-copyable type %qT in second "
kono
parents:
diff changeset
1332 "operand of conditional expression", type);
kono
parents:
diff changeset
1333 break;
kono
parents:
diff changeset
1334 case ICV_THIRD_OF_COND:
kono
parents:
diff changeset
1335 warning_at (loc, 0, "indirection will not access object of "
kono
parents:
diff changeset
1336 "non-trivially-copyable type %qT in third "
kono
parents:
diff changeset
1337 "operand of conditional expression", type);
kono
parents:
diff changeset
1338 break;
kono
parents:
diff changeset
1339 case ICV_RIGHT_OF_COMMA:
kono
parents:
diff changeset
1340 warning_at (loc, 0, "indirection will not access object of "
kono
parents:
diff changeset
1341 "non-trivially-copyable type %qT in right "
kono
parents:
diff changeset
1342 "operand of comma operator", type);
kono
parents:
diff changeset
1343 break;
kono
parents:
diff changeset
1344 case ICV_LEFT_OF_COMMA:
kono
parents:
diff changeset
1345 warning_at (loc, 0, "indirection will not access object of "
kono
parents:
diff changeset
1346 "non-trivially-copyable type %qT in left "
kono
parents:
diff changeset
1347 "operand of comma operator", type);
kono
parents:
diff changeset
1348 break;
kono
parents:
diff changeset
1349 case ICV_STATEMENT:
kono
parents:
diff changeset
1350 warning_at (loc, 0, "indirection will not access object of "
kono
parents:
diff changeset
1351 "non-trivially-copyable type %qT in statement",
kono
parents:
diff changeset
1352 type);
kono
parents:
diff changeset
1353 break;
kono
parents:
diff changeset
1354 case ICV_THIRD_IN_FOR:
kono
parents:
diff changeset
1355 warning_at (loc, 0, "indirection will not access object of "
kono
parents:
diff changeset
1356 "non-trivially-copyable type %qT in for "
kono
parents:
diff changeset
1357 "increment expression", type);
kono
parents:
diff changeset
1358 break;
kono
parents:
diff changeset
1359 default:
kono
parents:
diff changeset
1360 gcc_unreachable ();
kono
parents:
diff changeset
1361 }
kono
parents:
diff changeset
1362 }
kono
parents:
diff changeset
1363 if (is_reference || !is_volatile || !is_complete || TREE_ADDRESSABLE (type))
kono
parents:
diff changeset
1364 {
kono
parents:
diff changeset
1365 /* Emit a warning (if enabled) when the "effect-less" INDIRECT_REF
kono
parents:
diff changeset
1366 operation is stripped off. Note that we don't warn about
kono
parents:
diff changeset
1367 - an expression with TREE_NO_WARNING set. (For an example of
kono
parents:
diff changeset
1368 such expressions, see build_over_call in call.c.)
kono
parents:
diff changeset
1369 - automatic dereferencing of references, since the user cannot
kono
parents:
diff changeset
1370 control it. (See also warn_if_unused_value() in c-common.c.) */
kono
parents:
diff changeset
1371 if (warn_unused_value
kono
parents:
diff changeset
1372 && implicit != ICV_CAST
kono
parents:
diff changeset
1373 && (complain & tf_warning)
kono
parents:
diff changeset
1374 && !TREE_NO_WARNING (expr)
kono
parents:
diff changeset
1375 && !is_reference)
kono
parents:
diff changeset
1376 warning_at (loc, OPT_Wunused_value, "value computed is not used");
kono
parents:
diff changeset
1377 expr = TREE_OPERAND (expr, 0);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1378 if (TREE_CODE (expr) == CALL_EXPR
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1379 && (complain & tf_warning))
111
kono
parents:
diff changeset
1380 maybe_warn_nodiscard (expr, implicit);
kono
parents:
diff changeset
1381 }
kono
parents:
diff changeset
1382
kono
parents:
diff changeset
1383 break;
kono
parents:
diff changeset
1384 }
kono
parents:
diff changeset
1385
kono
parents:
diff changeset
1386 case VAR_DECL:
kono
parents:
diff changeset
1387 {
kono
parents:
diff changeset
1388 /* External variables might be incomplete. */
kono
parents:
diff changeset
1389 tree type = TREE_TYPE (expr);
kono
parents:
diff changeset
1390 int is_complete = COMPLETE_TYPE_P (complete_type (type));
kono
parents:
diff changeset
1391
kono
parents:
diff changeset
1392 if (TYPE_VOLATILE (type) && !is_complete && (complain & tf_warning))
kono
parents:
diff changeset
1393 switch (implicit)
kono
parents:
diff changeset
1394 {
kono
parents:
diff changeset
1395 case ICV_CAST:
kono
parents:
diff changeset
1396 warning_at (loc, 0, "conversion to void will not access "
kono
parents:
diff changeset
1397 "object %qE of incomplete type %qT", expr, type);
kono
parents:
diff changeset
1398 break;
kono
parents:
diff changeset
1399 case ICV_SECOND_OF_COND:
kono
parents:
diff changeset
1400 warning_at (loc, 0, "variable %qE of incomplete type %qT will "
kono
parents:
diff changeset
1401 "not be accessed in second operand of "
kono
parents:
diff changeset
1402 "conditional expression", expr, type);
kono
parents:
diff changeset
1403 break;
kono
parents:
diff changeset
1404 case ICV_THIRD_OF_COND:
kono
parents:
diff changeset
1405 warning_at (loc, 0, "variable %qE of incomplete type %qT will "
kono
parents:
diff changeset
1406 "not be accessed in third operand of "
kono
parents:
diff changeset
1407 "conditional expression", expr, type);
kono
parents:
diff changeset
1408 break;
kono
parents:
diff changeset
1409 case ICV_RIGHT_OF_COMMA:
kono
parents:
diff changeset
1410 warning_at (loc, 0, "variable %qE of incomplete type %qT will "
kono
parents:
diff changeset
1411 "not be accessed in right operand of comma operator",
kono
parents:
diff changeset
1412 expr, type);
kono
parents:
diff changeset
1413 break;
kono
parents:
diff changeset
1414 case ICV_LEFT_OF_COMMA:
kono
parents:
diff changeset
1415 warning_at (loc, 0, "variable %qE of incomplete type %qT will "
kono
parents:
diff changeset
1416 "not be accessed in left operand of comma operator",
kono
parents:
diff changeset
1417 expr, type);
kono
parents:
diff changeset
1418 break;
kono
parents:
diff changeset
1419 case ICV_STATEMENT:
kono
parents:
diff changeset
1420 warning_at (loc, 0, "variable %qE of incomplete type %qT will "
kono
parents:
diff changeset
1421 "not be accessed in statement", expr, type);
kono
parents:
diff changeset
1422 break;
kono
parents:
diff changeset
1423 case ICV_THIRD_IN_FOR:
kono
parents:
diff changeset
1424 warning_at (loc, 0, "variable %qE of incomplete type %qT will "
kono
parents:
diff changeset
1425 "not be accessed in for increment expression",
kono
parents:
diff changeset
1426 expr, type);
kono
parents:
diff changeset
1427 break;
kono
parents:
diff changeset
1428 default:
kono
parents:
diff changeset
1429 gcc_unreachable ();
kono
parents:
diff changeset
1430 }
kono
parents:
diff changeset
1431
kono
parents:
diff changeset
1432 break;
kono
parents:
diff changeset
1433 }
kono
parents:
diff changeset
1434
kono
parents:
diff changeset
1435 case TARGET_EXPR:
kono
parents:
diff changeset
1436 /* Don't bother with the temporary object returned from a function if
kono
parents:
diff changeset
1437 we don't use it, don't need to destroy it, and won't abort in
kono
parents:
diff changeset
1438 assign_temp. We'll still
kono
parents:
diff changeset
1439 allocate space for it in expand_call or declare_return_variable,
kono
parents:
diff changeset
1440 but we don't need to track it through all the tree phases. */
kono
parents:
diff changeset
1441 if (TARGET_EXPR_IMPLICIT_P (expr)
kono
parents:
diff changeset
1442 && !TREE_ADDRESSABLE (TREE_TYPE (expr)))
kono
parents:
diff changeset
1443 {
kono
parents:
diff changeset
1444 tree init = TARGET_EXPR_INITIAL (expr);
kono
parents:
diff changeset
1445 if (TREE_CODE (init) == AGGR_INIT_EXPR
kono
parents:
diff changeset
1446 && !AGGR_INIT_VIA_CTOR_P (init))
kono
parents:
diff changeset
1447 {
kono
parents:
diff changeset
1448 tree fn = AGGR_INIT_EXPR_FN (init);
kono
parents:
diff changeset
1449 expr = build_call_array_loc (input_location,
kono
parents:
diff changeset
1450 TREE_TYPE (TREE_TYPE
kono
parents:
diff changeset
1451 (TREE_TYPE (fn))),
kono
parents:
diff changeset
1452 fn,
kono
parents:
diff changeset
1453 aggr_init_expr_nargs (init),
kono
parents:
diff changeset
1454 AGGR_INIT_EXPR_ARGP (init));
kono
parents:
diff changeset
1455 }
kono
parents:
diff changeset
1456 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1457 if (complain & tf_warning)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1458 maybe_warn_nodiscard (expr, implicit);
111
kono
parents:
diff changeset
1459 break;
kono
parents:
diff changeset
1460
kono
parents:
diff changeset
1461 default:;
kono
parents:
diff changeset
1462 }
kono
parents:
diff changeset
1463 expr = resolve_nondeduced_context (expr, complain);
kono
parents:
diff changeset
1464 {
kono
parents:
diff changeset
1465 tree probe = expr;
kono
parents:
diff changeset
1466
kono
parents:
diff changeset
1467 if (TREE_CODE (probe) == ADDR_EXPR)
kono
parents:
diff changeset
1468 probe = TREE_OPERAND (expr, 0);
kono
parents:
diff changeset
1469 if (type_unknown_p (probe))
kono
parents:
diff changeset
1470 {
kono
parents:
diff changeset
1471 /* [over.over] enumerates the places where we can take the address
kono
parents:
diff changeset
1472 of an overloaded function, and this is not one of them. */
kono
parents:
diff changeset
1473 if (complain & tf_error)
kono
parents:
diff changeset
1474 switch (implicit)
kono
parents:
diff changeset
1475 {
kono
parents:
diff changeset
1476 case ICV_CAST:
kono
parents:
diff changeset
1477 error_at (loc, "conversion to void "
kono
parents:
diff changeset
1478 "cannot resolve address of overloaded function");
kono
parents:
diff changeset
1479 break;
kono
parents:
diff changeset
1480 case ICV_SECOND_OF_COND:
kono
parents:
diff changeset
1481 error_at (loc, "second operand of conditional expression "
kono
parents:
diff changeset
1482 "cannot resolve address of overloaded function");
kono
parents:
diff changeset
1483 break;
kono
parents:
diff changeset
1484 case ICV_THIRD_OF_COND:
kono
parents:
diff changeset
1485 error_at (loc, "third operand of conditional expression "
kono
parents:
diff changeset
1486 "cannot resolve address of overloaded function");
kono
parents:
diff changeset
1487 break;
kono
parents:
diff changeset
1488 case ICV_RIGHT_OF_COMMA:
kono
parents:
diff changeset
1489 error_at (loc, "right operand of comma operator "
kono
parents:
diff changeset
1490 "cannot resolve address of overloaded function");
kono
parents:
diff changeset
1491 break;
kono
parents:
diff changeset
1492 case ICV_LEFT_OF_COMMA:
kono
parents:
diff changeset
1493 error_at (loc, "left operand of comma operator "
kono
parents:
diff changeset
1494 "cannot resolve address of overloaded function");
kono
parents:
diff changeset
1495 break;
kono
parents:
diff changeset
1496 case ICV_STATEMENT:
kono
parents:
diff changeset
1497 error_at (loc, "statement "
kono
parents:
diff changeset
1498 "cannot resolve address of overloaded function");
kono
parents:
diff changeset
1499 break;
kono
parents:
diff changeset
1500 case ICV_THIRD_IN_FOR:
kono
parents:
diff changeset
1501 error_at (loc, "for increment expression "
kono
parents:
diff changeset
1502 "cannot resolve address of overloaded function");
kono
parents:
diff changeset
1503 break;
kono
parents:
diff changeset
1504 }
kono
parents:
diff changeset
1505 else
kono
parents:
diff changeset
1506 return error_mark_node;
kono
parents:
diff changeset
1507 expr = void_node;
kono
parents:
diff changeset
1508 }
kono
parents:
diff changeset
1509 else if (implicit != ICV_CAST && probe == expr && is_overloaded_fn (probe))
kono
parents:
diff changeset
1510 {
kono
parents:
diff changeset
1511 /* Only warn when there is no &. */
kono
parents:
diff changeset
1512 if (complain & tf_warning)
kono
parents:
diff changeset
1513 switch (implicit)
kono
parents:
diff changeset
1514 {
kono
parents:
diff changeset
1515 case ICV_SECOND_OF_COND:
kono
parents:
diff changeset
1516 warning_at (loc, OPT_Waddress,
kono
parents:
diff changeset
1517 "second operand of conditional expression "
kono
parents:
diff changeset
1518 "is a reference, not call, to function %qE", expr);
kono
parents:
diff changeset
1519 break;
kono
parents:
diff changeset
1520 case ICV_THIRD_OF_COND:
kono
parents:
diff changeset
1521 warning_at (loc, OPT_Waddress,
kono
parents:
diff changeset
1522 "third operand of conditional expression "
kono
parents:
diff changeset
1523 "is a reference, not call, to function %qE", expr);
kono
parents:
diff changeset
1524 break;
kono
parents:
diff changeset
1525 case ICV_RIGHT_OF_COMMA:
kono
parents:
diff changeset
1526 warning_at (loc, OPT_Waddress,
kono
parents:
diff changeset
1527 "right operand of comma operator "
kono
parents:
diff changeset
1528 "is a reference, not call, to function %qE", expr);
kono
parents:
diff changeset
1529 break;
kono
parents:
diff changeset
1530 case ICV_LEFT_OF_COMMA:
kono
parents:
diff changeset
1531 warning_at (loc, OPT_Waddress,
kono
parents:
diff changeset
1532 "left operand of comma operator "
kono
parents:
diff changeset
1533 "is a reference, not call, to function %qE", expr);
kono
parents:
diff changeset
1534 break;
kono
parents:
diff changeset
1535 case ICV_STATEMENT:
kono
parents:
diff changeset
1536 warning_at (loc, OPT_Waddress,
kono
parents:
diff changeset
1537 "statement is a reference, not call, to function %qE",
kono
parents:
diff changeset
1538 expr);
kono
parents:
diff changeset
1539 break;
kono
parents:
diff changeset
1540 case ICV_THIRD_IN_FOR:
kono
parents:
diff changeset
1541 warning_at (loc, OPT_Waddress,
kono
parents:
diff changeset
1542 "for increment expression "
kono
parents:
diff changeset
1543 "is a reference, not call, to function %qE", expr);
kono
parents:
diff changeset
1544 break;
kono
parents:
diff changeset
1545 default:
kono
parents:
diff changeset
1546 gcc_unreachable ();
kono
parents:
diff changeset
1547 }
kono
parents:
diff changeset
1548
kono
parents:
diff changeset
1549 if (TREE_CODE (expr) == COMPONENT_REF)
kono
parents:
diff changeset
1550 expr = TREE_OPERAND (expr, 0);
kono
parents:
diff changeset
1551 }
kono
parents:
diff changeset
1552 }
kono
parents:
diff changeset
1553
kono
parents:
diff changeset
1554 if (expr != error_mark_node && !VOID_TYPE_P (TREE_TYPE (expr)))
kono
parents:
diff changeset
1555 {
kono
parents:
diff changeset
1556 if (implicit != ICV_CAST
kono
parents:
diff changeset
1557 && warn_unused_value
kono
parents:
diff changeset
1558 && !TREE_NO_WARNING (expr)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1559 && !processing_template_decl
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1560 && !cp_unevaluated_operand)
111
kono
parents:
diff changeset
1561 {
kono
parents:
diff changeset
1562 /* The middle end does not warn about expressions that have
kono
parents:
diff changeset
1563 been explicitly cast to void, so we must do so here. */
kono
parents:
diff changeset
1564 if (!TREE_SIDE_EFFECTS (expr)) {
kono
parents:
diff changeset
1565 if (complain & tf_warning)
kono
parents:
diff changeset
1566 switch (implicit)
kono
parents:
diff changeset
1567 {
kono
parents:
diff changeset
1568 case ICV_SECOND_OF_COND:
kono
parents:
diff changeset
1569 warning_at (loc, OPT_Wunused_value,
kono
parents:
diff changeset
1570 "second operand of conditional expression "
kono
parents:
diff changeset
1571 "has no effect");
kono
parents:
diff changeset
1572 break;
kono
parents:
diff changeset
1573 case ICV_THIRD_OF_COND:
kono
parents:
diff changeset
1574 warning_at (loc, OPT_Wunused_value,
kono
parents:
diff changeset
1575 "third operand of conditional expression "
kono
parents:
diff changeset
1576 "has no effect");
kono
parents:
diff changeset
1577 break;
kono
parents:
diff changeset
1578 case ICV_RIGHT_OF_COMMA:
kono
parents:
diff changeset
1579 warning_at (loc, OPT_Wunused_value,
kono
parents:
diff changeset
1580 "right operand of comma operator has no effect");
kono
parents:
diff changeset
1581 break;
kono
parents:
diff changeset
1582 case ICV_LEFT_OF_COMMA:
kono
parents:
diff changeset
1583 warning_at (loc, OPT_Wunused_value,
kono
parents:
diff changeset
1584 "left operand of comma operator has no effect");
kono
parents:
diff changeset
1585 break;
kono
parents:
diff changeset
1586 case ICV_STATEMENT:
kono
parents:
diff changeset
1587 warning_at (loc, OPT_Wunused_value,
kono
parents:
diff changeset
1588 "statement has no effect");
kono
parents:
diff changeset
1589 break;
kono
parents:
diff changeset
1590 case ICV_THIRD_IN_FOR:
kono
parents:
diff changeset
1591 warning_at (loc, OPT_Wunused_value,
kono
parents:
diff changeset
1592 "for increment expression has no effect");
kono
parents:
diff changeset
1593 break;
kono
parents:
diff changeset
1594 default:
kono
parents:
diff changeset
1595 gcc_unreachable ();
kono
parents:
diff changeset
1596 }
kono
parents:
diff changeset
1597 }
kono
parents:
diff changeset
1598 else
kono
parents:
diff changeset
1599 {
kono
parents:
diff changeset
1600 tree e;
kono
parents:
diff changeset
1601 enum tree_code code;
kono
parents:
diff changeset
1602 enum tree_code_class tclass;
kono
parents:
diff changeset
1603
kono
parents:
diff changeset
1604 e = expr;
kono
parents:
diff changeset
1605 /* We might like to warn about (say) "(int) f()", as the
kono
parents:
diff changeset
1606 cast has no effect, but the compiler itself will
kono
parents:
diff changeset
1607 generate implicit conversions under some
kono
parents:
diff changeset
1608 circumstances. (For example a block copy will be
kono
parents:
diff changeset
1609 turned into a call to "__builtin_memcpy", with a
kono
parents:
diff changeset
1610 conversion of the return value to an appropriate
kono
parents:
diff changeset
1611 type.) So, to avoid false positives, we strip
kono
parents:
diff changeset
1612 conversions. Do not use STRIP_NOPs because it will
kono
parents:
diff changeset
1613 not strip conversions to "void", as that is not a
kono
parents:
diff changeset
1614 mode-preserving conversion. */
kono
parents:
diff changeset
1615 while (TREE_CODE (e) == NOP_EXPR)
kono
parents:
diff changeset
1616 e = TREE_OPERAND (e, 0);
kono
parents:
diff changeset
1617
kono
parents:
diff changeset
1618 code = TREE_CODE (e);
kono
parents:
diff changeset
1619 tclass = TREE_CODE_CLASS (code);
kono
parents:
diff changeset
1620 if ((tclass == tcc_comparison
kono
parents:
diff changeset
1621 || tclass == tcc_unary
kono
parents:
diff changeset
1622 || (tclass == tcc_binary
kono
parents:
diff changeset
1623 && !(code == MODIFY_EXPR
kono
parents:
diff changeset
1624 || code == INIT_EXPR
kono
parents:
diff changeset
1625 || code == PREDECREMENT_EXPR
kono
parents:
diff changeset
1626 || code == PREINCREMENT_EXPR
kono
parents:
diff changeset
1627 || code == POSTDECREMENT_EXPR
kono
parents:
diff changeset
1628 || code == POSTINCREMENT_EXPR))
kono
parents:
diff changeset
1629 || code == VEC_PERM_EXPR
kono
parents:
diff changeset
1630 || code == VEC_COND_EXPR)
kono
parents:
diff changeset
1631 && (complain & tf_warning))
kono
parents:
diff changeset
1632 warning_at (loc, OPT_Wunused_value, "value computed is not used");
kono
parents:
diff changeset
1633 }
kono
parents:
diff changeset
1634 }
kono
parents:
diff changeset
1635 expr = build1 (CONVERT_EXPR, void_type_node, expr);
kono
parents:
diff changeset
1636 }
kono
parents:
diff changeset
1637 if (! TREE_SIDE_EFFECTS (expr))
kono
parents:
diff changeset
1638 expr = void_node;
kono
parents:
diff changeset
1639 return expr;
kono
parents:
diff changeset
1640 }
kono
parents:
diff changeset
1641
kono
parents:
diff changeset
1642 /* Create an expression whose value is that of EXPR,
kono
parents:
diff changeset
1643 converted to type TYPE. The TREE_TYPE of the value
kono
parents:
diff changeset
1644 is always TYPE. This function implements all reasonable
kono
parents:
diff changeset
1645 conversions; callers should filter out those that are
kono
parents:
diff changeset
1646 not permitted by the language being compiled.
kono
parents:
diff changeset
1647
kono
parents:
diff changeset
1648 Most of this routine is from build_reinterpret_cast.
kono
parents:
diff changeset
1649
kono
parents:
diff changeset
1650 The back end cannot call cp_convert (what was convert) because
kono
parents:
diff changeset
1651 conversions to/from basetypes may involve memory references
kono
parents:
diff changeset
1652 (vbases) and adding or subtracting small values (multiple
kono
parents:
diff changeset
1653 inheritance), but it calls convert from the constant folding code
kono
parents:
diff changeset
1654 on subtrees of already built trees after it has ripped them apart.
kono
parents:
diff changeset
1655
kono
parents:
diff changeset
1656 Also, if we ever support range variables, we'll probably also have to
kono
parents:
diff changeset
1657 do a little bit more work. */
kono
parents:
diff changeset
1658
kono
parents:
diff changeset
1659 tree
kono
parents:
diff changeset
1660 convert (tree type, tree expr)
kono
parents:
diff changeset
1661 {
kono
parents:
diff changeset
1662 tree intype;
kono
parents:
diff changeset
1663
kono
parents:
diff changeset
1664 if (type == error_mark_node || expr == error_mark_node)
kono
parents:
diff changeset
1665 return error_mark_node;
kono
parents:
diff changeset
1666
kono
parents:
diff changeset
1667 intype = TREE_TYPE (expr);
kono
parents:
diff changeset
1668
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1669 if (INDIRECT_TYPE_P (type) && INDIRECT_TYPE_P (intype))
111
kono
parents:
diff changeset
1670 return build_nop (type, expr);
kono
parents:
diff changeset
1671
kono
parents:
diff changeset
1672 return ocp_convert (type, expr, CONV_BACKEND_CONVERT,
kono
parents:
diff changeset
1673 LOOKUP_NORMAL|LOOKUP_NO_CONVERSION,
kono
parents:
diff changeset
1674 tf_warning_or_error);
kono
parents:
diff changeset
1675 }
kono
parents:
diff changeset
1676
kono
parents:
diff changeset
1677 /* Like cp_convert, except permit conversions to take place which
kono
parents:
diff changeset
1678 are not normally allowed due to access restrictions
kono
parents:
diff changeset
1679 (such as conversion from sub-type to private super-type). */
kono
parents:
diff changeset
1680
kono
parents:
diff changeset
1681 tree
kono
parents:
diff changeset
1682 convert_force (tree type, tree expr, int convtype, tsubst_flags_t complain)
kono
parents:
diff changeset
1683 {
kono
parents:
diff changeset
1684 tree e = expr;
kono
parents:
diff changeset
1685 enum tree_code code = TREE_CODE (type);
kono
parents:
diff changeset
1686
kono
parents:
diff changeset
1687 if (code == REFERENCE_TYPE)
kono
parents:
diff changeset
1688 return convert_to_reference (type, e, CONV_C_CAST, 0,
kono
parents:
diff changeset
1689 NULL_TREE, complain);
kono
parents:
diff changeset
1690
kono
parents:
diff changeset
1691 if (code == POINTER_TYPE)
kono
parents:
diff changeset
1692 return convert_to_pointer_force (type, e, complain);
kono
parents:
diff changeset
1693
kono
parents:
diff changeset
1694 /* From typeck.c convert_for_assignment */
kono
parents:
diff changeset
1695 if (((TYPE_PTR_P (TREE_TYPE (e)) && TREE_CODE (e) == ADDR_EXPR
kono
parents:
diff changeset
1696 && TREE_CODE (TREE_TYPE (TREE_TYPE (e))) == METHOD_TYPE)
kono
parents:
diff changeset
1697 || integer_zerop (e)
kono
parents:
diff changeset
1698 || TYPE_PTRMEMFUNC_P (TREE_TYPE (e)))
kono
parents:
diff changeset
1699 && TYPE_PTRMEMFUNC_P (type))
kono
parents:
diff changeset
1700 /* compatible pointer to member functions. */
kono
parents:
diff changeset
1701 return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), e, 1,
kono
parents:
diff changeset
1702 /*c_cast_p=*/1, complain);
kono
parents:
diff changeset
1703
kono
parents:
diff changeset
1704 return ocp_convert (type, e, CONV_C_CAST|convtype, LOOKUP_NORMAL, complain);
kono
parents:
diff changeset
1705 }
kono
parents:
diff changeset
1706
kono
parents:
diff changeset
1707 /* Convert an aggregate EXPR to type XTYPE. If a conversion
kono
parents:
diff changeset
1708 exists, return the attempted conversion. This may
kono
parents:
diff changeset
1709 return ERROR_MARK_NODE if the conversion is not
kono
parents:
diff changeset
1710 allowed (references private members, etc).
kono
parents:
diff changeset
1711 If no conversion exists, NULL_TREE is returned.
kono
parents:
diff changeset
1712
kono
parents:
diff changeset
1713 FIXME: Ambiguity checking is wrong. Should choose one by the implicit
kono
parents:
diff changeset
1714 object parameter, or by the second standard conversion sequence if
kono
parents:
diff changeset
1715 that doesn't do it. This will probably wait for an overloading rewrite.
kono
parents:
diff changeset
1716 (jason 8/9/95) */
kono
parents:
diff changeset
1717
kono
parents:
diff changeset
1718 static tree
kono
parents:
diff changeset
1719 build_type_conversion (tree xtype, tree expr)
kono
parents:
diff changeset
1720 {
kono
parents:
diff changeset
1721 /* C++: check to see if we can convert this aggregate type
kono
parents:
diff changeset
1722 into the required type. */
kono
parents:
diff changeset
1723 return build_user_type_conversion (xtype, expr, LOOKUP_NORMAL,
kono
parents:
diff changeset
1724 tf_warning_or_error);
kono
parents:
diff changeset
1725 }
kono
parents:
diff changeset
1726
kono
parents:
diff changeset
1727 /* Convert the given EXPR to one of a group of types suitable for use in an
kono
parents:
diff changeset
1728 expression. DESIRES is a combination of various WANT_* flags (q.v.)
kono
parents:
diff changeset
1729 which indicates which types are suitable. If COMPLAIN is true, complain
kono
parents:
diff changeset
1730 about ambiguity; otherwise, the caller will deal with it. */
kono
parents:
diff changeset
1731
kono
parents:
diff changeset
1732 tree
kono
parents:
diff changeset
1733 build_expr_type_conversion (int desires, tree expr, bool complain)
kono
parents:
diff changeset
1734 {
kono
parents:
diff changeset
1735 tree basetype = TREE_TYPE (expr);
kono
parents:
diff changeset
1736 tree conv = NULL_TREE;
kono
parents:
diff changeset
1737 tree winner = NULL_TREE;
kono
parents:
diff changeset
1738
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1739 if (null_node_p (expr)
111
kono
parents:
diff changeset
1740 && (desires & WANT_INT)
kono
parents:
diff changeset
1741 && !(desires & WANT_NULL))
kono
parents:
diff changeset
1742 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1743 location_t loc =
111
kono
parents:
diff changeset
1744 expansion_point_location_if_in_system_header (input_location);
kono
parents:
diff changeset
1745
kono
parents:
diff changeset
1746 warning_at (loc, OPT_Wconversion_null,
kono
parents:
diff changeset
1747 "converting NULL to non-pointer type");
kono
parents:
diff changeset
1748 }
kono
parents:
diff changeset
1749
kono
parents:
diff changeset
1750 if (basetype == error_mark_node)
kono
parents:
diff changeset
1751 return error_mark_node;
kono
parents:
diff changeset
1752
kono
parents:
diff changeset
1753 if (! MAYBE_CLASS_TYPE_P (basetype))
kono
parents:
diff changeset
1754 switch (TREE_CODE (basetype))
kono
parents:
diff changeset
1755 {
kono
parents:
diff changeset
1756 case INTEGER_TYPE:
kono
parents:
diff changeset
1757 if ((desires & WANT_NULL) && null_ptr_cst_p (expr))
kono
parents:
diff changeset
1758 return expr;
kono
parents:
diff changeset
1759 /* fall through. */
kono
parents:
diff changeset
1760
kono
parents:
diff changeset
1761 case BOOLEAN_TYPE:
kono
parents:
diff changeset
1762 return (desires & WANT_INT) ? expr : NULL_TREE;
kono
parents:
diff changeset
1763 case ENUMERAL_TYPE:
kono
parents:
diff changeset
1764 return (desires & WANT_ENUM) ? expr : NULL_TREE;
kono
parents:
diff changeset
1765 case REAL_TYPE:
kono
parents:
diff changeset
1766 return (desires & WANT_FLOAT) ? expr : NULL_TREE;
kono
parents:
diff changeset
1767 case POINTER_TYPE:
kono
parents:
diff changeset
1768 return (desires & WANT_POINTER) ? expr : NULL_TREE;
kono
parents:
diff changeset
1769
kono
parents:
diff changeset
1770 case FUNCTION_TYPE:
kono
parents:
diff changeset
1771 case ARRAY_TYPE:
kono
parents:
diff changeset
1772 return (desires & WANT_POINTER) ? decay_conversion (expr,
kono
parents:
diff changeset
1773 tf_warning_or_error)
kono
parents:
diff changeset
1774 : NULL_TREE;
kono
parents:
diff changeset
1775
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1776 case VECTOR_TYPE:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1777 if (!gnu_vector_type_p (basetype))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1778 return NULL_TREE;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1779 /* FALLTHROUGH */
111
kono
parents:
diff changeset
1780 case COMPLEX_TYPE:
kono
parents:
diff changeset
1781 if ((desires & WANT_VECTOR_OR_COMPLEX) == 0)
kono
parents:
diff changeset
1782 return NULL_TREE;
kono
parents:
diff changeset
1783 switch (TREE_CODE (TREE_TYPE (basetype)))
kono
parents:
diff changeset
1784 {
kono
parents:
diff changeset
1785 case INTEGER_TYPE:
kono
parents:
diff changeset
1786 case BOOLEAN_TYPE:
kono
parents:
diff changeset
1787 return (desires & WANT_INT) ? expr : NULL_TREE;
kono
parents:
diff changeset
1788 case ENUMERAL_TYPE:
kono
parents:
diff changeset
1789 return (desires & WANT_ENUM) ? expr : NULL_TREE;
kono
parents:
diff changeset
1790 case REAL_TYPE:
kono
parents:
diff changeset
1791 return (desires & WANT_FLOAT) ? expr : NULL_TREE;
kono
parents:
diff changeset
1792 default:
kono
parents:
diff changeset
1793 return NULL_TREE;
kono
parents:
diff changeset
1794 }
kono
parents:
diff changeset
1795
kono
parents:
diff changeset
1796 default:
kono
parents:
diff changeset
1797 return NULL_TREE;
kono
parents:
diff changeset
1798 }
kono
parents:
diff changeset
1799
kono
parents:
diff changeset
1800 /* The code for conversions from class type is currently only used for
kono
parents:
diff changeset
1801 delete expressions. Other expressions are handled by build_new_op. */
kono
parents:
diff changeset
1802 if (!complete_type_or_maybe_complain (basetype, expr, complain))
kono
parents:
diff changeset
1803 return error_mark_node;
kono
parents:
diff changeset
1804 if (!TYPE_HAS_CONVERSION (basetype))
kono
parents:
diff changeset
1805 return NULL_TREE;
kono
parents:
diff changeset
1806
kono
parents:
diff changeset
1807 for (conv = lookup_conversions (basetype); conv; conv = TREE_CHAIN (conv))
kono
parents:
diff changeset
1808 {
kono
parents:
diff changeset
1809 int win = 0;
kono
parents:
diff changeset
1810 tree candidate;
kono
parents:
diff changeset
1811 tree cand = TREE_VALUE (conv);
kono
parents:
diff changeset
1812 cand = OVL_FIRST (cand);
kono
parents:
diff changeset
1813
kono
parents:
diff changeset
1814 if (winner && winner == cand)
kono
parents:
diff changeset
1815 continue;
kono
parents:
diff changeset
1816
kono
parents:
diff changeset
1817 if (DECL_NONCONVERTING_P (cand))
kono
parents:
diff changeset
1818 continue;
kono
parents:
diff changeset
1819
kono
parents:
diff changeset
1820 candidate = non_reference (TREE_TYPE (TREE_TYPE (cand)));
kono
parents:
diff changeset
1821
kono
parents:
diff changeset
1822 switch (TREE_CODE (candidate))
kono
parents:
diff changeset
1823 {
kono
parents:
diff changeset
1824 case BOOLEAN_TYPE:
kono
parents:
diff changeset
1825 case INTEGER_TYPE:
kono
parents:
diff changeset
1826 win = (desires & WANT_INT); break;
kono
parents:
diff changeset
1827 case ENUMERAL_TYPE:
kono
parents:
diff changeset
1828 win = (desires & WANT_ENUM); break;
kono
parents:
diff changeset
1829 case REAL_TYPE:
kono
parents:
diff changeset
1830 win = (desires & WANT_FLOAT); break;
kono
parents:
diff changeset
1831 case POINTER_TYPE:
kono
parents:
diff changeset
1832 win = (desires & WANT_POINTER); break;
kono
parents:
diff changeset
1833
kono
parents:
diff changeset
1834 case COMPLEX_TYPE:
kono
parents:
diff changeset
1835 case VECTOR_TYPE:
kono
parents:
diff changeset
1836 if ((desires & WANT_VECTOR_OR_COMPLEX) == 0)
kono
parents:
diff changeset
1837 break;
kono
parents:
diff changeset
1838 switch (TREE_CODE (TREE_TYPE (candidate)))
kono
parents:
diff changeset
1839 {
kono
parents:
diff changeset
1840 case BOOLEAN_TYPE:
kono
parents:
diff changeset
1841 case INTEGER_TYPE:
kono
parents:
diff changeset
1842 win = (desires & WANT_INT); break;
kono
parents:
diff changeset
1843 case ENUMERAL_TYPE:
kono
parents:
diff changeset
1844 win = (desires & WANT_ENUM); break;
kono
parents:
diff changeset
1845 case REAL_TYPE:
kono
parents:
diff changeset
1846 win = (desires & WANT_FLOAT); break;
kono
parents:
diff changeset
1847 default:
kono
parents:
diff changeset
1848 break;
kono
parents:
diff changeset
1849 }
kono
parents:
diff changeset
1850 break;
kono
parents:
diff changeset
1851
kono
parents:
diff changeset
1852 default:
kono
parents:
diff changeset
1853 /* A wildcard could be instantiated to match any desired
kono
parents:
diff changeset
1854 type, but we can't deduce the template argument. */
kono
parents:
diff changeset
1855 if (WILDCARD_TYPE_P (candidate))
kono
parents:
diff changeset
1856 win = true;
kono
parents:
diff changeset
1857 break;
kono
parents:
diff changeset
1858 }
kono
parents:
diff changeset
1859
kono
parents:
diff changeset
1860 if (win)
kono
parents:
diff changeset
1861 {
kono
parents:
diff changeset
1862 if (TREE_CODE (cand) == TEMPLATE_DECL)
kono
parents:
diff changeset
1863 {
kono
parents:
diff changeset
1864 if (complain)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1865 error ("default type conversion cannot deduce template"
111
kono
parents:
diff changeset
1866 " argument for %qD", cand);
kono
parents:
diff changeset
1867 return error_mark_node;
kono
parents:
diff changeset
1868 }
kono
parents:
diff changeset
1869
kono
parents:
diff changeset
1870 if (winner)
kono
parents:
diff changeset
1871 {
kono
parents:
diff changeset
1872 tree winner_type
kono
parents:
diff changeset
1873 = non_reference (TREE_TYPE (TREE_TYPE (winner)));
kono
parents:
diff changeset
1874
kono
parents:
diff changeset
1875 if (!same_type_ignoring_top_level_qualifiers_p (winner_type,
kono
parents:
diff changeset
1876 candidate))
kono
parents:
diff changeset
1877 {
kono
parents:
diff changeset
1878 if (complain)
kono
parents:
diff changeset
1879 {
kono
parents:
diff changeset
1880 error ("ambiguous default type conversion from %qT",
kono
parents:
diff changeset
1881 basetype);
kono
parents:
diff changeset
1882 inform (input_location,
kono
parents:
diff changeset
1883 " candidate conversions include %qD and %qD",
kono
parents:
diff changeset
1884 winner, cand);
kono
parents:
diff changeset
1885 }
kono
parents:
diff changeset
1886 return error_mark_node;
kono
parents:
diff changeset
1887 }
kono
parents:
diff changeset
1888 }
kono
parents:
diff changeset
1889
kono
parents:
diff changeset
1890 winner = cand;
kono
parents:
diff changeset
1891 }
kono
parents:
diff changeset
1892 }
kono
parents:
diff changeset
1893
kono
parents:
diff changeset
1894 if (winner)
kono
parents:
diff changeset
1895 {
kono
parents:
diff changeset
1896 tree type = non_reference (TREE_TYPE (TREE_TYPE (winner)));
kono
parents:
diff changeset
1897 return build_user_type_conversion (type, expr, LOOKUP_NORMAL,
kono
parents:
diff changeset
1898 tf_warning_or_error);
kono
parents:
diff changeset
1899 }
kono
parents:
diff changeset
1900
kono
parents:
diff changeset
1901 return NULL_TREE;
kono
parents:
diff changeset
1902 }
kono
parents:
diff changeset
1903
kono
parents:
diff changeset
1904 /* Implements integral promotion (4.1) and float->double promotion. */
kono
parents:
diff changeset
1905
kono
parents:
diff changeset
1906 tree
kono
parents:
diff changeset
1907 type_promotes_to (tree type)
kono
parents:
diff changeset
1908 {
kono
parents:
diff changeset
1909 tree promoted_type;
kono
parents:
diff changeset
1910
kono
parents:
diff changeset
1911 if (type == error_mark_node)
kono
parents:
diff changeset
1912 return error_mark_node;
kono
parents:
diff changeset
1913
kono
parents:
diff changeset
1914 type = TYPE_MAIN_VARIANT (type);
kono
parents:
diff changeset
1915
kono
parents:
diff changeset
1916 /* Check for promotions of target-defined types first. */
kono
parents:
diff changeset
1917 promoted_type = targetm.promoted_type (type);
kono
parents:
diff changeset
1918 if (promoted_type)
kono
parents:
diff changeset
1919 return promoted_type;
kono
parents:
diff changeset
1920
kono
parents:
diff changeset
1921 /* bool always promotes to int (not unsigned), even if it's the same
kono
parents:
diff changeset
1922 size. */
kono
parents:
diff changeset
1923 if (TREE_CODE (type) == BOOLEAN_TYPE)
kono
parents:
diff changeset
1924 type = integer_type_node;
kono
parents:
diff changeset
1925
kono
parents:
diff changeset
1926 /* Normally convert enums to int, but convert wide enums to something
kono
parents:
diff changeset
1927 wider. Scoped enums don't promote, but pretend they do for backward
kono
parents:
diff changeset
1928 ABI bug compatibility wrt varargs. */
kono
parents:
diff changeset
1929 else if (TREE_CODE (type) == ENUMERAL_TYPE
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1930 || type == char8_type_node
111
kono
parents:
diff changeset
1931 || type == char16_type_node
kono
parents:
diff changeset
1932 || type == char32_type_node
kono
parents:
diff changeset
1933 || type == wchar_type_node)
kono
parents:
diff changeset
1934 {
kono
parents:
diff changeset
1935 tree prom = type;
kono
parents:
diff changeset
1936
kono
parents:
diff changeset
1937 if (TREE_CODE (type) == ENUMERAL_TYPE)
kono
parents:
diff changeset
1938 {
kono
parents:
diff changeset
1939 prom = ENUM_UNDERLYING_TYPE (prom);
kono
parents:
diff changeset
1940 if (!ENUM_IS_SCOPED (type)
kono
parents:
diff changeset
1941 && ENUM_FIXED_UNDERLYING_TYPE_P (type))
kono
parents:
diff changeset
1942 {
kono
parents:
diff changeset
1943 /* ISO C++17, 7.6/4. A prvalue of an unscoped enumeration type
kono
parents:
diff changeset
1944 whose underlying type is fixed (10.2) can be converted to a
kono
parents:
diff changeset
1945 prvalue of its underlying type. Moreover, if integral promotion
kono
parents:
diff changeset
1946 can be applied to its underlying type, a prvalue of an unscoped
kono
parents:
diff changeset
1947 enumeration type whose underlying type is fixed can also be
kono
parents:
diff changeset
1948 converted to a prvalue of the promoted underlying type. */
kono
parents:
diff changeset
1949 return type_promotes_to (prom);
kono
parents:
diff changeset
1950 }
kono
parents:
diff changeset
1951 }
kono
parents:
diff changeset
1952
kono
parents:
diff changeset
1953 int precision = MAX (TYPE_PRECISION (type),
kono
parents:
diff changeset
1954 TYPE_PRECISION (integer_type_node));
kono
parents:
diff changeset
1955 tree totype = c_common_type_for_size (precision, 0);
kono
parents:
diff changeset
1956 if (TYPE_UNSIGNED (prom)
kono
parents:
diff changeset
1957 && ! int_fits_type_p (TYPE_MAX_VALUE (prom), totype))
kono
parents:
diff changeset
1958 prom = c_common_type_for_size (precision, 1);
kono
parents:
diff changeset
1959 else
kono
parents:
diff changeset
1960 prom = totype;
kono
parents:
diff changeset
1961 if (SCOPED_ENUM_P (type))
kono
parents:
diff changeset
1962 {
kono
parents:
diff changeset
1963 if (abi_version_crosses (6)
kono
parents:
diff changeset
1964 && TYPE_MODE (prom) != TYPE_MODE (type))
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1965 warning (OPT_Wabi, "scoped enum %qT passed through %<...%> as "
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1966 "%qT before %<-fabi-version=6%>, %qT after",
111
kono
parents:
diff changeset
1967 type, prom, ENUM_UNDERLYING_TYPE (type));
kono
parents:
diff changeset
1968 if (!abi_version_at_least (6))
kono
parents:
diff changeset
1969 type = prom;
kono
parents:
diff changeset
1970 }
kono
parents:
diff changeset
1971 else
kono
parents:
diff changeset
1972 type = prom;
kono
parents:
diff changeset
1973 }
kono
parents:
diff changeset
1974 else if (c_promoting_integer_type_p (type))
kono
parents:
diff changeset
1975 {
kono
parents:
diff changeset
1976 /* Retain unsignedness if really not getting bigger. */
kono
parents:
diff changeset
1977 if (TYPE_UNSIGNED (type)
kono
parents:
diff changeset
1978 && TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))
kono
parents:
diff changeset
1979 type = unsigned_type_node;
kono
parents:
diff changeset
1980 else
kono
parents:
diff changeset
1981 type = integer_type_node;
kono
parents:
diff changeset
1982 }
kono
parents:
diff changeset
1983 else if (type == float_type_node)
kono
parents:
diff changeset
1984 type = double_type_node;
kono
parents:
diff changeset
1985
kono
parents:
diff changeset
1986 return type;
kono
parents:
diff changeset
1987 }
kono
parents:
diff changeset
1988
kono
parents:
diff changeset
1989 /* The routines below this point are carefully written to conform to
kono
parents:
diff changeset
1990 the standard. They use the same terminology, and follow the rules
kono
parents:
diff changeset
1991 closely. Although they are used only in pt.c at the moment, they
kono
parents:
diff changeset
1992 should presumably be used everywhere in the future. */
kono
parents:
diff changeset
1993
kono
parents:
diff changeset
1994 /* True iff EXPR can be converted to TYPE via a qualification conversion.
kono
parents:
diff changeset
1995 Callers should check for identical types before calling this function. */
kono
parents:
diff changeset
1996
kono
parents:
diff changeset
1997 bool
kono
parents:
diff changeset
1998 can_convert_qual (tree type, tree expr)
kono
parents:
diff changeset
1999 {
kono
parents:
diff changeset
2000 tree expr_type = TREE_TYPE (expr);
kono
parents:
diff changeset
2001 gcc_assert (!same_type_p (type, expr_type));
kono
parents:
diff changeset
2002
kono
parents:
diff changeset
2003 if (TYPE_PTR_P (type) && TYPE_PTR_P (expr_type))
kono
parents:
diff changeset
2004 return comp_ptr_ttypes (TREE_TYPE (type), TREE_TYPE (expr_type));
kono
parents:
diff changeset
2005 else if (TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (expr_type))
kono
parents:
diff changeset
2006 return (same_type_p (TYPE_PTRMEM_CLASS_TYPE (type),
kono
parents:
diff changeset
2007 TYPE_PTRMEM_CLASS_TYPE (expr_type))
kono
parents:
diff changeset
2008 && comp_ptr_ttypes (TYPE_PTRMEM_POINTED_TO_TYPE (type),
kono
parents:
diff changeset
2009 TYPE_PTRMEM_POINTED_TO_TYPE (expr_type)));
kono
parents:
diff changeset
2010 else
kono
parents:
diff changeset
2011 return false;
kono
parents:
diff changeset
2012 }
kono
parents:
diff changeset
2013
kono
parents:
diff changeset
2014 /* Attempt to perform qualification conversions on EXPR to convert it
kono
parents:
diff changeset
2015 to TYPE. Return the resulting expression, or error_mark_node if
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2016 the conversion was impossible. Since this is only used by
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2017 convert_nontype_argument, we fold the conversion. */
111
kono
parents:
diff changeset
2018
kono
parents:
diff changeset
2019 tree
kono
parents:
diff changeset
2020 perform_qualification_conversions (tree type, tree expr)
kono
parents:
diff changeset
2021 {
kono
parents:
diff changeset
2022 tree expr_type;
kono
parents:
diff changeset
2023
kono
parents:
diff changeset
2024 expr_type = TREE_TYPE (expr);
kono
parents:
diff changeset
2025
kono
parents:
diff changeset
2026 if (same_type_p (type, expr_type))
kono
parents:
diff changeset
2027 return expr;
kono
parents:
diff changeset
2028 else if (can_convert_qual (type, expr))
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2029 return cp_fold_convert (type, expr);
111
kono
parents:
diff changeset
2030 else
kono
parents:
diff changeset
2031 return error_mark_node;
kono
parents:
diff changeset
2032 }
kono
parents:
diff changeset
2033
kono
parents:
diff changeset
2034 /* True iff T is a transaction-safe function type. */
kono
parents:
diff changeset
2035
kono
parents:
diff changeset
2036 bool
kono
parents:
diff changeset
2037 tx_safe_fn_type_p (tree t)
kono
parents:
diff changeset
2038 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2039 if (!FUNC_OR_METHOD_TYPE_P (t))
111
kono
parents:
diff changeset
2040 return false;
kono
parents:
diff changeset
2041 return !!lookup_attribute ("transaction_safe", TYPE_ATTRIBUTES (t));
kono
parents:
diff changeset
2042 }
kono
parents:
diff changeset
2043
kono
parents:
diff changeset
2044 /* Return the transaction-unsafe variant of transaction-safe function type
kono
parents:
diff changeset
2045 T. */
kono
parents:
diff changeset
2046
kono
parents:
diff changeset
2047 tree
kono
parents:
diff changeset
2048 tx_unsafe_fn_variant (tree t)
kono
parents:
diff changeset
2049 {
kono
parents:
diff changeset
2050 gcc_assert (tx_safe_fn_type_p (t));
kono
parents:
diff changeset
2051 tree attrs = remove_attribute ("transaction_safe",
kono
parents:
diff changeset
2052 TYPE_ATTRIBUTES (t));
kono
parents:
diff changeset
2053 return cp_build_type_attribute_variant (t, attrs);
kono
parents:
diff changeset
2054 }
kono
parents:
diff changeset
2055
kono
parents:
diff changeset
2056 /* Return true iff FROM can convert to TO by a transaction-safety
kono
parents:
diff changeset
2057 conversion. */
kono
parents:
diff changeset
2058
kono
parents:
diff changeset
2059 static bool
kono
parents:
diff changeset
2060 can_convert_tx_safety (tree to, tree from)
kono
parents:
diff changeset
2061 {
kono
parents:
diff changeset
2062 return (flag_tm && tx_safe_fn_type_p (from)
kono
parents:
diff changeset
2063 && same_type_p (to, tx_unsafe_fn_variant (from)));
kono
parents:
diff changeset
2064 }
kono
parents:
diff changeset
2065
kono
parents:
diff changeset
2066 /* Return true iff FROM can convert to TO by dropping noexcept. */
kono
parents:
diff changeset
2067
kono
parents:
diff changeset
2068 static bool
kono
parents:
diff changeset
2069 noexcept_conv_p (tree to, tree from)
kono
parents:
diff changeset
2070 {
kono
parents:
diff changeset
2071 if (!flag_noexcept_type)
kono
parents:
diff changeset
2072 return false;
kono
parents:
diff changeset
2073
kono
parents:
diff changeset
2074 tree t = non_reference (to);
kono
parents:
diff changeset
2075 tree f = from;
kono
parents:
diff changeset
2076 if (TYPE_PTRMEMFUNC_P (t)
kono
parents:
diff changeset
2077 && TYPE_PTRMEMFUNC_P (f))
kono
parents:
diff changeset
2078 {
kono
parents:
diff changeset
2079 t = TYPE_PTRMEMFUNC_FN_TYPE (t);
kono
parents:
diff changeset
2080 f = TYPE_PTRMEMFUNC_FN_TYPE (f);
kono
parents:
diff changeset
2081 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2082 if (TYPE_PTR_P (t)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2083 && TYPE_PTR_P (f))
111
kono
parents:
diff changeset
2084 {
kono
parents:
diff changeset
2085 t = TREE_TYPE (t);
kono
parents:
diff changeset
2086 f = TREE_TYPE (f);
kono
parents:
diff changeset
2087 }
kono
parents:
diff changeset
2088 tree_code code = TREE_CODE (f);
kono
parents:
diff changeset
2089 if (TREE_CODE (t) != code)
kono
parents:
diff changeset
2090 return false;
kono
parents:
diff changeset
2091 if (code != FUNCTION_TYPE && code != METHOD_TYPE)
kono
parents:
diff changeset
2092 return false;
kono
parents:
diff changeset
2093 if (!type_throw_all_p (t)
kono
parents:
diff changeset
2094 || type_throw_all_p (f))
kono
parents:
diff changeset
2095 return false;
kono
parents:
diff changeset
2096 tree v = build_exception_variant (f, NULL_TREE);
kono
parents:
diff changeset
2097 return same_type_p (t, v);
kono
parents:
diff changeset
2098 }
kono
parents:
diff changeset
2099
kono
parents:
diff changeset
2100 /* Return true iff FROM can convert to TO by a function pointer conversion. */
kono
parents:
diff changeset
2101
kono
parents:
diff changeset
2102 bool
kono
parents:
diff changeset
2103 fnptr_conv_p (tree to, tree from)
kono
parents:
diff changeset
2104 {
kono
parents:
diff changeset
2105 tree t = non_reference (to);
kono
parents:
diff changeset
2106 tree f = from;
kono
parents:
diff changeset
2107 if (TYPE_PTRMEMFUNC_P (t)
kono
parents:
diff changeset
2108 && TYPE_PTRMEMFUNC_P (f))
kono
parents:
diff changeset
2109 {
kono
parents:
diff changeset
2110 t = TYPE_PTRMEMFUNC_FN_TYPE (t);
kono
parents:
diff changeset
2111 f = TYPE_PTRMEMFUNC_FN_TYPE (f);
kono
parents:
diff changeset
2112 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2113 if (TYPE_PTR_P (t)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2114 && TYPE_PTR_P (f))
111
kono
parents:
diff changeset
2115 {
kono
parents:
diff changeset
2116 t = TREE_TYPE (t);
kono
parents:
diff changeset
2117 f = TREE_TYPE (f);
kono
parents:
diff changeset
2118 }
kono
parents:
diff changeset
2119
kono
parents:
diff changeset
2120 return (noexcept_conv_p (t, f)
kono
parents:
diff changeset
2121 || can_convert_tx_safety (t, f));
kono
parents:
diff changeset
2122 }
kono
parents:
diff changeset
2123
kono
parents:
diff changeset
2124 /* Return FN with any NOP_EXPRs stripped that represent function pointer
kono
parents:
diff changeset
2125 conversions or conversions to the same type. */
kono
parents:
diff changeset
2126
kono
parents:
diff changeset
2127 tree
kono
parents:
diff changeset
2128 strip_fnptr_conv (tree fn)
kono
parents:
diff changeset
2129 {
kono
parents:
diff changeset
2130 while (TREE_CODE (fn) == NOP_EXPR)
kono
parents:
diff changeset
2131 {
kono
parents:
diff changeset
2132 tree op = TREE_OPERAND (fn, 0);
kono
parents:
diff changeset
2133 tree ft = TREE_TYPE (fn);
kono
parents:
diff changeset
2134 tree ot = TREE_TYPE (op);
kono
parents:
diff changeset
2135 if (same_type_p (ft, ot)
kono
parents:
diff changeset
2136 || fnptr_conv_p (ft, ot))
kono
parents:
diff changeset
2137 fn = op;
kono
parents:
diff changeset
2138 else
kono
parents:
diff changeset
2139 break;
kono
parents:
diff changeset
2140 }
kono
parents:
diff changeset
2141 return fn;
kono
parents:
diff changeset
2142 }