annotate gcc/cp/cvt.c @ 131:84e7813d76e9

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