xref: /dragonfly/contrib/gcc-4.7/gcc/cp/typeck.c (revision 95d28233)
1e4b17023SJohn Marino /* Build expressions with type checking for C++ compiler.
2e4b17023SJohn Marino    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3e4b17023SJohn Marino    1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
4e4b17023SJohn Marino    2011, 2012
5e4b17023SJohn Marino    Free Software Foundation, Inc.
6e4b17023SJohn Marino    Hacked by Michael Tiemann (tiemann@cygnus.com)
7e4b17023SJohn Marino 
8e4b17023SJohn Marino This file is part of GCC.
9e4b17023SJohn Marino 
10e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify
11e4b17023SJohn Marino it under the terms of the GNU General Public License as published by
12e4b17023SJohn Marino the Free Software Foundation; either version 3, or (at your option)
13e4b17023SJohn Marino any later version.
14e4b17023SJohn Marino 
15e4b17023SJohn Marino GCC is distributed in the hope that it will be useful,
16e4b17023SJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
17e4b17023SJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18e4b17023SJohn Marino GNU General Public License for more details.
19e4b17023SJohn Marino 
20e4b17023SJohn Marino You should have received a copy of the GNU General Public License
21e4b17023SJohn Marino along with GCC; see the file COPYING3.  If not see
22e4b17023SJohn Marino <http://www.gnu.org/licenses/>.  */
23e4b17023SJohn Marino 
24e4b17023SJohn Marino 
25e4b17023SJohn Marino /* This file is part of the C++ front end.
26e4b17023SJohn Marino    It contains routines to build C++ expressions given their operands,
27e4b17023SJohn Marino    including computing the types of the result, C and C++ specific error
28e4b17023SJohn Marino    checks, and some optimization.  */
29e4b17023SJohn Marino 
30e4b17023SJohn Marino #include "config.h"
31e4b17023SJohn Marino #include "system.h"
32e4b17023SJohn Marino #include "coretypes.h"
33e4b17023SJohn Marino #include "tm.h"
34e4b17023SJohn Marino #include "tree.h"
35e4b17023SJohn Marino #include "cp-tree.h"
36e4b17023SJohn Marino #include "flags.h"
37e4b17023SJohn Marino #include "output.h"
38e4b17023SJohn Marino #include "diagnostic.h"
39e4b17023SJohn Marino #include "intl.h"
40e4b17023SJohn Marino #include "target.h"
41e4b17023SJohn Marino #include "convert.h"
42e4b17023SJohn Marino #include "c-family/c-common.h"
43e4b17023SJohn Marino #include "c-family/c-objc.h"
44e4b17023SJohn Marino #include "params.h"
45e4b17023SJohn Marino 
46e4b17023SJohn Marino static tree pfn_from_ptrmemfunc (tree);
47e4b17023SJohn Marino static tree delta_from_ptrmemfunc (tree);
48e4b17023SJohn Marino static tree convert_for_assignment (tree, tree, impl_conv_rhs, tree, int,
49e4b17023SJohn Marino 				    tsubst_flags_t, int);
50e4b17023SJohn Marino static tree cp_pointer_int_sum (enum tree_code, tree, tree);
51e4b17023SJohn Marino static tree rationalize_conditional_expr (enum tree_code, tree,
52e4b17023SJohn Marino 					  tsubst_flags_t);
53e4b17023SJohn Marino static int comp_ptr_ttypes_real (tree, tree, int);
54e4b17023SJohn Marino static bool comp_except_types (tree, tree, bool);
55e4b17023SJohn Marino static bool comp_array_types (const_tree, const_tree, bool);
56e4b17023SJohn Marino static tree pointer_diff (tree, tree, tree);
57e4b17023SJohn Marino static tree get_delta_difference (tree, tree, bool, bool, tsubst_flags_t);
58e4b17023SJohn Marino static void casts_away_constness_r (tree *, tree *);
59e4b17023SJohn Marino static bool casts_away_constness (tree, tree);
60e4b17023SJohn Marino static void maybe_warn_about_returning_address_of_local (tree);
61e4b17023SJohn Marino static tree lookup_destructor (tree, tree, tree);
62e4b17023SJohn Marino static void warn_args_num (location_t, tree, bool);
63e4b17023SJohn Marino static int convert_arguments (tree, VEC(tree,gc) **, tree, int,
64e4b17023SJohn Marino                               tsubst_flags_t);
65e4b17023SJohn Marino 
66e4b17023SJohn Marino /* Do `exp = require_complete_type (exp);' to make sure exp
67e4b17023SJohn Marino    does not have an incomplete type.  (That includes void types.)
68e4b17023SJohn Marino    Returns error_mark_node if the VALUE does not have
69e4b17023SJohn Marino    complete type when this function returns.  */
70e4b17023SJohn Marino 
71e4b17023SJohn Marino tree
require_complete_type_sfinae(tree value,tsubst_flags_t complain)72e4b17023SJohn Marino require_complete_type_sfinae (tree value, tsubst_flags_t complain)
73e4b17023SJohn Marino {
74e4b17023SJohn Marino   tree type;
75e4b17023SJohn Marino 
76e4b17023SJohn Marino   if (processing_template_decl || value == error_mark_node)
77e4b17023SJohn Marino     return value;
78e4b17023SJohn Marino 
79e4b17023SJohn Marino   if (TREE_CODE (value) == OVERLOAD)
80e4b17023SJohn Marino     type = unknown_type_node;
81e4b17023SJohn Marino   else
82e4b17023SJohn Marino     type = TREE_TYPE (value);
83e4b17023SJohn Marino 
84e4b17023SJohn Marino   if (type == error_mark_node)
85e4b17023SJohn Marino     return error_mark_node;
86e4b17023SJohn Marino 
87e4b17023SJohn Marino   /* First, detect a valid value with a complete type.  */
88e4b17023SJohn Marino   if (COMPLETE_TYPE_P (type))
89e4b17023SJohn Marino     return value;
90e4b17023SJohn Marino 
91e4b17023SJohn Marino   if (complete_type_or_maybe_complain (type, value, complain))
92e4b17023SJohn Marino     return value;
93e4b17023SJohn Marino   else
94e4b17023SJohn Marino     return error_mark_node;
95e4b17023SJohn Marino }
96e4b17023SJohn Marino 
97e4b17023SJohn Marino tree
require_complete_type(tree value)98e4b17023SJohn Marino require_complete_type (tree value)
99e4b17023SJohn Marino {
100e4b17023SJohn Marino   return require_complete_type_sfinae (value, tf_warning_or_error);
101e4b17023SJohn Marino }
102e4b17023SJohn Marino 
103e4b17023SJohn Marino /* Try to complete TYPE, if it is incomplete.  For example, if TYPE is
104e4b17023SJohn Marino    a template instantiation, do the instantiation.  Returns TYPE,
105e4b17023SJohn Marino    whether or not it could be completed, unless something goes
106e4b17023SJohn Marino    horribly wrong, in which case the error_mark_node is returned.  */
107e4b17023SJohn Marino 
108e4b17023SJohn Marino tree
complete_type(tree type)109e4b17023SJohn Marino complete_type (tree type)
110e4b17023SJohn Marino {
111e4b17023SJohn Marino   if (type == NULL_TREE)
112e4b17023SJohn Marino     /* Rather than crash, we return something sure to cause an error
113e4b17023SJohn Marino        at some point.  */
114e4b17023SJohn Marino     return error_mark_node;
115e4b17023SJohn Marino 
116e4b17023SJohn Marino   if (type == error_mark_node || COMPLETE_TYPE_P (type))
117e4b17023SJohn Marino     ;
118e4b17023SJohn Marino   else if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type))
119e4b17023SJohn Marino     {
120e4b17023SJohn Marino       tree t = complete_type (TREE_TYPE (type));
121e4b17023SJohn Marino       unsigned int needs_constructing, has_nontrivial_dtor;
122e4b17023SJohn Marino       if (COMPLETE_TYPE_P (t) && !dependent_type_p (type))
123e4b17023SJohn Marino 	layout_type (type);
124e4b17023SJohn Marino       needs_constructing
125e4b17023SJohn Marino 	= TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (t));
126e4b17023SJohn Marino       has_nontrivial_dtor
127e4b17023SJohn Marino 	= TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TYPE_MAIN_VARIANT (t));
128e4b17023SJohn Marino       for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
129e4b17023SJohn Marino 	{
130e4b17023SJohn Marino 	  TYPE_NEEDS_CONSTRUCTING (t) = needs_constructing;
131e4b17023SJohn Marino 	  TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = has_nontrivial_dtor;
132e4b17023SJohn Marino 	}
133e4b17023SJohn Marino     }
134e4b17023SJohn Marino   else if (CLASS_TYPE_P (type) && CLASSTYPE_TEMPLATE_INSTANTIATION (type))
135e4b17023SJohn Marino     instantiate_class_template (TYPE_MAIN_VARIANT (type));
136e4b17023SJohn Marino 
137e4b17023SJohn Marino   return type;
138e4b17023SJohn Marino }
139e4b17023SJohn Marino 
140e4b17023SJohn Marino /* Like complete_type, but issue an error if the TYPE cannot be completed.
141e4b17023SJohn Marino    VALUE is used for informative diagnostics.
142e4b17023SJohn Marino    Returns NULL_TREE if the type cannot be made complete.  */
143e4b17023SJohn Marino 
144e4b17023SJohn Marino tree
complete_type_or_maybe_complain(tree type,tree value,tsubst_flags_t complain)145e4b17023SJohn Marino complete_type_or_maybe_complain (tree type, tree value, tsubst_flags_t complain)
146e4b17023SJohn Marino {
147e4b17023SJohn Marino   type = complete_type (type);
148e4b17023SJohn Marino   if (type == error_mark_node)
149e4b17023SJohn Marino     /* We already issued an error.  */
150e4b17023SJohn Marino     return NULL_TREE;
151e4b17023SJohn Marino   else if (!COMPLETE_TYPE_P (type))
152e4b17023SJohn Marino     {
153e4b17023SJohn Marino       if (complain & tf_error)
154e4b17023SJohn Marino 	cxx_incomplete_type_diagnostic (value, type, DK_ERROR);
155e4b17023SJohn Marino       return NULL_TREE;
156e4b17023SJohn Marino     }
157e4b17023SJohn Marino   else
158e4b17023SJohn Marino     return type;
159e4b17023SJohn Marino }
160e4b17023SJohn Marino 
161e4b17023SJohn Marino tree
complete_type_or_else(tree type,tree value)162e4b17023SJohn Marino complete_type_or_else (tree type, tree value)
163e4b17023SJohn Marino {
164e4b17023SJohn Marino   return complete_type_or_maybe_complain (type, value, tf_warning_or_error);
165e4b17023SJohn Marino }
166e4b17023SJohn Marino 
167e4b17023SJohn Marino /* Return truthvalue of whether type of EXP is instantiated.  */
168e4b17023SJohn Marino 
169e4b17023SJohn Marino int
type_unknown_p(const_tree exp)170e4b17023SJohn Marino type_unknown_p (const_tree exp)
171e4b17023SJohn Marino {
172e4b17023SJohn Marino   return (TREE_CODE (exp) == TREE_LIST
173e4b17023SJohn Marino 	  || TREE_TYPE (exp) == unknown_type_node);
174e4b17023SJohn Marino }
175e4b17023SJohn Marino 
176e4b17023SJohn Marino 
177e4b17023SJohn Marino /* Return the common type of two parameter lists.
178e4b17023SJohn Marino    We assume that comptypes has already been done and returned 1;
179e4b17023SJohn Marino    if that isn't so, this may crash.
180e4b17023SJohn Marino 
181e4b17023SJohn Marino    As an optimization, free the space we allocate if the parameter
182e4b17023SJohn Marino    lists are already common.  */
183e4b17023SJohn Marino 
184e4b17023SJohn Marino static tree
commonparms(tree p1,tree p2)185e4b17023SJohn Marino commonparms (tree p1, tree p2)
186e4b17023SJohn Marino {
187e4b17023SJohn Marino   tree oldargs = p1, newargs, n;
188e4b17023SJohn Marino   int i, len;
189e4b17023SJohn Marino   int any_change = 0;
190e4b17023SJohn Marino 
191e4b17023SJohn Marino   len = list_length (p1);
192e4b17023SJohn Marino   newargs = tree_last (p1);
193e4b17023SJohn Marino 
194e4b17023SJohn Marino   if (newargs == void_list_node)
195e4b17023SJohn Marino     i = 1;
196e4b17023SJohn Marino   else
197e4b17023SJohn Marino     {
198e4b17023SJohn Marino       i = 0;
199e4b17023SJohn Marino       newargs = 0;
200e4b17023SJohn Marino     }
201e4b17023SJohn Marino 
202e4b17023SJohn Marino   for (; i < len; i++)
203e4b17023SJohn Marino     newargs = tree_cons (NULL_TREE, NULL_TREE, newargs);
204e4b17023SJohn Marino 
205e4b17023SJohn Marino   n = newargs;
206e4b17023SJohn Marino 
207e4b17023SJohn Marino   for (i = 0; p1;
208e4b17023SJohn Marino        p1 = TREE_CHAIN (p1), p2 = TREE_CHAIN (p2), n = TREE_CHAIN (n), i++)
209e4b17023SJohn Marino     {
210e4b17023SJohn Marino       if (TREE_PURPOSE (p1) && !TREE_PURPOSE (p2))
211e4b17023SJohn Marino 	{
212e4b17023SJohn Marino 	  TREE_PURPOSE (n) = TREE_PURPOSE (p1);
213e4b17023SJohn Marino 	  any_change = 1;
214e4b17023SJohn Marino 	}
215e4b17023SJohn Marino       else if (! TREE_PURPOSE (p1))
216e4b17023SJohn Marino 	{
217e4b17023SJohn Marino 	  if (TREE_PURPOSE (p2))
218e4b17023SJohn Marino 	    {
219e4b17023SJohn Marino 	      TREE_PURPOSE (n) = TREE_PURPOSE (p2);
220e4b17023SJohn Marino 	      any_change = 1;
221e4b17023SJohn Marino 	    }
222e4b17023SJohn Marino 	}
223e4b17023SJohn Marino       else
224e4b17023SJohn Marino 	{
225e4b17023SJohn Marino 	  if (1 != simple_cst_equal (TREE_PURPOSE (p1), TREE_PURPOSE (p2)))
226e4b17023SJohn Marino 	    any_change = 1;
227e4b17023SJohn Marino 	  TREE_PURPOSE (n) = TREE_PURPOSE (p2);
228e4b17023SJohn Marino 	}
229e4b17023SJohn Marino       if (TREE_VALUE (p1) != TREE_VALUE (p2))
230e4b17023SJohn Marino 	{
231e4b17023SJohn Marino 	  any_change = 1;
232e4b17023SJohn Marino 	  TREE_VALUE (n) = merge_types (TREE_VALUE (p1), TREE_VALUE (p2));
233e4b17023SJohn Marino 	}
234e4b17023SJohn Marino       else
235e4b17023SJohn Marino 	TREE_VALUE (n) = TREE_VALUE (p1);
236e4b17023SJohn Marino     }
237e4b17023SJohn Marino   if (! any_change)
238e4b17023SJohn Marino     return oldargs;
239e4b17023SJohn Marino 
240e4b17023SJohn Marino   return newargs;
241e4b17023SJohn Marino }
242e4b17023SJohn Marino 
243e4b17023SJohn Marino /* Given a type, perhaps copied for a typedef,
244e4b17023SJohn Marino    find the "original" version of it.  */
245e4b17023SJohn Marino static tree
original_type(tree t)246e4b17023SJohn Marino original_type (tree t)
247e4b17023SJohn Marino {
248e4b17023SJohn Marino   int quals = cp_type_quals (t);
249e4b17023SJohn Marino   while (t != error_mark_node
250e4b17023SJohn Marino 	 && TYPE_NAME (t) != NULL_TREE)
251e4b17023SJohn Marino     {
252e4b17023SJohn Marino       tree x = TYPE_NAME (t);
253e4b17023SJohn Marino       if (TREE_CODE (x) != TYPE_DECL)
254e4b17023SJohn Marino 	break;
255e4b17023SJohn Marino       x = DECL_ORIGINAL_TYPE (x);
256e4b17023SJohn Marino       if (x == NULL_TREE)
257e4b17023SJohn Marino 	break;
258e4b17023SJohn Marino       t = x;
259e4b17023SJohn Marino     }
260e4b17023SJohn Marino   return cp_build_qualified_type (t, quals);
261e4b17023SJohn Marino }
262e4b17023SJohn Marino 
263e4b17023SJohn Marino /* Return the common type for two arithmetic types T1 and T2 under the
264e4b17023SJohn Marino    usual arithmetic conversions.  The default conversions have already
265e4b17023SJohn Marino    been applied, and enumerated types converted to their compatible
266e4b17023SJohn Marino    integer types.  */
267e4b17023SJohn Marino 
268e4b17023SJohn Marino static tree
cp_common_type(tree t1,tree t2)269e4b17023SJohn Marino cp_common_type (tree t1, tree t2)
270e4b17023SJohn Marino {
271e4b17023SJohn Marino   enum tree_code code1 = TREE_CODE (t1);
272e4b17023SJohn Marino   enum tree_code code2 = TREE_CODE (t2);
273e4b17023SJohn Marino   tree attributes;
274e4b17023SJohn Marino 
275e4b17023SJohn Marino 
276e4b17023SJohn Marino   /* In what follows, we slightly generalize the rules given in [expr] so
277e4b17023SJohn Marino      as to deal with `long long' and `complex'.  First, merge the
278e4b17023SJohn Marino      attributes.  */
279e4b17023SJohn Marino   attributes = (*targetm.merge_type_attributes) (t1, t2);
280e4b17023SJohn Marino 
281e4b17023SJohn Marino   if (SCOPED_ENUM_P (t1) || SCOPED_ENUM_P (t2))
282e4b17023SJohn Marino     {
283e4b17023SJohn Marino       if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
284e4b17023SJohn Marino 	return build_type_attribute_variant (t1, attributes);
285e4b17023SJohn Marino       else
286e4b17023SJohn Marino 	return NULL_TREE;
287e4b17023SJohn Marino     }
288e4b17023SJohn Marino 
289e4b17023SJohn Marino   /* FIXME: Attributes.  */
290e4b17023SJohn Marino   gcc_assert (ARITHMETIC_TYPE_P (t1)
291e4b17023SJohn Marino 	      || TREE_CODE (t1) == VECTOR_TYPE
292e4b17023SJohn Marino 	      || UNSCOPED_ENUM_P (t1));
293e4b17023SJohn Marino   gcc_assert (ARITHMETIC_TYPE_P (t2)
294e4b17023SJohn Marino 	      || TREE_CODE (t2) == VECTOR_TYPE
295e4b17023SJohn Marino 	      || UNSCOPED_ENUM_P (t2));
296e4b17023SJohn Marino 
297e4b17023SJohn Marino   /* If one type is complex, form the common type of the non-complex
298e4b17023SJohn Marino      components, then make that complex.  Use T1 or T2 if it is the
299e4b17023SJohn Marino      required type.  */
300e4b17023SJohn Marino   if (code1 == COMPLEX_TYPE || code2 == COMPLEX_TYPE)
301e4b17023SJohn Marino     {
302e4b17023SJohn Marino       tree subtype1 = code1 == COMPLEX_TYPE ? TREE_TYPE (t1) : t1;
303e4b17023SJohn Marino       tree subtype2 = code2 == COMPLEX_TYPE ? TREE_TYPE (t2) : t2;
304e4b17023SJohn Marino       tree subtype
305e4b17023SJohn Marino 	= type_after_usual_arithmetic_conversions (subtype1, subtype2);
306e4b17023SJohn Marino 
307e4b17023SJohn Marino       if (code1 == COMPLEX_TYPE && TREE_TYPE (t1) == subtype)
308e4b17023SJohn Marino 	return build_type_attribute_variant (t1, attributes);
309e4b17023SJohn Marino       else if (code2 == COMPLEX_TYPE && TREE_TYPE (t2) == subtype)
310e4b17023SJohn Marino 	return build_type_attribute_variant (t2, attributes);
311e4b17023SJohn Marino       else
312e4b17023SJohn Marino 	return build_type_attribute_variant (build_complex_type (subtype),
313e4b17023SJohn Marino 					     attributes);
314e4b17023SJohn Marino     }
315e4b17023SJohn Marino 
316e4b17023SJohn Marino   if (code1 == VECTOR_TYPE)
317e4b17023SJohn Marino     {
318e4b17023SJohn Marino       /* When we get here we should have two vectors of the same size.
319e4b17023SJohn Marino 	 Just prefer the unsigned one if present.  */
320e4b17023SJohn Marino       if (TYPE_UNSIGNED (t1))
321e4b17023SJohn Marino 	return build_type_attribute_variant (t1, attributes);
322e4b17023SJohn Marino       else
323e4b17023SJohn Marino 	return build_type_attribute_variant (t2, attributes);
324e4b17023SJohn Marino     }
325e4b17023SJohn Marino 
326e4b17023SJohn Marino   /* If only one is real, use it as the result.  */
327e4b17023SJohn Marino   if (code1 == REAL_TYPE && code2 != REAL_TYPE)
328e4b17023SJohn Marino     return build_type_attribute_variant (t1, attributes);
329e4b17023SJohn Marino   if (code2 == REAL_TYPE && code1 != REAL_TYPE)
330e4b17023SJohn Marino     return build_type_attribute_variant (t2, attributes);
331e4b17023SJohn Marino 
332e4b17023SJohn Marino   /* Both real or both integers; use the one with greater precision.  */
333e4b17023SJohn Marino   if (TYPE_PRECISION (t1) > TYPE_PRECISION (t2))
334e4b17023SJohn Marino     return build_type_attribute_variant (t1, attributes);
335e4b17023SJohn Marino   else if (TYPE_PRECISION (t2) > TYPE_PRECISION (t1))
336e4b17023SJohn Marino     return build_type_attribute_variant (t2, attributes);
337e4b17023SJohn Marino 
338e4b17023SJohn Marino   /* The types are the same; no need to do anything fancy.  */
339e4b17023SJohn Marino   if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
340e4b17023SJohn Marino     return build_type_attribute_variant (t1, attributes);
341e4b17023SJohn Marino 
342e4b17023SJohn Marino   if (code1 != REAL_TYPE)
343e4b17023SJohn Marino     {
344e4b17023SJohn Marino       /* If one is unsigned long long, then convert the other to unsigned
345e4b17023SJohn Marino 	 long long.  */
346e4b17023SJohn Marino       if (same_type_p (TYPE_MAIN_VARIANT (t1), long_long_unsigned_type_node)
347e4b17023SJohn Marino 	  || same_type_p (TYPE_MAIN_VARIANT (t2), long_long_unsigned_type_node))
348e4b17023SJohn Marino 	return build_type_attribute_variant (long_long_unsigned_type_node,
349e4b17023SJohn Marino 					     attributes);
350e4b17023SJohn Marino       /* If one is a long long, and the other is an unsigned long, and
351e4b17023SJohn Marino 	 long long can represent all the values of an unsigned long, then
352e4b17023SJohn Marino 	 convert to a long long.  Otherwise, convert to an unsigned long
353e4b17023SJohn Marino 	 long.  Otherwise, if either operand is long long, convert the
354e4b17023SJohn Marino 	 other to long long.
355e4b17023SJohn Marino 
356e4b17023SJohn Marino 	 Since we're here, we know the TYPE_PRECISION is the same;
357e4b17023SJohn Marino 	 therefore converting to long long cannot represent all the values
358e4b17023SJohn Marino 	 of an unsigned long, so we choose unsigned long long in that
359e4b17023SJohn Marino 	 case.  */
360e4b17023SJohn Marino       if (same_type_p (TYPE_MAIN_VARIANT (t1), long_long_integer_type_node)
361e4b17023SJohn Marino 	  || same_type_p (TYPE_MAIN_VARIANT (t2), long_long_integer_type_node))
362e4b17023SJohn Marino 	{
363e4b17023SJohn Marino 	  tree t = ((TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
364e4b17023SJohn Marino 		    ? long_long_unsigned_type_node
365e4b17023SJohn Marino 		    : long_long_integer_type_node);
366e4b17023SJohn Marino 	  return build_type_attribute_variant (t, attributes);
367e4b17023SJohn Marino 	}
368e4b17023SJohn Marino       if (int128_integer_type_node != NULL_TREE
369e4b17023SJohn Marino 	  && (same_type_p (TYPE_MAIN_VARIANT (t1),
370e4b17023SJohn Marino 			   int128_integer_type_node)
371e4b17023SJohn Marino 	      || same_type_p (TYPE_MAIN_VARIANT (t2),
372e4b17023SJohn Marino 			      int128_integer_type_node)))
373e4b17023SJohn Marino 	{
374e4b17023SJohn Marino 	  tree t = ((TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
375e4b17023SJohn Marino 		    ? int128_unsigned_type_node
376e4b17023SJohn Marino 		    : int128_integer_type_node);
377e4b17023SJohn Marino 	  return build_type_attribute_variant (t, attributes);
378e4b17023SJohn Marino 	}
379e4b17023SJohn Marino 
380e4b17023SJohn Marino       /* Go through the same procedure, but for longs.  */
381e4b17023SJohn Marino       if (same_type_p (TYPE_MAIN_VARIANT (t1), long_unsigned_type_node)
382e4b17023SJohn Marino 	  || same_type_p (TYPE_MAIN_VARIANT (t2), long_unsigned_type_node))
383e4b17023SJohn Marino 	return build_type_attribute_variant (long_unsigned_type_node,
384e4b17023SJohn Marino 					     attributes);
385e4b17023SJohn Marino       if (same_type_p (TYPE_MAIN_VARIANT (t1), long_integer_type_node)
386e4b17023SJohn Marino 	  || same_type_p (TYPE_MAIN_VARIANT (t2), long_integer_type_node))
387e4b17023SJohn Marino 	{
388e4b17023SJohn Marino 	  tree t = ((TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
389e4b17023SJohn Marino 		    ? long_unsigned_type_node : long_integer_type_node);
390e4b17023SJohn Marino 	  return build_type_attribute_variant (t, attributes);
391e4b17023SJohn Marino 	}
392e4b17023SJohn Marino       /* Otherwise prefer the unsigned one.  */
393e4b17023SJohn Marino       if (TYPE_UNSIGNED (t1))
394e4b17023SJohn Marino 	return build_type_attribute_variant (t1, attributes);
395e4b17023SJohn Marino       else
396e4b17023SJohn Marino 	return build_type_attribute_variant (t2, attributes);
397e4b17023SJohn Marino     }
398e4b17023SJohn Marino   else
399e4b17023SJohn Marino     {
400e4b17023SJohn Marino       if (same_type_p (TYPE_MAIN_VARIANT (t1), long_double_type_node)
401e4b17023SJohn Marino 	  || same_type_p (TYPE_MAIN_VARIANT (t2), long_double_type_node))
402e4b17023SJohn Marino 	return build_type_attribute_variant (long_double_type_node,
403e4b17023SJohn Marino 					     attributes);
404e4b17023SJohn Marino       if (same_type_p (TYPE_MAIN_VARIANT (t1), double_type_node)
405e4b17023SJohn Marino 	  || same_type_p (TYPE_MAIN_VARIANT (t2), double_type_node))
406e4b17023SJohn Marino 	return build_type_attribute_variant (double_type_node,
407e4b17023SJohn Marino 					     attributes);
408e4b17023SJohn Marino       if (same_type_p (TYPE_MAIN_VARIANT (t1), float_type_node)
409e4b17023SJohn Marino 	  || same_type_p (TYPE_MAIN_VARIANT (t2), float_type_node))
410e4b17023SJohn Marino 	return build_type_attribute_variant (float_type_node,
411e4b17023SJohn Marino 					     attributes);
412e4b17023SJohn Marino 
413e4b17023SJohn Marino       /* Two floating-point types whose TYPE_MAIN_VARIANTs are none of
414e4b17023SJohn Marino 	 the standard C++ floating-point types.  Logic earlier in this
415e4b17023SJohn Marino 	 function has already eliminated the possibility that
416e4b17023SJohn Marino 	 TYPE_PRECISION (t2) != TYPE_PRECISION (t1), so there's no
417e4b17023SJohn Marino 	 compelling reason to choose one or the other.  */
418e4b17023SJohn Marino       return build_type_attribute_variant (t1, attributes);
419e4b17023SJohn Marino     }
420e4b17023SJohn Marino }
421e4b17023SJohn Marino 
422e4b17023SJohn Marino /* T1 and T2 are arithmetic or enumeration types.  Return the type
423e4b17023SJohn Marino    that will result from the "usual arithmetic conversions" on T1 and
424e4b17023SJohn Marino    T2 as described in [expr].  */
425e4b17023SJohn Marino 
426e4b17023SJohn Marino tree
type_after_usual_arithmetic_conversions(tree t1,tree t2)427e4b17023SJohn Marino type_after_usual_arithmetic_conversions (tree t1, tree t2)
428e4b17023SJohn Marino {
429e4b17023SJohn Marino   gcc_assert (ARITHMETIC_TYPE_P (t1)
430e4b17023SJohn Marino 	      || TREE_CODE (t1) == VECTOR_TYPE
431e4b17023SJohn Marino 	      || UNSCOPED_ENUM_P (t1));
432e4b17023SJohn Marino   gcc_assert (ARITHMETIC_TYPE_P (t2)
433e4b17023SJohn Marino 	      || TREE_CODE (t2) == VECTOR_TYPE
434e4b17023SJohn Marino 	      || UNSCOPED_ENUM_P (t2));
435e4b17023SJohn Marino 
436e4b17023SJohn Marino   /* Perform the integral promotions.  We do not promote real types here.  */
437e4b17023SJohn Marino   if (INTEGRAL_OR_ENUMERATION_TYPE_P (t1)
438e4b17023SJohn Marino       && INTEGRAL_OR_ENUMERATION_TYPE_P (t2))
439e4b17023SJohn Marino     {
440e4b17023SJohn Marino       t1 = type_promotes_to (t1);
441e4b17023SJohn Marino       t2 = type_promotes_to (t2);
442e4b17023SJohn Marino     }
443e4b17023SJohn Marino 
444e4b17023SJohn Marino   return cp_common_type (t1, t2);
445e4b17023SJohn Marino }
446e4b17023SJohn Marino 
447e4b17023SJohn Marino static void
composite_pointer_error(diagnostic_t kind,tree t1,tree t2,composite_pointer_operation operation)448e4b17023SJohn Marino composite_pointer_error (diagnostic_t kind, tree t1, tree t2,
449e4b17023SJohn Marino 			 composite_pointer_operation operation)
450e4b17023SJohn Marino {
451e4b17023SJohn Marino   switch (operation)
452e4b17023SJohn Marino     {
453e4b17023SJohn Marino     case CPO_COMPARISON:
454e4b17023SJohn Marino       emit_diagnostic (kind, input_location, 0,
455e4b17023SJohn Marino 		       "comparison between "
456e4b17023SJohn Marino 		       "distinct pointer types %qT and %qT lacks a cast",
457e4b17023SJohn Marino 		       t1, t2);
458e4b17023SJohn Marino       break;
459e4b17023SJohn Marino     case CPO_CONVERSION:
460e4b17023SJohn Marino       emit_diagnostic (kind, input_location, 0,
461e4b17023SJohn Marino 		       "conversion between "
462e4b17023SJohn Marino 		       "distinct pointer types %qT and %qT lacks a cast",
463e4b17023SJohn Marino 		       t1, t2);
464e4b17023SJohn Marino       break;
465e4b17023SJohn Marino     case CPO_CONDITIONAL_EXPR:
466e4b17023SJohn Marino       emit_diagnostic (kind, input_location, 0,
467e4b17023SJohn Marino 		       "conditional expression between "
468e4b17023SJohn Marino 		       "distinct pointer types %qT and %qT lacks a cast",
469e4b17023SJohn Marino 		       t1, t2);
470e4b17023SJohn Marino       break;
471e4b17023SJohn Marino     default:
472e4b17023SJohn Marino       gcc_unreachable ();
473e4b17023SJohn Marino     }
474e4b17023SJohn Marino }
475e4b17023SJohn Marino 
476e4b17023SJohn Marino /* Subroutine of composite_pointer_type to implement the recursive
477e4b17023SJohn Marino    case.  See that function for documentation of the parameters.  */
478e4b17023SJohn Marino 
479e4b17023SJohn Marino static tree
composite_pointer_type_r(tree t1,tree t2,composite_pointer_operation operation,tsubst_flags_t complain)480e4b17023SJohn Marino composite_pointer_type_r (tree t1, tree t2,
481e4b17023SJohn Marino 			  composite_pointer_operation operation,
482e4b17023SJohn Marino 			  tsubst_flags_t complain)
483e4b17023SJohn Marino {
484e4b17023SJohn Marino   tree pointee1;
485e4b17023SJohn Marino   tree pointee2;
486e4b17023SJohn Marino   tree result_type;
487e4b17023SJohn Marino   tree attributes;
488e4b17023SJohn Marino 
489e4b17023SJohn Marino   /* Determine the types pointed to by T1 and T2.  */
490e4b17023SJohn Marino   if (TREE_CODE (t1) == POINTER_TYPE)
491e4b17023SJohn Marino     {
492e4b17023SJohn Marino       pointee1 = TREE_TYPE (t1);
493e4b17023SJohn Marino       pointee2 = TREE_TYPE (t2);
494e4b17023SJohn Marino     }
495e4b17023SJohn Marino   else
496e4b17023SJohn Marino     {
497e4b17023SJohn Marino       pointee1 = TYPE_PTRMEM_POINTED_TO_TYPE (t1);
498e4b17023SJohn Marino       pointee2 = TYPE_PTRMEM_POINTED_TO_TYPE (t2);
499e4b17023SJohn Marino     }
500e4b17023SJohn Marino 
501e4b17023SJohn Marino   /* [expr.rel]
502e4b17023SJohn Marino 
503e4b17023SJohn Marino      Otherwise, the composite pointer type is a pointer type
504e4b17023SJohn Marino      similar (_conv.qual_) to the type of one of the operands,
505e4b17023SJohn Marino      with a cv-qualification signature (_conv.qual_) that is the
506e4b17023SJohn Marino      union of the cv-qualification signatures of the operand
507e4b17023SJohn Marino      types.  */
508e4b17023SJohn Marino   if (same_type_ignoring_top_level_qualifiers_p (pointee1, pointee2))
509e4b17023SJohn Marino     result_type = pointee1;
510e4b17023SJohn Marino   else if ((TREE_CODE (pointee1) == POINTER_TYPE
511e4b17023SJohn Marino 	    && TREE_CODE (pointee2) == POINTER_TYPE)
512e4b17023SJohn Marino 	   || (TYPE_PTR_TO_MEMBER_P (pointee1)
513e4b17023SJohn Marino 	       && TYPE_PTR_TO_MEMBER_P (pointee2)))
514e4b17023SJohn Marino     {
515e4b17023SJohn Marino       result_type = composite_pointer_type_r (pointee1, pointee2, operation,
516e4b17023SJohn Marino 					      complain);
517e4b17023SJohn Marino       if (result_type == error_mark_node)
518e4b17023SJohn Marino 	return error_mark_node;
519e4b17023SJohn Marino     }
520e4b17023SJohn Marino   else
521e4b17023SJohn Marino     {
522e4b17023SJohn Marino       if (complain & tf_error)
523e4b17023SJohn Marino 	composite_pointer_error (DK_PERMERROR, t1, t2, operation);
524e4b17023SJohn Marino       else
525e4b17023SJohn Marino 	return error_mark_node;
526e4b17023SJohn Marino       result_type = void_type_node;
527e4b17023SJohn Marino     }
528e4b17023SJohn Marino   result_type = cp_build_qualified_type (result_type,
529e4b17023SJohn Marino 					 (cp_type_quals (pointee1)
530e4b17023SJohn Marino 					  | cp_type_quals (pointee2)));
531e4b17023SJohn Marino   /* If the original types were pointers to members, so is the
532e4b17023SJohn Marino      result.  */
533e4b17023SJohn Marino   if (TYPE_PTR_TO_MEMBER_P (t1))
534e4b17023SJohn Marino     {
535e4b17023SJohn Marino       if (!same_type_p (TYPE_PTRMEM_CLASS_TYPE (t1),
536e4b17023SJohn Marino 			TYPE_PTRMEM_CLASS_TYPE (t2)))
537e4b17023SJohn Marino 	{
538e4b17023SJohn Marino 	  if (complain & tf_error)
539e4b17023SJohn Marino 	    composite_pointer_error (DK_PERMERROR, t1, t2, operation);
540e4b17023SJohn Marino 	  else
541e4b17023SJohn Marino 	    return error_mark_node;
542e4b17023SJohn Marino 	}
543e4b17023SJohn Marino       result_type = build_ptrmem_type (TYPE_PTRMEM_CLASS_TYPE (t1),
544e4b17023SJohn Marino 				       result_type);
545e4b17023SJohn Marino     }
546e4b17023SJohn Marino   else
547e4b17023SJohn Marino     result_type = build_pointer_type (result_type);
548e4b17023SJohn Marino 
549e4b17023SJohn Marino   /* Merge the attributes.  */
550e4b17023SJohn Marino   attributes = (*targetm.merge_type_attributes) (t1, t2);
551e4b17023SJohn Marino   return build_type_attribute_variant (result_type, attributes);
552e4b17023SJohn Marino }
553e4b17023SJohn Marino 
554e4b17023SJohn Marino /* Return the composite pointer type (see [expr.rel]) for T1 and T2.
555e4b17023SJohn Marino    ARG1 and ARG2 are the values with those types.  The OPERATION is to
556e4b17023SJohn Marino    describe the operation between the pointer types,
557e4b17023SJohn Marino    in case an error occurs.
558e4b17023SJohn Marino 
559e4b17023SJohn Marino    This routine also implements the computation of a common type for
560e4b17023SJohn Marino    pointers-to-members as per [expr.eq].  */
561e4b17023SJohn Marino 
562e4b17023SJohn Marino tree
composite_pointer_type(tree t1,tree t2,tree arg1,tree arg2,composite_pointer_operation operation,tsubst_flags_t complain)563e4b17023SJohn Marino composite_pointer_type (tree t1, tree t2, tree arg1, tree arg2,
564e4b17023SJohn Marino 			composite_pointer_operation operation,
565e4b17023SJohn Marino 			tsubst_flags_t complain)
566e4b17023SJohn Marino {
567e4b17023SJohn Marino   tree class1;
568e4b17023SJohn Marino   tree class2;
569e4b17023SJohn Marino 
570e4b17023SJohn Marino   /* [expr.rel]
571e4b17023SJohn Marino 
572e4b17023SJohn Marino      If one operand is a null pointer constant, the composite pointer
573e4b17023SJohn Marino      type is the type of the other operand.  */
574e4b17023SJohn Marino   if (null_ptr_cst_p (arg1))
575e4b17023SJohn Marino     return t2;
576e4b17023SJohn Marino   if (null_ptr_cst_p (arg2))
577e4b17023SJohn Marino     return t1;
578e4b17023SJohn Marino 
579e4b17023SJohn Marino   /* We have:
580e4b17023SJohn Marino 
581e4b17023SJohn Marino        [expr.rel]
582e4b17023SJohn Marino 
583e4b17023SJohn Marino        If one of the operands has type "pointer to cv1 void*", then
584e4b17023SJohn Marino        the other has type "pointer to cv2T", and the composite pointer
585e4b17023SJohn Marino        type is "pointer to cv12 void", where cv12 is the union of cv1
586e4b17023SJohn Marino        and cv2.
587e4b17023SJohn Marino 
588e4b17023SJohn Marino     If either type is a pointer to void, make sure it is T1.  */
589e4b17023SJohn Marino   if (TREE_CODE (t2) == POINTER_TYPE && VOID_TYPE_P (TREE_TYPE (t2)))
590e4b17023SJohn Marino     {
591e4b17023SJohn Marino       tree t;
592e4b17023SJohn Marino       t = t1;
593e4b17023SJohn Marino       t1 = t2;
594e4b17023SJohn Marino       t2 = t;
595e4b17023SJohn Marino     }
596e4b17023SJohn Marino 
597e4b17023SJohn Marino   /* Now, if T1 is a pointer to void, merge the qualifiers.  */
598e4b17023SJohn Marino   if (TREE_CODE (t1) == POINTER_TYPE && VOID_TYPE_P (TREE_TYPE (t1)))
599e4b17023SJohn Marino     {
600e4b17023SJohn Marino       tree attributes;
601e4b17023SJohn Marino       tree result_type;
602e4b17023SJohn Marino 
603e4b17023SJohn Marino       if (TYPE_PTRFN_P (t2) && (complain & tf_error))
604e4b17023SJohn Marino         {
605e4b17023SJohn Marino           switch (operation)
606e4b17023SJohn Marino               {
607e4b17023SJohn Marino               case CPO_COMPARISON:
608e4b17023SJohn Marino                 pedwarn (input_location, OPT_pedantic,
609e4b17023SJohn Marino                          "ISO C++ forbids comparison between "
610e4b17023SJohn Marino                          "pointer of type %<void *%> and pointer-to-function");
611e4b17023SJohn Marino                 break;
612e4b17023SJohn Marino               case CPO_CONVERSION:
613e4b17023SJohn Marino                 pedwarn (input_location, OPT_pedantic,
614e4b17023SJohn Marino                          "ISO C++ forbids conversion between "
615e4b17023SJohn Marino                          "pointer of type %<void *%> and pointer-to-function");
616e4b17023SJohn Marino                 break;
617e4b17023SJohn Marino               case CPO_CONDITIONAL_EXPR:
618e4b17023SJohn Marino                 pedwarn (input_location, OPT_pedantic,
619e4b17023SJohn Marino                          "ISO C++ forbids conditional expression between "
620e4b17023SJohn Marino                          "pointer of type %<void *%> and pointer-to-function");
621e4b17023SJohn Marino                 break;
622e4b17023SJohn Marino               default:
623e4b17023SJohn Marino                 gcc_unreachable ();
624e4b17023SJohn Marino               }
625e4b17023SJohn Marino         }
626e4b17023SJohn Marino       result_type
627e4b17023SJohn Marino 	= cp_build_qualified_type (void_type_node,
628e4b17023SJohn Marino 				   (cp_type_quals (TREE_TYPE (t1))
629e4b17023SJohn Marino 				    | cp_type_quals (TREE_TYPE (t2))));
630e4b17023SJohn Marino       result_type = build_pointer_type (result_type);
631e4b17023SJohn Marino       /* Merge the attributes.  */
632e4b17023SJohn Marino       attributes = (*targetm.merge_type_attributes) (t1, t2);
633e4b17023SJohn Marino       return build_type_attribute_variant (result_type, attributes);
634e4b17023SJohn Marino     }
635e4b17023SJohn Marino 
636e4b17023SJohn Marino   if (c_dialect_objc () && TREE_CODE (t1) == POINTER_TYPE
637e4b17023SJohn Marino       && TREE_CODE (t2) == POINTER_TYPE)
638e4b17023SJohn Marino     {
639e4b17023SJohn Marino       if (objc_have_common_type (t1, t2, -3, NULL_TREE))
640e4b17023SJohn Marino 	return objc_common_type (t1, t2);
641e4b17023SJohn Marino     }
642e4b17023SJohn Marino 
643e4b17023SJohn Marino   /* [expr.eq] permits the application of a pointer conversion to
644e4b17023SJohn Marino      bring the pointers to a common type.  */
645e4b17023SJohn Marino   if (TREE_CODE (t1) == POINTER_TYPE && TREE_CODE (t2) == POINTER_TYPE
646e4b17023SJohn Marino       && CLASS_TYPE_P (TREE_TYPE (t1))
647e4b17023SJohn Marino       && CLASS_TYPE_P (TREE_TYPE (t2))
648e4b17023SJohn Marino       && !same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (t1),
649e4b17023SJohn Marino 						     TREE_TYPE (t2)))
650e4b17023SJohn Marino     {
651e4b17023SJohn Marino       class1 = TREE_TYPE (t1);
652e4b17023SJohn Marino       class2 = TREE_TYPE (t2);
653e4b17023SJohn Marino 
654e4b17023SJohn Marino       if (DERIVED_FROM_P (class1, class2))
655e4b17023SJohn Marino 	t2 = (build_pointer_type
656e4b17023SJohn Marino 	      (cp_build_qualified_type (class1, cp_type_quals (class2))));
657e4b17023SJohn Marino       else if (DERIVED_FROM_P (class2, class1))
658e4b17023SJohn Marino 	t1 = (build_pointer_type
659e4b17023SJohn Marino 	      (cp_build_qualified_type (class2, cp_type_quals (class1))));
660e4b17023SJohn Marino       else
661e4b17023SJohn Marino         {
662e4b17023SJohn Marino           if (complain & tf_error)
663e4b17023SJohn Marino 	    composite_pointer_error (DK_ERROR, t1, t2, operation);
664e4b17023SJohn Marino           return error_mark_node;
665e4b17023SJohn Marino         }
666e4b17023SJohn Marino     }
667e4b17023SJohn Marino   /* [expr.eq] permits the application of a pointer-to-member
668e4b17023SJohn Marino      conversion to change the class type of one of the types.  */
669e4b17023SJohn Marino   else if (TYPE_PTR_TO_MEMBER_P (t1)
670e4b17023SJohn Marino            && !same_type_p (TYPE_PTRMEM_CLASS_TYPE (t1),
671e4b17023SJohn Marino 			    TYPE_PTRMEM_CLASS_TYPE (t2)))
672e4b17023SJohn Marino     {
673e4b17023SJohn Marino       class1 = TYPE_PTRMEM_CLASS_TYPE (t1);
674e4b17023SJohn Marino       class2 = TYPE_PTRMEM_CLASS_TYPE (t2);
675e4b17023SJohn Marino 
676e4b17023SJohn Marino       if (DERIVED_FROM_P (class1, class2))
677e4b17023SJohn Marino 	t1 = build_ptrmem_type (class2, TYPE_PTRMEM_POINTED_TO_TYPE (t1));
678e4b17023SJohn Marino       else if (DERIVED_FROM_P (class2, class1))
679e4b17023SJohn Marino 	t2 = build_ptrmem_type (class1, TYPE_PTRMEM_POINTED_TO_TYPE (t2));
680e4b17023SJohn Marino       else
681e4b17023SJohn Marino         {
682e4b17023SJohn Marino           if (complain & tf_error)
683e4b17023SJohn Marino             switch (operation)
684e4b17023SJohn Marino               {
685e4b17023SJohn Marino               case CPO_COMPARISON:
686e4b17023SJohn Marino                 error ("comparison between distinct "
687e4b17023SJohn Marino                        "pointer-to-member types %qT and %qT lacks a cast",
688e4b17023SJohn Marino                        t1, t2);
689e4b17023SJohn Marino                 break;
690e4b17023SJohn Marino               case CPO_CONVERSION:
691e4b17023SJohn Marino                 error ("conversion between distinct "
692e4b17023SJohn Marino                        "pointer-to-member types %qT and %qT lacks a cast",
693e4b17023SJohn Marino                        t1, t2);
694e4b17023SJohn Marino                 break;
695e4b17023SJohn Marino               case CPO_CONDITIONAL_EXPR:
696e4b17023SJohn Marino                 error ("conditional expression between distinct "
697e4b17023SJohn Marino                        "pointer-to-member types %qT and %qT lacks a cast",
698e4b17023SJohn Marino                        t1, t2);
699e4b17023SJohn Marino                 break;
700e4b17023SJohn Marino               default:
701e4b17023SJohn Marino                 gcc_unreachable ();
702e4b17023SJohn Marino               }
703e4b17023SJohn Marino           return error_mark_node;
704e4b17023SJohn Marino         }
705e4b17023SJohn Marino     }
706e4b17023SJohn Marino 
707e4b17023SJohn Marino   return composite_pointer_type_r (t1, t2, operation, complain);
708e4b17023SJohn Marino }
709e4b17023SJohn Marino 
710e4b17023SJohn Marino /* Return the merged type of two types.
711e4b17023SJohn Marino    We assume that comptypes has already been done and returned 1;
712e4b17023SJohn Marino    if that isn't so, this may crash.
713e4b17023SJohn Marino 
714e4b17023SJohn Marino    This just combines attributes and default arguments; any other
715e4b17023SJohn Marino    differences would cause the two types to compare unalike.  */
716e4b17023SJohn Marino 
717e4b17023SJohn Marino tree
merge_types(tree t1,tree t2)718e4b17023SJohn Marino merge_types (tree t1, tree t2)
719e4b17023SJohn Marino {
720e4b17023SJohn Marino   enum tree_code code1;
721e4b17023SJohn Marino   enum tree_code code2;
722e4b17023SJohn Marino   tree attributes;
723e4b17023SJohn Marino 
724e4b17023SJohn Marino   /* Save time if the two types are the same.  */
725e4b17023SJohn Marino   if (t1 == t2)
726e4b17023SJohn Marino     return t1;
727e4b17023SJohn Marino   if (original_type (t1) == original_type (t2))
728e4b17023SJohn Marino     return t1;
729e4b17023SJohn Marino 
730e4b17023SJohn Marino   /* If one type is nonsense, use the other.  */
731e4b17023SJohn Marino   if (t1 == error_mark_node)
732e4b17023SJohn Marino     return t2;
733e4b17023SJohn Marino   if (t2 == error_mark_node)
734e4b17023SJohn Marino     return t1;
735e4b17023SJohn Marino 
736e4b17023SJohn Marino   /* Merge the attributes.  */
737e4b17023SJohn Marino   attributes = (*targetm.merge_type_attributes) (t1, t2);
738e4b17023SJohn Marino 
739e4b17023SJohn Marino   if (TYPE_PTRMEMFUNC_P (t1))
740e4b17023SJohn Marino     t1 = TYPE_PTRMEMFUNC_FN_TYPE (t1);
741e4b17023SJohn Marino   if (TYPE_PTRMEMFUNC_P (t2))
742e4b17023SJohn Marino     t2 = TYPE_PTRMEMFUNC_FN_TYPE (t2);
743e4b17023SJohn Marino 
744e4b17023SJohn Marino   code1 = TREE_CODE (t1);
745e4b17023SJohn Marino   code2 = TREE_CODE (t2);
746e4b17023SJohn Marino   if (code1 != code2)
747e4b17023SJohn Marino     {
748e4b17023SJohn Marino       gcc_assert (code1 == TYPENAME_TYPE || code2 == TYPENAME_TYPE);
749e4b17023SJohn Marino       if (code1 == TYPENAME_TYPE)
750e4b17023SJohn Marino 	{
751e4b17023SJohn Marino           t1 = resolve_typename_type (t1, /*only_current_p=*/true);
752e4b17023SJohn Marino 	  code1 = TREE_CODE (t1);
753e4b17023SJohn Marino 	}
754e4b17023SJohn Marino       else
755e4b17023SJohn Marino 	{
756e4b17023SJohn Marino           t2 = resolve_typename_type (t2, /*only_current_p=*/true);
757e4b17023SJohn Marino 	  code2 = TREE_CODE (t2);
758e4b17023SJohn Marino 	}
759e4b17023SJohn Marino     }
760e4b17023SJohn Marino 
761e4b17023SJohn Marino   switch (code1)
762e4b17023SJohn Marino     {
763e4b17023SJohn Marino     case POINTER_TYPE:
764e4b17023SJohn Marino     case REFERENCE_TYPE:
765e4b17023SJohn Marino       /* For two pointers, do this recursively on the target type.  */
766e4b17023SJohn Marino       {
767e4b17023SJohn Marino 	tree target = merge_types (TREE_TYPE (t1), TREE_TYPE (t2));
768e4b17023SJohn Marino 	int quals = cp_type_quals (t1);
769e4b17023SJohn Marino 
770e4b17023SJohn Marino 	if (code1 == POINTER_TYPE)
771e4b17023SJohn Marino 	  t1 = build_pointer_type (target);
772e4b17023SJohn Marino 	else
773e4b17023SJohn Marino 	  t1 = cp_build_reference_type (target, TYPE_REF_IS_RVALUE (t1));
774e4b17023SJohn Marino 	t1 = build_type_attribute_variant (t1, attributes);
775e4b17023SJohn Marino 	t1 = cp_build_qualified_type (t1, quals);
776e4b17023SJohn Marino 
777e4b17023SJohn Marino 	if (TREE_CODE (target) == METHOD_TYPE)
778e4b17023SJohn Marino 	  t1 = build_ptrmemfunc_type (t1);
779e4b17023SJohn Marino 
780e4b17023SJohn Marino 	return t1;
781e4b17023SJohn Marino       }
782e4b17023SJohn Marino 
783e4b17023SJohn Marino     case OFFSET_TYPE:
784e4b17023SJohn Marino       {
785e4b17023SJohn Marino 	int quals;
786e4b17023SJohn Marino 	tree pointee;
787e4b17023SJohn Marino 	quals = cp_type_quals (t1);
788e4b17023SJohn Marino 	pointee = merge_types (TYPE_PTRMEM_POINTED_TO_TYPE (t1),
789e4b17023SJohn Marino 			       TYPE_PTRMEM_POINTED_TO_TYPE (t2));
790e4b17023SJohn Marino 	t1 = build_ptrmem_type (TYPE_PTRMEM_CLASS_TYPE (t1),
791e4b17023SJohn Marino 				pointee);
792e4b17023SJohn Marino 	t1 = cp_build_qualified_type (t1, quals);
793e4b17023SJohn Marino 	break;
794e4b17023SJohn Marino       }
795e4b17023SJohn Marino 
796e4b17023SJohn Marino     case ARRAY_TYPE:
797e4b17023SJohn Marino       {
798e4b17023SJohn Marino 	tree elt = merge_types (TREE_TYPE (t1), TREE_TYPE (t2));
799e4b17023SJohn Marino 	/* Save space: see if the result is identical to one of the args.  */
800e4b17023SJohn Marino 	if (elt == TREE_TYPE (t1) && TYPE_DOMAIN (t1))
801e4b17023SJohn Marino 	  return build_type_attribute_variant (t1, attributes);
802e4b17023SJohn Marino 	if (elt == TREE_TYPE (t2) && TYPE_DOMAIN (t2))
803e4b17023SJohn Marino 	  return build_type_attribute_variant (t2, attributes);
804e4b17023SJohn Marino 	/* Merge the element types, and have a size if either arg has one.  */
805e4b17023SJohn Marino 	t1 = build_cplus_array_type
806e4b17023SJohn Marino 	  (elt, TYPE_DOMAIN (TYPE_DOMAIN (t1) ? t1 : t2));
807e4b17023SJohn Marino 	break;
808e4b17023SJohn Marino       }
809e4b17023SJohn Marino 
810e4b17023SJohn Marino     case FUNCTION_TYPE:
811e4b17023SJohn Marino       /* Function types: prefer the one that specified arg types.
812e4b17023SJohn Marino 	 If both do, merge the arg types.  Also merge the return types.  */
813e4b17023SJohn Marino       {
814e4b17023SJohn Marino 	tree valtype = merge_types (TREE_TYPE (t1), TREE_TYPE (t2));
815e4b17023SJohn Marino 	tree p1 = TYPE_ARG_TYPES (t1);
816e4b17023SJohn Marino 	tree p2 = TYPE_ARG_TYPES (t2);
817e4b17023SJohn Marino 	tree parms;
818e4b17023SJohn Marino 	tree rval, raises;
819e4b17023SJohn Marino 
820e4b17023SJohn Marino 	/* Save space: see if the result is identical to one of the args.  */
821e4b17023SJohn Marino 	if (valtype == TREE_TYPE (t1) && ! p2)
822e4b17023SJohn Marino 	  return cp_build_type_attribute_variant (t1, attributes);
823e4b17023SJohn Marino 	if (valtype == TREE_TYPE (t2) && ! p1)
824e4b17023SJohn Marino 	  return cp_build_type_attribute_variant (t2, attributes);
825e4b17023SJohn Marino 
826e4b17023SJohn Marino 	/* Simple way if one arg fails to specify argument types.  */
827e4b17023SJohn Marino 	if (p1 == NULL_TREE || TREE_VALUE (p1) == void_type_node)
828e4b17023SJohn Marino 	  parms = p2;
829e4b17023SJohn Marino 	else if (p2 == NULL_TREE || TREE_VALUE (p2) == void_type_node)
830e4b17023SJohn Marino 	  parms = p1;
831e4b17023SJohn Marino 	else
832e4b17023SJohn Marino 	  parms = commonparms (p1, p2);
833e4b17023SJohn Marino 
834e4b17023SJohn Marino 	rval = build_function_type (valtype, parms);
835e4b17023SJohn Marino 	gcc_assert (type_memfn_quals (t1) == type_memfn_quals (t2));
836e4b17023SJohn Marino 	rval = apply_memfn_quals (rval, type_memfn_quals (t1));
837e4b17023SJohn Marino 	raises = merge_exception_specifiers (TYPE_RAISES_EXCEPTIONS (t1),
838e4b17023SJohn Marino 					     TYPE_RAISES_EXCEPTIONS (t2),
839e4b17023SJohn Marino 					     NULL_TREE);
840e4b17023SJohn Marino 	t1 = build_exception_variant (rval, raises);
841e4b17023SJohn Marino 	break;
842e4b17023SJohn Marino       }
843e4b17023SJohn Marino 
844e4b17023SJohn Marino     case METHOD_TYPE:
845e4b17023SJohn Marino       {
846e4b17023SJohn Marino 	/* Get this value the long way, since TYPE_METHOD_BASETYPE
847e4b17023SJohn Marino 	   is just the main variant of this.  */
848e4b17023SJohn Marino 	tree basetype = class_of_this_parm (t2);
849e4b17023SJohn Marino 	tree raises = merge_exception_specifiers (TYPE_RAISES_EXCEPTIONS (t1),
850e4b17023SJohn Marino 						  TYPE_RAISES_EXCEPTIONS (t2),
851e4b17023SJohn Marino 						  NULL_TREE);
852e4b17023SJohn Marino 	tree t3;
853e4b17023SJohn Marino 
854e4b17023SJohn Marino 	/* If this was a member function type, get back to the
855e4b17023SJohn Marino 	   original type of type member function (i.e., without
856e4b17023SJohn Marino 	   the class instance variable up front.  */
857e4b17023SJohn Marino 	t1 = build_function_type (TREE_TYPE (t1),
858e4b17023SJohn Marino 				  TREE_CHAIN (TYPE_ARG_TYPES (t1)));
859e4b17023SJohn Marino 	t2 = build_function_type (TREE_TYPE (t2),
860e4b17023SJohn Marino 				  TREE_CHAIN (TYPE_ARG_TYPES (t2)));
861e4b17023SJohn Marino 	t3 = merge_types (t1, t2);
862e4b17023SJohn Marino 	t3 = build_method_type_directly (basetype, TREE_TYPE (t3),
863e4b17023SJohn Marino 					 TYPE_ARG_TYPES (t3));
864e4b17023SJohn Marino 	t1 = build_exception_variant (t3, raises);
865e4b17023SJohn Marino 	break;
866e4b17023SJohn Marino       }
867e4b17023SJohn Marino 
868e4b17023SJohn Marino     case TYPENAME_TYPE:
869e4b17023SJohn Marino       /* There is no need to merge attributes into a TYPENAME_TYPE.
870e4b17023SJohn Marino 	 When the type is instantiated it will have whatever
871e4b17023SJohn Marino 	 attributes result from the instantiation.  */
872e4b17023SJohn Marino       return t1;
873e4b17023SJohn Marino 
874e4b17023SJohn Marino     default:;
875e4b17023SJohn Marino     }
876e4b17023SJohn Marino 
877e4b17023SJohn Marino   if (attribute_list_equal (TYPE_ATTRIBUTES (t1), attributes))
878e4b17023SJohn Marino     return t1;
879e4b17023SJohn Marino   else if (attribute_list_equal (TYPE_ATTRIBUTES (t2), attributes))
880e4b17023SJohn Marino     return t2;
881e4b17023SJohn Marino   else
882e4b17023SJohn Marino     return cp_build_type_attribute_variant (t1, attributes);
883e4b17023SJohn Marino }
884e4b17023SJohn Marino 
885e4b17023SJohn Marino /* Return the ARRAY_TYPE type without its domain.  */
886e4b17023SJohn Marino 
887e4b17023SJohn Marino tree
strip_array_domain(tree type)888e4b17023SJohn Marino strip_array_domain (tree type)
889e4b17023SJohn Marino {
890e4b17023SJohn Marino   tree t2;
891e4b17023SJohn Marino   gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
892e4b17023SJohn Marino   if (TYPE_DOMAIN (type) == NULL_TREE)
893e4b17023SJohn Marino     return type;
894e4b17023SJohn Marino   t2 = build_cplus_array_type (TREE_TYPE (type), NULL_TREE);
895e4b17023SJohn Marino   return cp_build_type_attribute_variant (t2, TYPE_ATTRIBUTES (type));
896e4b17023SJohn Marino }
897e4b17023SJohn Marino 
898e4b17023SJohn Marino /* Wrapper around cp_common_type that is used by c-common.c and other
899e4b17023SJohn Marino    front end optimizations that remove promotions.
900e4b17023SJohn Marino 
901e4b17023SJohn Marino    Return the common type for two arithmetic types T1 and T2 under the
902e4b17023SJohn Marino    usual arithmetic conversions.  The default conversions have already
903e4b17023SJohn Marino    been applied, and enumerated types converted to their compatible
904e4b17023SJohn Marino    integer types.  */
905e4b17023SJohn Marino 
906e4b17023SJohn Marino tree
common_type(tree t1,tree t2)907e4b17023SJohn Marino common_type (tree t1, tree t2)
908e4b17023SJohn Marino {
909e4b17023SJohn Marino   /* If one type is nonsense, use the other  */
910e4b17023SJohn Marino   if (t1 == error_mark_node)
911e4b17023SJohn Marino     return t2;
912e4b17023SJohn Marino   if (t2 == error_mark_node)
913e4b17023SJohn Marino     return t1;
914e4b17023SJohn Marino 
915e4b17023SJohn Marino   return cp_common_type (t1, t2);
916e4b17023SJohn Marino }
917e4b17023SJohn Marino 
918e4b17023SJohn Marino /* Return the common type of two pointer types T1 and T2.  This is the
919e4b17023SJohn Marino    type for the result of most arithmetic operations if the operands
920e4b17023SJohn Marino    have the given two types.
921e4b17023SJohn Marino 
922e4b17023SJohn Marino    We assume that comp_target_types has already been done and returned
923e4b17023SJohn Marino    nonzero; if that isn't so, this may crash.  */
924e4b17023SJohn Marino 
925e4b17023SJohn Marino tree
common_pointer_type(tree t1,tree t2)926e4b17023SJohn Marino common_pointer_type (tree t1, tree t2)
927e4b17023SJohn Marino {
928e4b17023SJohn Marino   gcc_assert ((TYPE_PTR_P (t1) && TYPE_PTR_P (t2))
929e4b17023SJohn Marino               || (TYPE_PTRMEM_P (t1) && TYPE_PTRMEM_P (t2))
930e4b17023SJohn Marino               || (TYPE_PTRMEMFUNC_P (t1) && TYPE_PTRMEMFUNC_P (t2)));
931e4b17023SJohn Marino 
932e4b17023SJohn Marino   return composite_pointer_type (t1, t2, error_mark_node, error_mark_node,
933e4b17023SJohn Marino                                  CPO_CONVERSION, tf_warning_or_error);
934e4b17023SJohn Marino }
935e4b17023SJohn Marino 
936e4b17023SJohn Marino /* Compare two exception specifier types for exactness or subsetness, if
937e4b17023SJohn Marino    allowed. Returns false for mismatch, true for match (same, or
938e4b17023SJohn Marino    derived and !exact).
939e4b17023SJohn Marino 
940e4b17023SJohn Marino    [except.spec] "If a class X ... objects of class X or any class publicly
941e4b17023SJohn Marino    and unambiguously derived from X. Similarly, if a pointer type Y * ...
942e4b17023SJohn Marino    exceptions of type Y * or that are pointers to any type publicly and
943e4b17023SJohn Marino    unambiguously derived from Y. Otherwise a function only allows exceptions
944e4b17023SJohn Marino    that have the same type ..."
945e4b17023SJohn Marino    This does not mention cv qualifiers and is different to what throw
946e4b17023SJohn Marino    [except.throw] and catch [except.catch] will do. They will ignore the
947e4b17023SJohn Marino    top level cv qualifiers, and allow qualifiers in the pointer to class
948e4b17023SJohn Marino    example.
949e4b17023SJohn Marino 
950e4b17023SJohn Marino    We implement the letter of the standard.  */
951e4b17023SJohn Marino 
952e4b17023SJohn Marino static bool
comp_except_types(tree a,tree b,bool exact)953e4b17023SJohn Marino comp_except_types (tree a, tree b, bool exact)
954e4b17023SJohn Marino {
955e4b17023SJohn Marino   if (same_type_p (a, b))
956e4b17023SJohn Marino     return true;
957e4b17023SJohn Marino   else if (!exact)
958e4b17023SJohn Marino     {
959e4b17023SJohn Marino       if (cp_type_quals (a) || cp_type_quals (b))
960e4b17023SJohn Marino 	return false;
961e4b17023SJohn Marino 
962e4b17023SJohn Marino       if (TREE_CODE (a) == POINTER_TYPE
963e4b17023SJohn Marino 	  && TREE_CODE (b) == POINTER_TYPE)
964e4b17023SJohn Marino 	{
965e4b17023SJohn Marino 	  a = TREE_TYPE (a);
966e4b17023SJohn Marino 	  b = TREE_TYPE (b);
967e4b17023SJohn Marino 	  if (cp_type_quals (a) || cp_type_quals (b))
968e4b17023SJohn Marino 	    return false;
969e4b17023SJohn Marino 	}
970e4b17023SJohn Marino 
971e4b17023SJohn Marino       if (TREE_CODE (a) != RECORD_TYPE
972e4b17023SJohn Marino 	  || TREE_CODE (b) != RECORD_TYPE)
973e4b17023SJohn Marino 	return false;
974e4b17023SJohn Marino 
975e4b17023SJohn Marino       if (PUBLICLY_UNIQUELY_DERIVED_P (a, b))
976e4b17023SJohn Marino 	return true;
977e4b17023SJohn Marino     }
978e4b17023SJohn Marino   return false;
979e4b17023SJohn Marino }
980e4b17023SJohn Marino 
981e4b17023SJohn Marino /* Return true if TYPE1 and TYPE2 are equivalent exception specifiers.
982e4b17023SJohn Marino    If EXACT is ce_derived, T2 can be stricter than T1 (according to 15.4/5).
983e4b17023SJohn Marino    If EXACT is ce_normal, the compatibility rules in 15.4/3 apply.
984e4b17023SJohn Marino    If EXACT is ce_exact, the specs must be exactly the same. Exception lists
985e4b17023SJohn Marino    are unordered, but we've already filtered out duplicates. Most lists will
986e4b17023SJohn Marino    be in order, we should try to make use of that.  */
987e4b17023SJohn Marino 
988e4b17023SJohn Marino bool
comp_except_specs(const_tree t1,const_tree t2,int exact)989e4b17023SJohn Marino comp_except_specs (const_tree t1, const_tree t2, int exact)
990e4b17023SJohn Marino {
991e4b17023SJohn Marino   const_tree probe;
992e4b17023SJohn Marino   const_tree base;
993e4b17023SJohn Marino   int  length = 0;
994e4b17023SJohn Marino 
995e4b17023SJohn Marino   if (t1 == t2)
996e4b17023SJohn Marino     return true;
997e4b17023SJohn Marino 
998e4b17023SJohn Marino   /* First handle noexcept.  */
999e4b17023SJohn Marino   if (exact < ce_exact)
1000e4b17023SJohn Marino     {
1001e4b17023SJohn Marino       /* noexcept(false) is compatible with no exception-specification,
1002e4b17023SJohn Marino 	 and stricter than any spec.  */
1003e4b17023SJohn Marino       if (t1 == noexcept_false_spec)
1004e4b17023SJohn Marino 	return t2 == NULL_TREE || exact == ce_derived;
1005e4b17023SJohn Marino       /* Even a derived noexcept(false) is compatible with no
1006e4b17023SJohn Marino 	 exception-specification.  */
1007e4b17023SJohn Marino       if (t2 == noexcept_false_spec)
1008e4b17023SJohn Marino 	return t1 == NULL_TREE;
1009e4b17023SJohn Marino 
1010e4b17023SJohn Marino       /* Otherwise, if we aren't looking for an exact match, noexcept is
1011e4b17023SJohn Marino 	 equivalent to throw().  */
1012e4b17023SJohn Marino       if (t1 == noexcept_true_spec)
1013e4b17023SJohn Marino 	t1 = empty_except_spec;
1014e4b17023SJohn Marino       if (t2 == noexcept_true_spec)
1015e4b17023SJohn Marino 	t2 = empty_except_spec;
1016e4b17023SJohn Marino     }
1017e4b17023SJohn Marino 
1018e4b17023SJohn Marino   /* If any noexcept is left, it is only comparable to itself;
1019e4b17023SJohn Marino      either we're looking for an exact match or we're redeclaring a
1020e4b17023SJohn Marino      template with dependent noexcept.  */
1021e4b17023SJohn Marino   if ((t1 && TREE_PURPOSE (t1))
1022e4b17023SJohn Marino       || (t2 && TREE_PURPOSE (t2)))
1023e4b17023SJohn Marino     return (t1 && t2
1024e4b17023SJohn Marino 	    && cp_tree_equal (TREE_PURPOSE (t1), TREE_PURPOSE (t2)));
1025e4b17023SJohn Marino 
1026e4b17023SJohn Marino   if (t1 == NULL_TREE)			   /* T1 is ...  */
1027e4b17023SJohn Marino     return t2 == NULL_TREE || exact == ce_derived;
1028e4b17023SJohn Marino   if (!TREE_VALUE (t1))			   /* t1 is EMPTY */
1029e4b17023SJohn Marino     return t2 != NULL_TREE && !TREE_VALUE (t2);
1030e4b17023SJohn Marino   if (t2 == NULL_TREE)			   /* T2 is ...  */
1031e4b17023SJohn Marino     return false;
1032e4b17023SJohn Marino   if (TREE_VALUE (t1) && !TREE_VALUE (t2)) /* T2 is EMPTY, T1 is not */
1033e4b17023SJohn Marino     return exact == ce_derived;
1034e4b17023SJohn Marino 
1035e4b17023SJohn Marino   /* Neither set is ... or EMPTY, make sure each part of T2 is in T1.
1036e4b17023SJohn Marino      Count how many we find, to determine exactness. For exact matching and
1037e4b17023SJohn Marino      ordered T1, T2, this is an O(n) operation, otherwise its worst case is
1038e4b17023SJohn Marino      O(nm).  */
1039e4b17023SJohn Marino   for (base = t1; t2 != NULL_TREE; t2 = TREE_CHAIN (t2))
1040e4b17023SJohn Marino     {
1041e4b17023SJohn Marino       for (probe = base; probe != NULL_TREE; probe = TREE_CHAIN (probe))
1042e4b17023SJohn Marino 	{
1043e4b17023SJohn Marino 	  tree a = TREE_VALUE (probe);
1044e4b17023SJohn Marino 	  tree b = TREE_VALUE (t2);
1045e4b17023SJohn Marino 
1046e4b17023SJohn Marino 	  if (comp_except_types (a, b, exact))
1047e4b17023SJohn Marino 	    {
1048e4b17023SJohn Marino 	      if (probe == base && exact > ce_derived)
1049e4b17023SJohn Marino 		base = TREE_CHAIN (probe);
1050e4b17023SJohn Marino 	      length++;
1051e4b17023SJohn Marino 	      break;
1052e4b17023SJohn Marino 	    }
1053e4b17023SJohn Marino 	}
1054e4b17023SJohn Marino       if (probe == NULL_TREE)
1055e4b17023SJohn Marino 	return false;
1056e4b17023SJohn Marino     }
1057e4b17023SJohn Marino   return exact == ce_derived || base == NULL_TREE || length == list_length (t1);
1058e4b17023SJohn Marino }
1059e4b17023SJohn Marino 
1060e4b17023SJohn Marino /* Compare the array types T1 and T2.  ALLOW_REDECLARATION is true if
1061e4b17023SJohn Marino    [] can match [size].  */
1062e4b17023SJohn Marino 
1063e4b17023SJohn Marino static bool
comp_array_types(const_tree t1,const_tree t2,bool allow_redeclaration)1064e4b17023SJohn Marino comp_array_types (const_tree t1, const_tree t2, bool allow_redeclaration)
1065e4b17023SJohn Marino {
1066e4b17023SJohn Marino   tree d1;
1067e4b17023SJohn Marino   tree d2;
1068e4b17023SJohn Marino   tree max1, max2;
1069e4b17023SJohn Marino 
1070e4b17023SJohn Marino   if (t1 == t2)
1071e4b17023SJohn Marino     return true;
1072e4b17023SJohn Marino 
1073e4b17023SJohn Marino   /* The type of the array elements must be the same.  */
1074e4b17023SJohn Marino   if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
1075e4b17023SJohn Marino     return false;
1076e4b17023SJohn Marino 
1077e4b17023SJohn Marino   d1 = TYPE_DOMAIN (t1);
1078e4b17023SJohn Marino   d2 = TYPE_DOMAIN (t2);
1079e4b17023SJohn Marino 
1080e4b17023SJohn Marino   if (d1 == d2)
1081e4b17023SJohn Marino     return true;
1082e4b17023SJohn Marino 
1083e4b17023SJohn Marino   /* If one of the arrays is dimensionless, and the other has a
1084e4b17023SJohn Marino      dimension, they are of different types.  However, it is valid to
1085e4b17023SJohn Marino      write:
1086e4b17023SJohn Marino 
1087e4b17023SJohn Marino        extern int a[];
1088e4b17023SJohn Marino        int a[3];
1089e4b17023SJohn Marino 
1090e4b17023SJohn Marino      by [basic.link]:
1091e4b17023SJohn Marino 
1092e4b17023SJohn Marino        declarations for an array object can specify
1093e4b17023SJohn Marino        array types that differ by the presence or absence of a major
1094e4b17023SJohn Marino        array bound (_dcl.array_).  */
1095e4b17023SJohn Marino   if (!d1 || !d2)
1096e4b17023SJohn Marino     return allow_redeclaration;
1097e4b17023SJohn Marino 
1098e4b17023SJohn Marino   /* Check that the dimensions are the same.  */
1099e4b17023SJohn Marino 
1100e4b17023SJohn Marino   if (!cp_tree_equal (TYPE_MIN_VALUE (d1), TYPE_MIN_VALUE (d2)))
1101e4b17023SJohn Marino     return false;
1102e4b17023SJohn Marino   max1 = TYPE_MAX_VALUE (d1);
1103e4b17023SJohn Marino   max2 = TYPE_MAX_VALUE (d2);
1104e4b17023SJohn Marino   if (processing_template_decl && !abi_version_at_least (2)
1105e4b17023SJohn Marino       && !value_dependent_expression_p (max1)
1106e4b17023SJohn Marino       && !value_dependent_expression_p (max2))
1107e4b17023SJohn Marino     {
1108e4b17023SJohn Marino       /* With abi-1 we do not fold non-dependent array bounds, (and
1109e4b17023SJohn Marino 	 consequently mangle them incorrectly).  We must therefore
1110e4b17023SJohn Marino 	 fold them here, to verify the domains have the same
1111e4b17023SJohn Marino 	 value.  */
1112e4b17023SJohn Marino       max1 = fold (max1);
1113e4b17023SJohn Marino       max2 = fold (max2);
1114e4b17023SJohn Marino     }
1115e4b17023SJohn Marino 
1116e4b17023SJohn Marino   if (!cp_tree_equal (max1, max2))
1117e4b17023SJohn Marino     return false;
1118e4b17023SJohn Marino 
1119e4b17023SJohn Marino   return true;
1120e4b17023SJohn Marino }
1121e4b17023SJohn Marino 
1122e4b17023SJohn Marino /* Compare the relative position of T1 and T2 into their respective
1123e4b17023SJohn Marino    template parameter list.
1124e4b17023SJohn Marino    T1 and T2 must be template parameter types.
1125e4b17023SJohn Marino    Return TRUE if T1 and T2 have the same position, FALSE otherwise.  */
1126e4b17023SJohn Marino 
1127e4b17023SJohn Marino static bool
comp_template_parms_position(tree t1,tree t2)1128e4b17023SJohn Marino comp_template_parms_position (tree t1, tree t2)
1129e4b17023SJohn Marino {
1130e4b17023SJohn Marino   tree index1, index2;
1131e4b17023SJohn Marino   gcc_assert (t1 && t2
1132e4b17023SJohn Marino 	      && TREE_CODE (t1) == TREE_CODE (t2)
1133e4b17023SJohn Marino 	      && (TREE_CODE (t1) == BOUND_TEMPLATE_TEMPLATE_PARM
1134e4b17023SJohn Marino 		  || TREE_CODE (t1) == TEMPLATE_TEMPLATE_PARM
1135e4b17023SJohn Marino 		  || TREE_CODE (t1) == TEMPLATE_TYPE_PARM));
1136e4b17023SJohn Marino 
1137e4b17023SJohn Marino   index1 = TEMPLATE_TYPE_PARM_INDEX (TYPE_MAIN_VARIANT (t1));
1138e4b17023SJohn Marino   index2 = TEMPLATE_TYPE_PARM_INDEX (TYPE_MAIN_VARIANT (t2));
1139e4b17023SJohn Marino 
1140e4b17023SJohn Marino   /* Then compare their relative position.  */
1141e4b17023SJohn Marino   if (TEMPLATE_PARM_IDX (index1) != TEMPLATE_PARM_IDX (index2)
1142e4b17023SJohn Marino       || TEMPLATE_PARM_LEVEL (index1) != TEMPLATE_PARM_LEVEL (index2)
1143e4b17023SJohn Marino       || (TEMPLATE_PARM_PARAMETER_PACK (index1)
1144e4b17023SJohn Marino 	  != TEMPLATE_PARM_PARAMETER_PACK (index2)))
1145e4b17023SJohn Marino     return false;
1146e4b17023SJohn Marino 
1147e4b17023SJohn Marino   return true;
1148e4b17023SJohn Marino }
1149e4b17023SJohn Marino 
1150e4b17023SJohn Marino /* Subroutine in comptypes.  */
1151e4b17023SJohn Marino 
1152e4b17023SJohn Marino static bool
structural_comptypes(tree t1,tree t2,int strict)1153e4b17023SJohn Marino structural_comptypes (tree t1, tree t2, int strict)
1154e4b17023SJohn Marino {
1155e4b17023SJohn Marino   if (t1 == t2)
1156e4b17023SJohn Marino     return true;
1157e4b17023SJohn Marino 
1158e4b17023SJohn Marino   /* Suppress errors caused by previously reported errors.  */
1159e4b17023SJohn Marino   if (t1 == error_mark_node || t2 == error_mark_node)
1160e4b17023SJohn Marino     return false;
1161e4b17023SJohn Marino 
1162e4b17023SJohn Marino   gcc_assert (TYPE_P (t1) && TYPE_P (t2));
1163e4b17023SJohn Marino 
1164e4b17023SJohn Marino   /* TYPENAME_TYPEs should be resolved if the qualifying scope is the
1165e4b17023SJohn Marino      current instantiation.  */
1166e4b17023SJohn Marino   if (TREE_CODE (t1) == TYPENAME_TYPE)
1167e4b17023SJohn Marino     t1 = resolve_typename_type (t1, /*only_current_p=*/true);
1168e4b17023SJohn Marino 
1169e4b17023SJohn Marino   if (TREE_CODE (t2) == TYPENAME_TYPE)
1170e4b17023SJohn Marino     t2 = resolve_typename_type (t2, /*only_current_p=*/true);
1171e4b17023SJohn Marino 
1172e4b17023SJohn Marino   if (TYPE_PTRMEMFUNC_P (t1))
1173e4b17023SJohn Marino     t1 = TYPE_PTRMEMFUNC_FN_TYPE (t1);
1174e4b17023SJohn Marino   if (TYPE_PTRMEMFUNC_P (t2))
1175e4b17023SJohn Marino     t2 = TYPE_PTRMEMFUNC_FN_TYPE (t2);
1176e4b17023SJohn Marino 
1177e4b17023SJohn Marino   /* Different classes of types can't be compatible.  */
1178e4b17023SJohn Marino   if (TREE_CODE (t1) != TREE_CODE (t2))
1179e4b17023SJohn Marino     return false;
1180e4b17023SJohn Marino 
1181e4b17023SJohn Marino   /* Qualifiers must match.  For array types, we will check when we
1182e4b17023SJohn Marino      recur on the array element types.  */
1183e4b17023SJohn Marino   if (TREE_CODE (t1) != ARRAY_TYPE
1184e4b17023SJohn Marino       && cp_type_quals (t1) != cp_type_quals (t2))
1185e4b17023SJohn Marino     return false;
1186e4b17023SJohn Marino   if (TREE_CODE (t1) == FUNCTION_TYPE
1187e4b17023SJohn Marino       && type_memfn_quals (t1) != type_memfn_quals (t2))
1188e4b17023SJohn Marino     return false;
1189e4b17023SJohn Marino   if (TYPE_FOR_JAVA (t1) != TYPE_FOR_JAVA (t2))
1190e4b17023SJohn Marino     return false;
1191e4b17023SJohn Marino 
1192e4b17023SJohn Marino   /* Allow for two different type nodes which have essentially the same
1193e4b17023SJohn Marino      definition.  Note that we already checked for equality of the type
1194e4b17023SJohn Marino      qualifiers (just above).  */
1195e4b17023SJohn Marino 
1196e4b17023SJohn Marino   if (TREE_CODE (t1) != ARRAY_TYPE
1197e4b17023SJohn Marino       && TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
1198e4b17023SJohn Marino     return true;
1199e4b17023SJohn Marino 
1200e4b17023SJohn Marino 
1201e4b17023SJohn Marino   /* Compare the types.  Break out if they could be the same.  */
1202e4b17023SJohn Marino   switch (TREE_CODE (t1))
1203e4b17023SJohn Marino     {
1204e4b17023SJohn Marino     case VOID_TYPE:
1205e4b17023SJohn Marino     case BOOLEAN_TYPE:
1206e4b17023SJohn Marino       /* All void and bool types are the same.  */
1207e4b17023SJohn Marino       break;
1208e4b17023SJohn Marino 
1209e4b17023SJohn Marino     case INTEGER_TYPE:
1210e4b17023SJohn Marino     case FIXED_POINT_TYPE:
1211e4b17023SJohn Marino     case REAL_TYPE:
1212e4b17023SJohn Marino       /* With these nodes, we can't determine type equivalence by
1213e4b17023SJohn Marino 	 looking at what is stored in the nodes themselves, because
1214e4b17023SJohn Marino 	 two nodes might have different TYPE_MAIN_VARIANTs but still
1215e4b17023SJohn Marino 	 represent the same type.  For example, wchar_t and int could
1216e4b17023SJohn Marino 	 have the same properties (TYPE_PRECISION, TYPE_MIN_VALUE,
1217e4b17023SJohn Marino 	 TYPE_MAX_VALUE, etc.), but have different TYPE_MAIN_VARIANTs
1218e4b17023SJohn Marino 	 and are distinct types. On the other hand, int and the
1219e4b17023SJohn Marino 	 following typedef
1220e4b17023SJohn Marino 
1221e4b17023SJohn Marino            typedef int INT __attribute((may_alias));
1222e4b17023SJohn Marino 
1223e4b17023SJohn Marino 	 have identical properties, different TYPE_MAIN_VARIANTs, but
1224e4b17023SJohn Marino 	 represent the same type.  The canonical type system keeps
1225e4b17023SJohn Marino 	 track of equivalence in this case, so we fall back on it.  */
1226e4b17023SJohn Marino       return TYPE_CANONICAL (t1) == TYPE_CANONICAL (t2);
1227e4b17023SJohn Marino 
1228e4b17023SJohn Marino     case TEMPLATE_TEMPLATE_PARM:
1229e4b17023SJohn Marino     case BOUND_TEMPLATE_TEMPLATE_PARM:
1230e4b17023SJohn Marino       if (!comp_template_parms_position (t1, t2))
1231e4b17023SJohn Marino 	return false;
1232e4b17023SJohn Marino       if (!comp_template_parms
1233e4b17023SJohn Marino 	  (DECL_TEMPLATE_PARMS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (t1)),
1234e4b17023SJohn Marino 	   DECL_TEMPLATE_PARMS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (t2))))
1235e4b17023SJohn Marino 	return false;
1236e4b17023SJohn Marino       if (TREE_CODE (t1) == TEMPLATE_TEMPLATE_PARM)
1237e4b17023SJohn Marino 	break;
1238e4b17023SJohn Marino       /* Don't check inheritance.  */
1239e4b17023SJohn Marino       strict = COMPARE_STRICT;
1240e4b17023SJohn Marino       /* Fall through.  */
1241e4b17023SJohn Marino 
1242e4b17023SJohn Marino     case RECORD_TYPE:
1243e4b17023SJohn Marino     case UNION_TYPE:
1244e4b17023SJohn Marino       if (TYPE_TEMPLATE_INFO (t1) && TYPE_TEMPLATE_INFO (t2)
1245e4b17023SJohn Marino 	  && (TYPE_TI_TEMPLATE (t1) == TYPE_TI_TEMPLATE (t2)
1246e4b17023SJohn Marino 	      || TREE_CODE (t1) == BOUND_TEMPLATE_TEMPLATE_PARM)
1247e4b17023SJohn Marino 	  && comp_template_args (TYPE_TI_ARGS (t1), TYPE_TI_ARGS (t2)))
1248e4b17023SJohn Marino 	break;
1249e4b17023SJohn Marino 
1250e4b17023SJohn Marino       if ((strict & COMPARE_BASE) && DERIVED_FROM_P (t1, t2))
1251e4b17023SJohn Marino 	break;
1252e4b17023SJohn Marino       else if ((strict & COMPARE_DERIVED) && DERIVED_FROM_P (t2, t1))
1253e4b17023SJohn Marino 	break;
1254e4b17023SJohn Marino 
1255e4b17023SJohn Marino       return false;
1256e4b17023SJohn Marino 
1257e4b17023SJohn Marino     case OFFSET_TYPE:
1258e4b17023SJohn Marino       if (!comptypes (TYPE_OFFSET_BASETYPE (t1), TYPE_OFFSET_BASETYPE (t2),
1259e4b17023SJohn Marino 		      strict & ~COMPARE_REDECLARATION))
1260e4b17023SJohn Marino 	return false;
1261e4b17023SJohn Marino       if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
1262e4b17023SJohn Marino 	return false;
1263e4b17023SJohn Marino       break;
1264e4b17023SJohn Marino 
1265e4b17023SJohn Marino     case REFERENCE_TYPE:
1266e4b17023SJohn Marino       if (TYPE_REF_IS_RVALUE (t1) != TYPE_REF_IS_RVALUE (t2))
1267e4b17023SJohn Marino 	return false;
1268e4b17023SJohn Marino       /* fall through to checks for pointer types */
1269e4b17023SJohn Marino 
1270e4b17023SJohn Marino     case POINTER_TYPE:
1271e4b17023SJohn Marino       if (TYPE_MODE (t1) != TYPE_MODE (t2)
1272e4b17023SJohn Marino 	  || TYPE_REF_CAN_ALIAS_ALL (t1) != TYPE_REF_CAN_ALIAS_ALL (t2)
1273e4b17023SJohn Marino 	  || !same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
1274e4b17023SJohn Marino 	return false;
1275e4b17023SJohn Marino       break;
1276e4b17023SJohn Marino 
1277e4b17023SJohn Marino     case METHOD_TYPE:
1278e4b17023SJohn Marino     case FUNCTION_TYPE:
1279e4b17023SJohn Marino       if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
1280e4b17023SJohn Marino 	return false;
1281e4b17023SJohn Marino       if (!compparms (TYPE_ARG_TYPES (t1), TYPE_ARG_TYPES (t2)))
1282e4b17023SJohn Marino 	return false;
1283e4b17023SJohn Marino       break;
1284e4b17023SJohn Marino 
1285e4b17023SJohn Marino     case ARRAY_TYPE:
1286e4b17023SJohn Marino       /* Target types must match incl. qualifiers.  */
1287e4b17023SJohn Marino       if (!comp_array_types (t1, t2, !!(strict & COMPARE_REDECLARATION)))
1288e4b17023SJohn Marino 	return false;
1289e4b17023SJohn Marino       break;
1290e4b17023SJohn Marino 
1291e4b17023SJohn Marino     case TEMPLATE_TYPE_PARM:
1292e4b17023SJohn Marino       /* If T1 and T2 don't have the same relative position in their
1293e4b17023SJohn Marino 	 template parameters set, they can't be equal.  */
1294e4b17023SJohn Marino       if (!comp_template_parms_position (t1, t2))
1295e4b17023SJohn Marino 	return false;
1296e4b17023SJohn Marino       break;
1297e4b17023SJohn Marino 
1298e4b17023SJohn Marino     case TYPENAME_TYPE:
1299e4b17023SJohn Marino       if (!cp_tree_equal (TYPENAME_TYPE_FULLNAME (t1),
1300e4b17023SJohn Marino 			  TYPENAME_TYPE_FULLNAME (t2)))
1301e4b17023SJohn Marino 	return false;
1302e4b17023SJohn Marino       /* Qualifiers don't matter on scopes.  */
1303e4b17023SJohn Marino       if (!same_type_ignoring_top_level_qualifiers_p (TYPE_CONTEXT (t1),
1304e4b17023SJohn Marino 						      TYPE_CONTEXT (t2)))
1305e4b17023SJohn Marino 	return false;
1306e4b17023SJohn Marino       break;
1307e4b17023SJohn Marino 
1308e4b17023SJohn Marino     case UNBOUND_CLASS_TEMPLATE:
1309e4b17023SJohn Marino       if (!cp_tree_equal (TYPE_IDENTIFIER (t1), TYPE_IDENTIFIER (t2)))
1310e4b17023SJohn Marino 	return false;
1311e4b17023SJohn Marino       if (!same_type_p (TYPE_CONTEXT (t1), TYPE_CONTEXT (t2)))
1312e4b17023SJohn Marino 	return false;
1313e4b17023SJohn Marino       break;
1314e4b17023SJohn Marino 
1315e4b17023SJohn Marino     case COMPLEX_TYPE:
1316e4b17023SJohn Marino       if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
1317e4b17023SJohn Marino 	return false;
1318e4b17023SJohn Marino       break;
1319e4b17023SJohn Marino 
1320e4b17023SJohn Marino     case VECTOR_TYPE:
1321e4b17023SJohn Marino       if (TYPE_VECTOR_SUBPARTS (t1) != TYPE_VECTOR_SUBPARTS (t2)
1322e4b17023SJohn Marino 	  || !same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
1323e4b17023SJohn Marino 	return false;
1324e4b17023SJohn Marino       break;
1325e4b17023SJohn Marino 
1326e4b17023SJohn Marino     case TYPE_PACK_EXPANSION:
1327e4b17023SJohn Marino       return (same_type_p (PACK_EXPANSION_PATTERN (t1),
1328e4b17023SJohn Marino 			   PACK_EXPANSION_PATTERN (t2))
1329e4b17023SJohn Marino 	      && comp_template_args (PACK_EXPANSION_EXTRA_ARGS (t1),
1330e4b17023SJohn Marino 				     PACK_EXPANSION_EXTRA_ARGS (t2)));
1331e4b17023SJohn Marino 
1332e4b17023SJohn Marino     case DECLTYPE_TYPE:
1333e4b17023SJohn Marino       if (DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t1)
1334e4b17023SJohn Marino           != DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t2)
1335e4b17023SJohn Marino 	  || (DECLTYPE_FOR_LAMBDA_CAPTURE (t1)
1336e4b17023SJohn Marino 	      != DECLTYPE_FOR_LAMBDA_CAPTURE (t2))
1337e4b17023SJohn Marino 	  || (DECLTYPE_FOR_LAMBDA_PROXY (t1)
1338e4b17023SJohn Marino 	      != DECLTYPE_FOR_LAMBDA_PROXY (t2))
1339e4b17023SJohn Marino           || !cp_tree_equal (DECLTYPE_TYPE_EXPR (t1),
1340e4b17023SJohn Marino                              DECLTYPE_TYPE_EXPR (t2)))
1341e4b17023SJohn Marino         return false;
1342e4b17023SJohn Marino       break;
1343e4b17023SJohn Marino 
1344e4b17023SJohn Marino     case UNDERLYING_TYPE:
1345e4b17023SJohn Marino       return same_type_p (UNDERLYING_TYPE_TYPE (t1),
1346e4b17023SJohn Marino 			  UNDERLYING_TYPE_TYPE (t2));
1347e4b17023SJohn Marino 
1348e4b17023SJohn Marino     default:
1349e4b17023SJohn Marino       return false;
1350e4b17023SJohn Marino     }
1351e4b17023SJohn Marino 
1352e4b17023SJohn Marino   /* If we get here, we know that from a target independent POV the
1353e4b17023SJohn Marino      types are the same.  Make sure the target attributes are also
1354e4b17023SJohn Marino      the same.  */
1355e4b17023SJohn Marino   return comp_type_attributes (t1, t2);
1356e4b17023SJohn Marino }
1357e4b17023SJohn Marino 
1358e4b17023SJohn Marino /* Return true if T1 and T2 are related as allowed by STRICT.  STRICT
1359e4b17023SJohn Marino    is a bitwise-or of the COMPARE_* flags.  */
1360e4b17023SJohn Marino 
1361e4b17023SJohn Marino bool
comptypes(tree t1,tree t2,int strict)1362e4b17023SJohn Marino comptypes (tree t1, tree t2, int strict)
1363e4b17023SJohn Marino {
1364e4b17023SJohn Marino   if (strict == COMPARE_STRICT)
1365e4b17023SJohn Marino     {
1366e4b17023SJohn Marino       if (t1 == t2)
1367e4b17023SJohn Marino 	return true;
1368e4b17023SJohn Marino 
1369e4b17023SJohn Marino       if (t1 == error_mark_node || t2 == error_mark_node)
1370e4b17023SJohn Marino 	return false;
1371e4b17023SJohn Marino 
1372e4b17023SJohn Marino       if (TYPE_STRUCTURAL_EQUALITY_P (t1) || TYPE_STRUCTURAL_EQUALITY_P (t2))
1373e4b17023SJohn Marino 	/* At least one of the types requires structural equality, so
1374e4b17023SJohn Marino 	   perform a deep check. */
1375e4b17023SJohn Marino 	return structural_comptypes (t1, t2, strict);
1376e4b17023SJohn Marino 
1377e4b17023SJohn Marino #ifdef ENABLE_CHECKING
1378e4b17023SJohn Marino       if (USE_CANONICAL_TYPES)
1379e4b17023SJohn Marino 	{
1380e4b17023SJohn Marino 	  bool result = structural_comptypes (t1, t2, strict);
1381e4b17023SJohn Marino 
1382e4b17023SJohn Marino 	  if (result && TYPE_CANONICAL (t1) != TYPE_CANONICAL (t2))
1383e4b17023SJohn Marino 	    /* The two types are structurally equivalent, but their
1384e4b17023SJohn Marino 	       canonical types were different. This is a failure of the
1385e4b17023SJohn Marino 	       canonical type propagation code.*/
1386e4b17023SJohn Marino 	    internal_error
1387e4b17023SJohn Marino 	      ("canonical types differ for identical types %T and %T",
1388e4b17023SJohn Marino 	       t1, t2);
1389e4b17023SJohn Marino 	  else if (!result && TYPE_CANONICAL (t1) == TYPE_CANONICAL (t2))
1390e4b17023SJohn Marino 	    /* Two types are structurally different, but the canonical
1391e4b17023SJohn Marino 	       types are the same. This means we were over-eager in
1392e4b17023SJohn Marino 	       assigning canonical types. */
1393e4b17023SJohn Marino 	    internal_error
1394e4b17023SJohn Marino 	      ("same canonical type node for different types %T and %T",
1395e4b17023SJohn Marino 	       t1, t2);
1396e4b17023SJohn Marino 
1397e4b17023SJohn Marino 	  return result;
1398e4b17023SJohn Marino 	}
1399e4b17023SJohn Marino #else
1400e4b17023SJohn Marino       if (USE_CANONICAL_TYPES)
1401e4b17023SJohn Marino 	return TYPE_CANONICAL (t1) == TYPE_CANONICAL (t2);
1402e4b17023SJohn Marino #endif
1403e4b17023SJohn Marino       else
1404e4b17023SJohn Marino 	return structural_comptypes (t1, t2, strict);
1405e4b17023SJohn Marino     }
1406e4b17023SJohn Marino   else if (strict == COMPARE_STRUCTURAL)
1407e4b17023SJohn Marino     return structural_comptypes (t1, t2, COMPARE_STRICT);
1408e4b17023SJohn Marino   else
1409e4b17023SJohn Marino     return structural_comptypes (t1, t2, strict);
1410e4b17023SJohn Marino }
1411e4b17023SJohn Marino 
1412e4b17023SJohn Marino /* Returns nonzero iff TYPE1 and TYPE2 are the same type, ignoring
1413e4b17023SJohn Marino    top-level qualifiers.  */
1414e4b17023SJohn Marino 
1415e4b17023SJohn Marino bool
same_type_ignoring_top_level_qualifiers_p(tree type1,tree type2)1416e4b17023SJohn Marino same_type_ignoring_top_level_qualifiers_p (tree type1, tree type2)
1417e4b17023SJohn Marino {
1418e4b17023SJohn Marino   if (type1 == error_mark_node || type2 == error_mark_node)
1419e4b17023SJohn Marino     return false;
1420e4b17023SJohn Marino 
1421e4b17023SJohn Marino   return same_type_p (TYPE_MAIN_VARIANT (type1), TYPE_MAIN_VARIANT (type2));
1422e4b17023SJohn Marino }
1423e4b17023SJohn Marino 
1424e4b17023SJohn Marino /* Returns 1 if TYPE1 is at least as qualified as TYPE2.  */
1425e4b17023SJohn Marino 
1426e4b17023SJohn Marino bool
at_least_as_qualified_p(const_tree type1,const_tree type2)1427e4b17023SJohn Marino at_least_as_qualified_p (const_tree type1, const_tree type2)
1428e4b17023SJohn Marino {
1429e4b17023SJohn Marino   int q1 = cp_type_quals (type1);
1430e4b17023SJohn Marino   int q2 = cp_type_quals (type2);
1431e4b17023SJohn Marino 
1432e4b17023SJohn Marino   /* All qualifiers for TYPE2 must also appear in TYPE1.  */
1433e4b17023SJohn Marino   return (q1 & q2) == q2;
1434e4b17023SJohn Marino }
1435e4b17023SJohn Marino 
1436e4b17023SJohn Marino /* Returns 1 if TYPE1 is more cv-qualified than TYPE2, -1 if TYPE2 is
1437e4b17023SJohn Marino    more cv-qualified that TYPE1, and 0 otherwise.  */
1438e4b17023SJohn Marino 
1439e4b17023SJohn Marino int
comp_cv_qualification(const_tree type1,const_tree type2)1440e4b17023SJohn Marino comp_cv_qualification (const_tree type1, const_tree type2)
1441e4b17023SJohn Marino {
1442e4b17023SJohn Marino   int q1 = cp_type_quals (type1);
1443e4b17023SJohn Marino   int q2 = cp_type_quals (type2);
1444e4b17023SJohn Marino 
1445e4b17023SJohn Marino   if (q1 == q2)
1446e4b17023SJohn Marino     return 0;
1447e4b17023SJohn Marino 
1448e4b17023SJohn Marino   if ((q1 & q2) == q2)
1449e4b17023SJohn Marino     return 1;
1450e4b17023SJohn Marino   else if ((q1 & q2) == q1)
1451e4b17023SJohn Marino     return -1;
1452e4b17023SJohn Marino 
1453e4b17023SJohn Marino   return 0;
1454e4b17023SJohn Marino }
1455e4b17023SJohn Marino 
1456e4b17023SJohn Marino /* Returns 1 if the cv-qualification signature of TYPE1 is a proper
1457e4b17023SJohn Marino    subset of the cv-qualification signature of TYPE2, and the types
1458e4b17023SJohn Marino    are similar.  Returns -1 if the other way 'round, and 0 otherwise.  */
1459e4b17023SJohn Marino 
1460e4b17023SJohn Marino int
comp_cv_qual_signature(tree type1,tree type2)1461e4b17023SJohn Marino comp_cv_qual_signature (tree type1, tree type2)
1462e4b17023SJohn Marino {
1463e4b17023SJohn Marino   if (comp_ptr_ttypes_real (type2, type1, -1))
1464e4b17023SJohn Marino     return 1;
1465e4b17023SJohn Marino   else if (comp_ptr_ttypes_real (type1, type2, -1))
1466e4b17023SJohn Marino     return -1;
1467e4b17023SJohn Marino   else
1468e4b17023SJohn Marino     return 0;
1469e4b17023SJohn Marino }
1470e4b17023SJohn Marino 
1471e4b17023SJohn Marino /* Subroutines of `comptypes'.  */
1472e4b17023SJohn Marino 
1473e4b17023SJohn Marino /* Return true if two parameter type lists PARMS1 and PARMS2 are
1474e4b17023SJohn Marino    equivalent in the sense that functions with those parameter types
1475e4b17023SJohn Marino    can have equivalent types.  The two lists must be equivalent,
1476e4b17023SJohn Marino    element by element.  */
1477e4b17023SJohn Marino 
1478e4b17023SJohn Marino bool
compparms(const_tree parms1,const_tree parms2)1479e4b17023SJohn Marino compparms (const_tree parms1, const_tree parms2)
1480e4b17023SJohn Marino {
1481e4b17023SJohn Marino   const_tree t1, t2;
1482e4b17023SJohn Marino 
1483e4b17023SJohn Marino   /* An unspecified parmlist matches any specified parmlist
1484e4b17023SJohn Marino      whose argument types don't need default promotions.  */
1485e4b17023SJohn Marino 
1486e4b17023SJohn Marino   for (t1 = parms1, t2 = parms2;
1487e4b17023SJohn Marino        t1 || t2;
1488e4b17023SJohn Marino        t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2))
1489e4b17023SJohn Marino     {
1490e4b17023SJohn Marino       /* If one parmlist is shorter than the other,
1491e4b17023SJohn Marino 	 they fail to match.  */
1492e4b17023SJohn Marino       if (!t1 || !t2)
1493e4b17023SJohn Marino 	return false;
1494e4b17023SJohn Marino       if (!same_type_p (TREE_VALUE (t1), TREE_VALUE (t2)))
1495e4b17023SJohn Marino 	return false;
1496e4b17023SJohn Marino     }
1497e4b17023SJohn Marino   return true;
1498e4b17023SJohn Marino }
1499e4b17023SJohn Marino 
1500e4b17023SJohn Marino 
1501e4b17023SJohn Marino /* Process a sizeof or alignof expression where the operand is a
1502e4b17023SJohn Marino    type.  */
1503e4b17023SJohn Marino 
1504e4b17023SJohn Marino tree
cxx_sizeof_or_alignof_type(tree type,enum tree_code op,bool complain)1505e4b17023SJohn Marino cxx_sizeof_or_alignof_type (tree type, enum tree_code op, bool complain)
1506e4b17023SJohn Marino {
1507e4b17023SJohn Marino   tree value;
1508e4b17023SJohn Marino   bool dependent_p;
1509e4b17023SJohn Marino 
1510e4b17023SJohn Marino   gcc_assert (op == SIZEOF_EXPR || op == ALIGNOF_EXPR);
1511e4b17023SJohn Marino   if (type == error_mark_node)
1512e4b17023SJohn Marino     return error_mark_node;
1513e4b17023SJohn Marino 
1514e4b17023SJohn Marino   type = non_reference (type);
1515e4b17023SJohn Marino   if (TREE_CODE (type) == METHOD_TYPE)
1516e4b17023SJohn Marino     {
1517e4b17023SJohn Marino       if (complain)
1518e4b17023SJohn Marino 	pedwarn (input_location, pedantic ? OPT_pedantic : OPT_Wpointer_arith,
1519e4b17023SJohn Marino 		 "invalid application of %qs to a member function",
1520e4b17023SJohn Marino 		 operator_name_info[(int) op].name);
1521e4b17023SJohn Marino       value = size_one_node;
1522e4b17023SJohn Marino     }
1523e4b17023SJohn Marino 
1524e4b17023SJohn Marino   dependent_p = dependent_type_p (type);
1525e4b17023SJohn Marino   if (!dependent_p)
1526e4b17023SJohn Marino     complete_type (type);
1527e4b17023SJohn Marino   if (dependent_p
1528e4b17023SJohn Marino       /* VLA types will have a non-constant size.  In the body of an
1529e4b17023SJohn Marino 	 uninstantiated template, we don't need to try to compute the
1530e4b17023SJohn Marino 	 value, because the sizeof expression is not an integral
1531e4b17023SJohn Marino 	 constant expression in that case.  And, if we do try to
1532e4b17023SJohn Marino 	 compute the value, we'll likely end up with SAVE_EXPRs, which
1533e4b17023SJohn Marino 	 the template substitution machinery does not expect to see.  */
1534e4b17023SJohn Marino       || (processing_template_decl
1535e4b17023SJohn Marino 	  && COMPLETE_TYPE_P (type)
1536e4b17023SJohn Marino 	  && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST))
1537e4b17023SJohn Marino     {
1538e4b17023SJohn Marino       value = build_min (op, size_type_node, type);
1539e4b17023SJohn Marino       TREE_READONLY (value) = 1;
1540e4b17023SJohn Marino       return value;
1541e4b17023SJohn Marino     }
1542e4b17023SJohn Marino 
1543e4b17023SJohn Marino   return c_sizeof_or_alignof_type (input_location, complete_type (type),
1544e4b17023SJohn Marino 				   op == SIZEOF_EXPR,
1545e4b17023SJohn Marino 				   complain);
1546e4b17023SJohn Marino }
1547e4b17023SJohn Marino 
1548e4b17023SJohn Marino /* Return the size of the type, without producing any warnings for
1549e4b17023SJohn Marino    types whose size cannot be taken.  This routine should be used only
1550e4b17023SJohn Marino    in some other routine that has already produced a diagnostic about
1551e4b17023SJohn Marino    using the size of such a type.  */
1552e4b17023SJohn Marino tree
cxx_sizeof_nowarn(tree type)1553e4b17023SJohn Marino cxx_sizeof_nowarn (tree type)
1554e4b17023SJohn Marino {
1555e4b17023SJohn Marino   if (TREE_CODE (type) == FUNCTION_TYPE
1556e4b17023SJohn Marino       || TREE_CODE (type) == VOID_TYPE
1557e4b17023SJohn Marino       || TREE_CODE (type) == ERROR_MARK)
1558e4b17023SJohn Marino     return size_one_node;
1559e4b17023SJohn Marino   else if (!COMPLETE_TYPE_P (type))
1560e4b17023SJohn Marino     return size_zero_node;
1561e4b17023SJohn Marino   else
1562e4b17023SJohn Marino     return cxx_sizeof_or_alignof_type (type, SIZEOF_EXPR, false);
1563e4b17023SJohn Marino }
1564e4b17023SJohn Marino 
1565e4b17023SJohn Marino /* Process a sizeof expression where the operand is an expression.  */
1566e4b17023SJohn Marino 
1567e4b17023SJohn Marino static tree
cxx_sizeof_expr(tree e,tsubst_flags_t complain)1568e4b17023SJohn Marino cxx_sizeof_expr (tree e, tsubst_flags_t complain)
1569e4b17023SJohn Marino {
1570e4b17023SJohn Marino   if (e == error_mark_node)
1571e4b17023SJohn Marino     return error_mark_node;
1572e4b17023SJohn Marino 
1573e4b17023SJohn Marino   if (processing_template_decl)
1574e4b17023SJohn Marino     {
1575e4b17023SJohn Marino       e = build_min (SIZEOF_EXPR, size_type_node, e);
1576e4b17023SJohn Marino       TREE_SIDE_EFFECTS (e) = 0;
1577e4b17023SJohn Marino       TREE_READONLY (e) = 1;
1578e4b17023SJohn Marino 
1579e4b17023SJohn Marino       return e;
1580e4b17023SJohn Marino     }
1581e4b17023SJohn Marino 
1582e4b17023SJohn Marino   /* To get the size of a static data member declared as an array of
1583e4b17023SJohn Marino      unknown bound, we need to instantiate it.  */
1584e4b17023SJohn Marino   if (TREE_CODE (e) == VAR_DECL
1585e4b17023SJohn Marino       && VAR_HAD_UNKNOWN_BOUND (e)
1586e4b17023SJohn Marino       && DECL_TEMPLATE_INSTANTIATION (e))
1587e4b17023SJohn Marino     instantiate_decl (e, /*defer_ok*/true, /*expl_inst_mem*/false);
1588e4b17023SJohn Marino 
1589e4b17023SJohn Marino   e = mark_type_use (e);
1590e4b17023SJohn Marino 
1591e4b17023SJohn Marino   if (TREE_CODE (e) == COMPONENT_REF
1592e4b17023SJohn Marino       && TREE_CODE (TREE_OPERAND (e, 1)) == FIELD_DECL
1593e4b17023SJohn Marino       && DECL_C_BIT_FIELD (TREE_OPERAND (e, 1)))
1594e4b17023SJohn Marino     {
1595e4b17023SJohn Marino       if (complain & tf_error)
1596e4b17023SJohn Marino         error ("invalid application of %<sizeof%> to a bit-field");
1597e4b17023SJohn Marino       else
1598e4b17023SJohn Marino         return error_mark_node;
1599e4b17023SJohn Marino       e = char_type_node;
1600e4b17023SJohn Marino     }
1601e4b17023SJohn Marino   else if (is_overloaded_fn (e))
1602e4b17023SJohn Marino     {
1603e4b17023SJohn Marino       if (complain & tf_error)
1604e4b17023SJohn Marino         permerror (input_location, "ISO C++ forbids applying %<sizeof%> to an expression of "
1605e4b17023SJohn Marino                    "function type");
1606e4b17023SJohn Marino       else
1607e4b17023SJohn Marino         return error_mark_node;
1608e4b17023SJohn Marino       e = char_type_node;
1609e4b17023SJohn Marino     }
1610e4b17023SJohn Marino   else if (type_unknown_p (e))
1611e4b17023SJohn Marino     {
1612e4b17023SJohn Marino       if (complain & tf_error)
1613e4b17023SJohn Marino         cxx_incomplete_type_error (e, TREE_TYPE (e));
1614e4b17023SJohn Marino       else
1615e4b17023SJohn Marino         return error_mark_node;
1616e4b17023SJohn Marino       e = char_type_node;
1617e4b17023SJohn Marino     }
1618e4b17023SJohn Marino   else
1619e4b17023SJohn Marino     e = TREE_TYPE (e);
1620e4b17023SJohn Marino 
1621e4b17023SJohn Marino   return cxx_sizeof_or_alignof_type (e, SIZEOF_EXPR, complain & tf_error);
1622e4b17023SJohn Marino }
1623e4b17023SJohn Marino 
1624e4b17023SJohn Marino /* Implement the __alignof keyword: Return the minimum required
1625e4b17023SJohn Marino    alignment of E, measured in bytes.  For VAR_DECL's and
1626e4b17023SJohn Marino    FIELD_DECL's return DECL_ALIGN (which can be set from an
1627e4b17023SJohn Marino    "aligned" __attribute__ specification).  */
1628e4b17023SJohn Marino 
1629e4b17023SJohn Marino static tree
cxx_alignof_expr(tree e,tsubst_flags_t complain)1630e4b17023SJohn Marino cxx_alignof_expr (tree e, tsubst_flags_t complain)
1631e4b17023SJohn Marino {
1632e4b17023SJohn Marino   tree t;
1633e4b17023SJohn Marino 
1634e4b17023SJohn Marino   if (e == error_mark_node)
1635e4b17023SJohn Marino     return error_mark_node;
1636e4b17023SJohn Marino 
1637e4b17023SJohn Marino   if (processing_template_decl)
1638e4b17023SJohn Marino     {
1639e4b17023SJohn Marino       e = build_min (ALIGNOF_EXPR, size_type_node, e);
1640e4b17023SJohn Marino       TREE_SIDE_EFFECTS (e) = 0;
1641e4b17023SJohn Marino       TREE_READONLY (e) = 1;
1642e4b17023SJohn Marino 
1643e4b17023SJohn Marino       return e;
1644e4b17023SJohn Marino     }
1645e4b17023SJohn Marino 
1646e4b17023SJohn Marino   e = mark_type_use (e);
1647e4b17023SJohn Marino 
1648e4b17023SJohn Marino   if (TREE_CODE (e) == VAR_DECL)
1649e4b17023SJohn Marino     t = size_int (DECL_ALIGN_UNIT (e));
1650e4b17023SJohn Marino   else if (TREE_CODE (e) == COMPONENT_REF
1651e4b17023SJohn Marino 	   && TREE_CODE (TREE_OPERAND (e, 1)) == FIELD_DECL
1652e4b17023SJohn Marino 	   && DECL_C_BIT_FIELD (TREE_OPERAND (e, 1)))
1653e4b17023SJohn Marino     {
1654e4b17023SJohn Marino       if (complain & tf_error)
1655e4b17023SJohn Marino         error ("invalid application of %<__alignof%> to a bit-field");
1656e4b17023SJohn Marino       else
1657e4b17023SJohn Marino         return error_mark_node;
1658e4b17023SJohn Marino       t = size_one_node;
1659e4b17023SJohn Marino     }
1660e4b17023SJohn Marino   else if (TREE_CODE (e) == COMPONENT_REF
1661e4b17023SJohn Marino 	   && TREE_CODE (TREE_OPERAND (e, 1)) == FIELD_DECL)
1662e4b17023SJohn Marino     t = size_int (DECL_ALIGN_UNIT (TREE_OPERAND (e, 1)));
1663e4b17023SJohn Marino   else if (is_overloaded_fn (e))
1664e4b17023SJohn Marino     {
1665e4b17023SJohn Marino       if (complain & tf_error)
1666e4b17023SJohn Marino         permerror (input_location, "ISO C++ forbids applying %<__alignof%> to an expression of "
1667e4b17023SJohn Marino                    "function type");
1668e4b17023SJohn Marino       else
1669e4b17023SJohn Marino         return error_mark_node;
1670e4b17023SJohn Marino       if (TREE_CODE (e) == FUNCTION_DECL)
1671e4b17023SJohn Marino 	t = size_int (DECL_ALIGN_UNIT (e));
1672e4b17023SJohn Marino       else
1673e4b17023SJohn Marino 	t = size_one_node;
1674e4b17023SJohn Marino     }
1675e4b17023SJohn Marino   else if (type_unknown_p (e))
1676e4b17023SJohn Marino     {
1677e4b17023SJohn Marino       if (complain & tf_error)
1678e4b17023SJohn Marino         cxx_incomplete_type_error (e, TREE_TYPE (e));
1679e4b17023SJohn Marino       else
1680e4b17023SJohn Marino         return error_mark_node;
1681e4b17023SJohn Marino       t = size_one_node;
1682e4b17023SJohn Marino     }
1683e4b17023SJohn Marino   else
1684e4b17023SJohn Marino     return cxx_sizeof_or_alignof_type (TREE_TYPE (e), ALIGNOF_EXPR,
1685e4b17023SJohn Marino                                        complain & tf_error);
1686e4b17023SJohn Marino 
1687e4b17023SJohn Marino   return fold_convert (size_type_node, t);
1688e4b17023SJohn Marino }
1689e4b17023SJohn Marino 
1690e4b17023SJohn Marino /* Process a sizeof or alignof expression E with code OP where the operand
1691e4b17023SJohn Marino    is an expression.  */
1692e4b17023SJohn Marino 
1693e4b17023SJohn Marino tree
cxx_sizeof_or_alignof_expr(tree e,enum tree_code op,bool complain)1694e4b17023SJohn Marino cxx_sizeof_or_alignof_expr (tree e, enum tree_code op, bool complain)
1695e4b17023SJohn Marino {
1696e4b17023SJohn Marino   if (op == SIZEOF_EXPR)
1697e4b17023SJohn Marino     return cxx_sizeof_expr (e, complain? tf_warning_or_error : tf_none);
1698e4b17023SJohn Marino   else
1699e4b17023SJohn Marino     return cxx_alignof_expr (e, complain? tf_warning_or_error : tf_none);
1700e4b17023SJohn Marino }
1701e4b17023SJohn Marino 
1702e4b17023SJohn Marino /* EXPR is being used in a context that is not a function call.
1703e4b17023SJohn Marino    Enforce:
1704e4b17023SJohn Marino 
1705e4b17023SJohn Marino      [expr.ref]
1706e4b17023SJohn Marino 
1707e4b17023SJohn Marino      The expression can be used only as the left-hand operand of a
1708e4b17023SJohn Marino      member function call.
1709e4b17023SJohn Marino 
1710e4b17023SJohn Marino      [expr.mptr.operator]
1711e4b17023SJohn Marino 
1712e4b17023SJohn Marino      If the result of .* or ->* is a function, then that result can be
1713e4b17023SJohn Marino      used only as the operand for the function call operator ().
1714e4b17023SJohn Marino 
1715e4b17023SJohn Marino    by issuing an error message if appropriate.  Returns true iff EXPR
1716e4b17023SJohn Marino    violates these rules.  */
1717e4b17023SJohn Marino 
1718e4b17023SJohn Marino bool
invalid_nonstatic_memfn_p(const_tree expr,tsubst_flags_t complain)1719e4b17023SJohn Marino invalid_nonstatic_memfn_p (const_tree expr, tsubst_flags_t complain)
1720e4b17023SJohn Marino {
1721e4b17023SJohn Marino   if (expr && DECL_NONSTATIC_MEMBER_FUNCTION_P (expr))
1722e4b17023SJohn Marino     {
1723e4b17023SJohn Marino       if (complain & tf_error)
1724e4b17023SJohn Marino         error ("invalid use of non-static member function");
1725e4b17023SJohn Marino       return true;
1726e4b17023SJohn Marino     }
1727e4b17023SJohn Marino   return false;
1728e4b17023SJohn Marino }
1729e4b17023SJohn Marino 
1730e4b17023SJohn Marino /* If EXP is a reference to a bitfield, and the type of EXP does not
1731e4b17023SJohn Marino    match the declared type of the bitfield, return the declared type
1732e4b17023SJohn Marino    of the bitfield.  Otherwise, return NULL_TREE.  */
1733e4b17023SJohn Marino 
1734e4b17023SJohn Marino tree
is_bitfield_expr_with_lowered_type(const_tree exp)1735e4b17023SJohn Marino is_bitfield_expr_with_lowered_type (const_tree exp)
1736e4b17023SJohn Marino {
1737e4b17023SJohn Marino   switch (TREE_CODE (exp))
1738e4b17023SJohn Marino     {
1739e4b17023SJohn Marino     case COND_EXPR:
1740e4b17023SJohn Marino       if (!is_bitfield_expr_with_lowered_type (TREE_OPERAND (exp, 1)
1741e4b17023SJohn Marino 					       ? TREE_OPERAND (exp, 1)
1742e4b17023SJohn Marino 					       : TREE_OPERAND (exp, 0)))
1743e4b17023SJohn Marino 	return NULL_TREE;
1744e4b17023SJohn Marino       return is_bitfield_expr_with_lowered_type (TREE_OPERAND (exp, 2));
1745e4b17023SJohn Marino 
1746e4b17023SJohn Marino     case COMPOUND_EXPR:
1747e4b17023SJohn Marino       return is_bitfield_expr_with_lowered_type (TREE_OPERAND (exp, 1));
1748e4b17023SJohn Marino 
1749e4b17023SJohn Marino     case MODIFY_EXPR:
1750e4b17023SJohn Marino     case SAVE_EXPR:
1751e4b17023SJohn Marino       return is_bitfield_expr_with_lowered_type (TREE_OPERAND (exp, 0));
1752e4b17023SJohn Marino 
1753e4b17023SJohn Marino     case COMPONENT_REF:
1754e4b17023SJohn Marino       {
1755e4b17023SJohn Marino 	tree field;
1756e4b17023SJohn Marino 
1757e4b17023SJohn Marino 	field = TREE_OPERAND (exp, 1);
1758e4b17023SJohn Marino 	if (TREE_CODE (field) != FIELD_DECL || !DECL_BIT_FIELD_TYPE (field))
1759e4b17023SJohn Marino 	  return NULL_TREE;
1760e4b17023SJohn Marino 	if (same_type_ignoring_top_level_qualifiers_p
1761e4b17023SJohn Marino 	    (TREE_TYPE (exp), DECL_BIT_FIELD_TYPE (field)))
1762e4b17023SJohn Marino 	  return NULL_TREE;
1763e4b17023SJohn Marino 	return DECL_BIT_FIELD_TYPE (field);
1764e4b17023SJohn Marino       }
1765e4b17023SJohn Marino 
1766e4b17023SJohn Marino     CASE_CONVERT:
1767e4b17023SJohn Marino       if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (exp, 0)))
1768e4b17023SJohn Marino 	  == TYPE_MAIN_VARIANT (TREE_TYPE (exp)))
1769e4b17023SJohn Marino 	return is_bitfield_expr_with_lowered_type (TREE_OPERAND (exp, 0));
1770e4b17023SJohn Marino       /* Fallthrough.  */
1771e4b17023SJohn Marino 
1772e4b17023SJohn Marino     default:
1773e4b17023SJohn Marino       return NULL_TREE;
1774e4b17023SJohn Marino     }
1775e4b17023SJohn Marino }
1776e4b17023SJohn Marino 
1777e4b17023SJohn Marino /* Like is_bitfield_with_lowered_type, except that if EXP is not a
1778e4b17023SJohn Marino    bitfield with a lowered type, the type of EXP is returned, rather
1779e4b17023SJohn Marino    than NULL_TREE.  */
1780e4b17023SJohn Marino 
1781e4b17023SJohn Marino tree
unlowered_expr_type(const_tree exp)1782e4b17023SJohn Marino unlowered_expr_type (const_tree exp)
1783e4b17023SJohn Marino {
1784e4b17023SJohn Marino   tree type;
1785e4b17023SJohn Marino   tree etype = TREE_TYPE (exp);
1786e4b17023SJohn Marino 
1787e4b17023SJohn Marino   type = is_bitfield_expr_with_lowered_type (exp);
1788e4b17023SJohn Marino   if (type)
1789e4b17023SJohn Marino     type = cp_build_qualified_type (type, cp_type_quals (etype));
1790e4b17023SJohn Marino   else
1791e4b17023SJohn Marino     type = etype;
1792e4b17023SJohn Marino 
1793e4b17023SJohn Marino   return type;
1794e4b17023SJohn Marino }
1795e4b17023SJohn Marino 
1796e4b17023SJohn Marino /* Perform the conversions in [expr] that apply when an lvalue appears
1797e4b17023SJohn Marino    in an rvalue context: the lvalue-to-rvalue, array-to-pointer, and
1798e4b17023SJohn Marino    function-to-pointer conversions.  In addition, manifest constants
1799e4b17023SJohn Marino    are replaced by their values, and bitfield references are converted
1800e4b17023SJohn Marino    to their declared types. Note that this function does not perform the
1801e4b17023SJohn Marino    lvalue-to-rvalue conversion for class types. If you need that conversion
1802e4b17023SJohn Marino    to for class types, then you probably need to use force_rvalue.
1803e4b17023SJohn Marino 
1804e4b17023SJohn Marino    Although the returned value is being used as an rvalue, this
1805e4b17023SJohn Marino    function does not wrap the returned expression in a
1806e4b17023SJohn Marino    NON_LVALUE_EXPR; the caller is expected to be mindful of the fact
1807e4b17023SJohn Marino    that the return value is no longer an lvalue.  */
1808e4b17023SJohn Marino 
1809e4b17023SJohn Marino tree
decay_conversion(tree exp)1810e4b17023SJohn Marino decay_conversion (tree exp)
1811e4b17023SJohn Marino {
1812e4b17023SJohn Marino   tree type;
1813e4b17023SJohn Marino   enum tree_code code;
1814e4b17023SJohn Marino 
1815e4b17023SJohn Marino   type = TREE_TYPE (exp);
1816e4b17023SJohn Marino   if (type == error_mark_node)
1817e4b17023SJohn Marino     return error_mark_node;
1818e4b17023SJohn Marino 
1819e4b17023SJohn Marino   exp = mark_rvalue_use (exp);
1820e4b17023SJohn Marino 
1821e4b17023SJohn Marino   exp = resolve_nondeduced_context (exp);
1822e4b17023SJohn Marino   if (type_unknown_p (exp))
1823e4b17023SJohn Marino     {
1824e4b17023SJohn Marino       cxx_incomplete_type_error (exp, TREE_TYPE (exp));
1825e4b17023SJohn Marino       return error_mark_node;
1826e4b17023SJohn Marino     }
1827e4b17023SJohn Marino 
1828e4b17023SJohn Marino   /* FIXME remove? at least need to remember that this isn't really a
1829e4b17023SJohn Marino      constant expression if EXP isn't decl_constant_var_p, like with
1830e4b17023SJohn Marino      C_MAYBE_CONST_EXPR.  */
1831e4b17023SJohn Marino   exp = decl_constant_value_safe (exp);
1832e4b17023SJohn Marino   if (error_operand_p (exp))
1833e4b17023SJohn Marino     return error_mark_node;
1834e4b17023SJohn Marino 
1835e4b17023SJohn Marino   if (NULLPTR_TYPE_P (type) && !TREE_SIDE_EFFECTS (exp))
1836e4b17023SJohn Marino     return nullptr_node;
1837e4b17023SJohn Marino 
1838e4b17023SJohn Marino   /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
1839e4b17023SJohn Marino      Leave such NOP_EXPRs, since RHS is being used in non-lvalue context.  */
1840e4b17023SJohn Marino   code = TREE_CODE (type);
1841e4b17023SJohn Marino   if (code == VOID_TYPE)
1842e4b17023SJohn Marino     {
1843e4b17023SJohn Marino       error ("void value not ignored as it ought to be");
1844e4b17023SJohn Marino       return error_mark_node;
1845e4b17023SJohn Marino     }
1846e4b17023SJohn Marino   if (invalid_nonstatic_memfn_p (exp, tf_warning_or_error))
1847e4b17023SJohn Marino     return error_mark_node;
1848e4b17023SJohn Marino   if (code == FUNCTION_TYPE || is_overloaded_fn (exp))
1849e4b17023SJohn Marino     return cp_build_addr_expr (exp, tf_warning_or_error);
1850e4b17023SJohn Marino   if (code == ARRAY_TYPE)
1851e4b17023SJohn Marino     {
1852e4b17023SJohn Marino       tree adr;
1853e4b17023SJohn Marino       tree ptrtype;
1854e4b17023SJohn Marino 
1855e4b17023SJohn Marino       if (TREE_CODE (exp) == INDIRECT_REF)
1856e4b17023SJohn Marino 	return build_nop (build_pointer_type (TREE_TYPE (type)),
1857e4b17023SJohn Marino 			  TREE_OPERAND (exp, 0));
1858e4b17023SJohn Marino 
1859e4b17023SJohn Marino       if (TREE_CODE (exp) == COMPOUND_EXPR)
1860e4b17023SJohn Marino 	{
1861e4b17023SJohn Marino 	  tree op1 = decay_conversion (TREE_OPERAND (exp, 1));
1862e4b17023SJohn Marino 	  return build2 (COMPOUND_EXPR, TREE_TYPE (op1),
1863e4b17023SJohn Marino 			 TREE_OPERAND (exp, 0), op1);
1864e4b17023SJohn Marino 	}
1865e4b17023SJohn Marino 
1866e4b17023SJohn Marino       if (!lvalue_p (exp)
1867e4b17023SJohn Marino 	  && ! (TREE_CODE (exp) == CONSTRUCTOR && TREE_STATIC (exp)))
1868e4b17023SJohn Marino 	{
1869e4b17023SJohn Marino 	  error ("invalid use of non-lvalue array");
1870e4b17023SJohn Marino 	  return error_mark_node;
1871e4b17023SJohn Marino 	}
1872e4b17023SJohn Marino 
1873e4b17023SJohn Marino       /* Don't let an array compound literal decay to a pointer.  It can
1874e4b17023SJohn Marino 	 still be used to initialize an array or bind to a reference.  */
1875e4b17023SJohn Marino       if (TREE_CODE (exp) == TARGET_EXPR)
1876e4b17023SJohn Marino 	{
1877e4b17023SJohn Marino 	  error ("taking address of temporary array");
1878e4b17023SJohn Marino 	  return error_mark_node;
1879e4b17023SJohn Marino 	}
1880e4b17023SJohn Marino 
1881e4b17023SJohn Marino       ptrtype = build_pointer_type (TREE_TYPE (type));
1882e4b17023SJohn Marino 
1883e4b17023SJohn Marino       if (TREE_CODE (exp) == VAR_DECL)
1884e4b17023SJohn Marino 	{
1885e4b17023SJohn Marino 	  if (!cxx_mark_addressable (exp))
1886e4b17023SJohn Marino 	    return error_mark_node;
1887e4b17023SJohn Marino 	  adr = build_nop (ptrtype, build_address (exp));
1888e4b17023SJohn Marino 	  return adr;
1889e4b17023SJohn Marino 	}
1890e4b17023SJohn Marino       /* This way is better for a COMPONENT_REF since it can
1891e4b17023SJohn Marino 	 simplify the offset for a component.  */
1892e4b17023SJohn Marino       adr = cp_build_addr_expr (exp, tf_warning_or_error);
1893e4b17023SJohn Marino       return cp_convert (ptrtype, adr);
1894e4b17023SJohn Marino     }
1895e4b17023SJohn Marino 
1896e4b17023SJohn Marino   /* If a bitfield is used in a context where integral promotion
1897e4b17023SJohn Marino      applies, then the caller is expected to have used
1898e4b17023SJohn Marino      default_conversion.  That function promotes bitfields correctly
1899e4b17023SJohn Marino      before calling this function.  At this point, if we have a
1900e4b17023SJohn Marino      bitfield referenced, we may assume that is not subject to
1901e4b17023SJohn Marino      promotion, and that, therefore, the type of the resulting rvalue
1902e4b17023SJohn Marino      is the declared type of the bitfield.  */
1903e4b17023SJohn Marino   exp = convert_bitfield_to_declared_type (exp);
1904e4b17023SJohn Marino 
1905e4b17023SJohn Marino   /* We do not call rvalue() here because we do not want to wrap EXP
1906e4b17023SJohn Marino      in a NON_LVALUE_EXPR.  */
1907e4b17023SJohn Marino 
1908e4b17023SJohn Marino   /* [basic.lval]
1909e4b17023SJohn Marino 
1910e4b17023SJohn Marino      Non-class rvalues always have cv-unqualified types.  */
1911e4b17023SJohn Marino   type = TREE_TYPE (exp);
1912e4b17023SJohn Marino   if (!CLASS_TYPE_P (type) && cv_qualified_p (type))
1913e4b17023SJohn Marino     exp = build_nop (cv_unqualified (type), exp);
1914e4b17023SJohn Marino 
1915e4b17023SJohn Marino   return exp;
1916e4b17023SJohn Marino }
1917e4b17023SJohn Marino 
1918e4b17023SJohn Marino /* Perform preparatory conversions, as part of the "usual arithmetic
1919e4b17023SJohn Marino    conversions".  In particular, as per [expr]:
1920e4b17023SJohn Marino 
1921e4b17023SJohn Marino      Whenever an lvalue expression appears as an operand of an
1922e4b17023SJohn Marino      operator that expects the rvalue for that operand, the
1923e4b17023SJohn Marino      lvalue-to-rvalue, array-to-pointer, or function-to-pointer
1924e4b17023SJohn Marino      standard conversions are applied to convert the expression to an
1925e4b17023SJohn Marino      rvalue.
1926e4b17023SJohn Marino 
1927e4b17023SJohn Marino    In addition, we perform integral promotions here, as those are
1928e4b17023SJohn Marino    applied to both operands to a binary operator before determining
1929e4b17023SJohn Marino    what additional conversions should apply.  */
1930e4b17023SJohn Marino 
1931e4b17023SJohn Marino tree
default_conversion(tree exp)1932e4b17023SJohn Marino default_conversion (tree exp)
1933e4b17023SJohn Marino {
1934e4b17023SJohn Marino   /* Check for target-specific promotions.  */
1935e4b17023SJohn Marino   tree promoted_type = targetm.promoted_type (TREE_TYPE (exp));
1936e4b17023SJohn Marino   if (promoted_type)
1937e4b17023SJohn Marino     exp = cp_convert (promoted_type, exp);
1938e4b17023SJohn Marino   /* Perform the integral promotions first so that bitfield
1939e4b17023SJohn Marino      expressions (which may promote to "int", even if the bitfield is
1940e4b17023SJohn Marino      declared "unsigned") are promoted correctly.  */
1941e4b17023SJohn Marino   else if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (exp)))
1942e4b17023SJohn Marino     exp = perform_integral_promotions (exp);
1943e4b17023SJohn Marino   /* Perform the other conversions.  */
1944e4b17023SJohn Marino   exp = decay_conversion (exp);
1945e4b17023SJohn Marino 
1946e4b17023SJohn Marino   return exp;
1947e4b17023SJohn Marino }
1948e4b17023SJohn Marino 
1949e4b17023SJohn Marino /* EXPR is an expression with an integral or enumeration type.
1950e4b17023SJohn Marino    Perform the integral promotions in [conv.prom], and return the
1951e4b17023SJohn Marino    converted value.  */
1952e4b17023SJohn Marino 
1953e4b17023SJohn Marino tree
perform_integral_promotions(tree expr)1954e4b17023SJohn Marino perform_integral_promotions (tree expr)
1955e4b17023SJohn Marino {
1956e4b17023SJohn Marino   tree type;
1957e4b17023SJohn Marino   tree promoted_type;
1958e4b17023SJohn Marino 
1959e4b17023SJohn Marino   expr = mark_rvalue_use (expr);
1960e4b17023SJohn Marino 
1961e4b17023SJohn Marino   /* [conv.prom]
1962e4b17023SJohn Marino 
1963e4b17023SJohn Marino      If the bitfield has an enumerated type, it is treated as any
1964e4b17023SJohn Marino      other value of that type for promotion purposes.  */
1965e4b17023SJohn Marino   type = is_bitfield_expr_with_lowered_type (expr);
1966e4b17023SJohn Marino   if (!type || TREE_CODE (type) != ENUMERAL_TYPE)
1967e4b17023SJohn Marino     type = TREE_TYPE (expr);
1968e4b17023SJohn Marino   gcc_assert (INTEGRAL_OR_ENUMERATION_TYPE_P (type));
1969e4b17023SJohn Marino   /* Scoped enums don't promote.  */
1970e4b17023SJohn Marino   if (SCOPED_ENUM_P (type))
1971e4b17023SJohn Marino     return expr;
1972e4b17023SJohn Marino   promoted_type = type_promotes_to (type);
1973e4b17023SJohn Marino   if (type != promoted_type)
1974e4b17023SJohn Marino     expr = cp_convert (promoted_type, expr);
1975e4b17023SJohn Marino   return expr;
1976e4b17023SJohn Marino }
1977e4b17023SJohn Marino 
1978e4b17023SJohn Marino /* Returns nonzero iff exp is a STRING_CST or the result of applying
1979e4b17023SJohn Marino    decay_conversion to one.  */
1980e4b17023SJohn Marino 
1981e4b17023SJohn Marino int
string_conv_p(const_tree totype,const_tree exp,int warn)1982e4b17023SJohn Marino string_conv_p (const_tree totype, const_tree exp, int warn)
1983e4b17023SJohn Marino {
1984e4b17023SJohn Marino   tree t;
1985e4b17023SJohn Marino 
1986e4b17023SJohn Marino   if (TREE_CODE (totype) != POINTER_TYPE)
1987e4b17023SJohn Marino     return 0;
1988e4b17023SJohn Marino 
1989e4b17023SJohn Marino   t = TREE_TYPE (totype);
1990e4b17023SJohn Marino   if (!same_type_p (t, char_type_node)
1991e4b17023SJohn Marino       && !same_type_p (t, char16_type_node)
1992e4b17023SJohn Marino       && !same_type_p (t, char32_type_node)
1993e4b17023SJohn Marino       && !same_type_p (t, wchar_type_node))
1994e4b17023SJohn Marino     return 0;
1995e4b17023SJohn Marino 
1996e4b17023SJohn Marino   if (TREE_CODE (exp) == STRING_CST)
1997e4b17023SJohn Marino     {
1998e4b17023SJohn Marino       /* Make sure that we don't try to convert between char and wide chars.  */
1999e4b17023SJohn Marino       if (!same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (exp))), t))
2000e4b17023SJohn Marino 	return 0;
2001e4b17023SJohn Marino     }
2002e4b17023SJohn Marino   else
2003e4b17023SJohn Marino     {
2004e4b17023SJohn Marino       /* Is this a string constant which has decayed to 'const char *'?  */
2005e4b17023SJohn Marino       t = build_pointer_type (cp_build_qualified_type (t, TYPE_QUAL_CONST));
2006e4b17023SJohn Marino       if (!same_type_p (TREE_TYPE (exp), t))
2007e4b17023SJohn Marino 	return 0;
2008e4b17023SJohn Marino       STRIP_NOPS (exp);
2009e4b17023SJohn Marino       if (TREE_CODE (exp) != ADDR_EXPR
2010e4b17023SJohn Marino 	  || TREE_CODE (TREE_OPERAND (exp, 0)) != STRING_CST)
2011e4b17023SJohn Marino 	return 0;
2012e4b17023SJohn Marino     }
2013e4b17023SJohn Marino 
2014e4b17023SJohn Marino   /* This warning is not very useful, as it complains about printf.  */
2015e4b17023SJohn Marino   if (warn)
2016e4b17023SJohn Marino     warning (OPT_Wwrite_strings,
2017e4b17023SJohn Marino 	     "deprecated conversion from string constant to %qT",
2018e4b17023SJohn Marino 	     totype);
2019e4b17023SJohn Marino 
2020e4b17023SJohn Marino   return 1;
2021e4b17023SJohn Marino }
2022e4b17023SJohn Marino 
2023e4b17023SJohn Marino /* Given a COND_EXPR, MIN_EXPR, or MAX_EXPR in T, return it in a form that we
2024e4b17023SJohn Marino    can, for example, use as an lvalue.  This code used to be in
2025e4b17023SJohn Marino    unary_complex_lvalue, but we needed it to deal with `a = (d == c) ? b : c'
2026e4b17023SJohn Marino    expressions, where we're dealing with aggregates.  But now it's again only
2027e4b17023SJohn Marino    called from unary_complex_lvalue.  The case (in particular) that led to
2028e4b17023SJohn Marino    this was with CODE == ADDR_EXPR, since it's not an lvalue when we'd
2029e4b17023SJohn Marino    get it there.  */
2030e4b17023SJohn Marino 
2031e4b17023SJohn Marino static tree
rationalize_conditional_expr(enum tree_code code,tree t,tsubst_flags_t complain)2032e4b17023SJohn Marino rationalize_conditional_expr (enum tree_code code, tree t,
2033e4b17023SJohn Marino                               tsubst_flags_t complain)
2034e4b17023SJohn Marino {
2035e4b17023SJohn Marino   /* For MIN_EXPR or MAX_EXPR, fold-const.c has arranged things so that
2036e4b17023SJohn Marino      the first operand is always the one to be used if both operands
2037e4b17023SJohn Marino      are equal, so we know what conditional expression this used to be.  */
2038e4b17023SJohn Marino   if (TREE_CODE (t) == MIN_EXPR || TREE_CODE (t) == MAX_EXPR)
2039e4b17023SJohn Marino     {
2040e4b17023SJohn Marino       tree op0 = TREE_OPERAND (t, 0);
2041e4b17023SJohn Marino       tree op1 = TREE_OPERAND (t, 1);
2042e4b17023SJohn Marino 
2043e4b17023SJohn Marino       /* The following code is incorrect if either operand side-effects.  */
2044e4b17023SJohn Marino       gcc_assert (!TREE_SIDE_EFFECTS (op0)
2045e4b17023SJohn Marino 		  && !TREE_SIDE_EFFECTS (op1));
2046e4b17023SJohn Marino       return
2047e4b17023SJohn Marino 	build_conditional_expr (build_x_binary_op ((TREE_CODE (t) == MIN_EXPR
2048e4b17023SJohn Marino 						    ? LE_EXPR : GE_EXPR),
2049e4b17023SJohn Marino 						   op0, TREE_CODE (op0),
2050e4b17023SJohn Marino 						   op1, TREE_CODE (op1),
2051e4b17023SJohn Marino 						   /*overload=*/NULL,
2052e4b17023SJohn Marino 						   complain),
2053e4b17023SJohn Marino                                 cp_build_unary_op (code, op0, 0, complain),
2054e4b17023SJohn Marino                                 cp_build_unary_op (code, op1, 0, complain),
2055e4b17023SJohn Marino                                 complain);
2056e4b17023SJohn Marino     }
2057e4b17023SJohn Marino 
2058e4b17023SJohn Marino   return
2059e4b17023SJohn Marino     build_conditional_expr (TREE_OPERAND (t, 0),
2060e4b17023SJohn Marino 			    cp_build_unary_op (code, TREE_OPERAND (t, 1), 0,
2061e4b17023SJohn Marino                                                complain),
2062e4b17023SJohn Marino 			    cp_build_unary_op (code, TREE_OPERAND (t, 2), 0,
2063e4b17023SJohn Marino                                                complain),
2064e4b17023SJohn Marino                             complain);
2065e4b17023SJohn Marino }
2066e4b17023SJohn Marino 
2067e4b17023SJohn Marino /* Given the TYPE of an anonymous union field inside T, return the
2068e4b17023SJohn Marino    FIELD_DECL for the field.  If not found return NULL_TREE.  Because
2069e4b17023SJohn Marino    anonymous unions can nest, we must also search all anonymous unions
2070e4b17023SJohn Marino    that are directly reachable.  */
2071e4b17023SJohn Marino 
2072e4b17023SJohn Marino tree
lookup_anon_field(tree t,tree type)2073e4b17023SJohn Marino lookup_anon_field (tree t, tree type)
2074e4b17023SJohn Marino {
2075e4b17023SJohn Marino   tree field;
2076e4b17023SJohn Marino 
2077e4b17023SJohn Marino   for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
2078e4b17023SJohn Marino     {
2079e4b17023SJohn Marino       if (TREE_STATIC (field))
2080e4b17023SJohn Marino 	continue;
2081e4b17023SJohn Marino       if (TREE_CODE (field) != FIELD_DECL || DECL_ARTIFICIAL (field))
2082e4b17023SJohn Marino 	continue;
2083e4b17023SJohn Marino 
2084e4b17023SJohn Marino       /* If we find it directly, return the field.  */
2085e4b17023SJohn Marino       if (DECL_NAME (field) == NULL_TREE
2086e4b17023SJohn Marino 	  && type == TYPE_MAIN_VARIANT (TREE_TYPE (field)))
2087e4b17023SJohn Marino 	{
2088e4b17023SJohn Marino 	  return field;
2089e4b17023SJohn Marino 	}
2090e4b17023SJohn Marino 
2091e4b17023SJohn Marino       /* Otherwise, it could be nested, search harder.  */
2092e4b17023SJohn Marino       if (DECL_NAME (field) == NULL_TREE
2093e4b17023SJohn Marino 	  && ANON_AGGR_TYPE_P (TREE_TYPE (field)))
2094e4b17023SJohn Marino 	{
2095e4b17023SJohn Marino 	  tree subfield = lookup_anon_field (TREE_TYPE (field), type);
2096e4b17023SJohn Marino 	  if (subfield)
2097e4b17023SJohn Marino 	    return subfield;
2098e4b17023SJohn Marino 	}
2099e4b17023SJohn Marino     }
2100e4b17023SJohn Marino   return NULL_TREE;
2101e4b17023SJohn Marino }
2102e4b17023SJohn Marino 
2103e4b17023SJohn Marino /* Build an expression representing OBJECT.MEMBER.  OBJECT is an
2104e4b17023SJohn Marino    expression; MEMBER is a DECL or baselink.  If ACCESS_PATH is
2105e4b17023SJohn Marino    non-NULL, it indicates the path to the base used to name MEMBER.
2106e4b17023SJohn Marino    If PRESERVE_REFERENCE is true, the expression returned will have
2107e4b17023SJohn Marino    REFERENCE_TYPE if the MEMBER does.  Otherwise, the expression
2108e4b17023SJohn Marino    returned will have the type referred to by the reference.
2109e4b17023SJohn Marino 
2110e4b17023SJohn Marino    This function does not perform access control; that is either done
2111e4b17023SJohn Marino    earlier by the parser when the name of MEMBER is resolved to MEMBER
2112e4b17023SJohn Marino    itself, or later when overload resolution selects one of the
2113e4b17023SJohn Marino    functions indicated by MEMBER.  */
2114e4b17023SJohn Marino 
2115e4b17023SJohn Marino tree
build_class_member_access_expr(tree object,tree member,tree access_path,bool preserve_reference,tsubst_flags_t complain)2116e4b17023SJohn Marino build_class_member_access_expr (tree object, tree member,
2117e4b17023SJohn Marino 				tree access_path, bool preserve_reference,
2118e4b17023SJohn Marino 				tsubst_flags_t complain)
2119e4b17023SJohn Marino {
2120e4b17023SJohn Marino   tree object_type;
2121e4b17023SJohn Marino   tree member_scope;
2122e4b17023SJohn Marino   tree result = NULL_TREE;
2123e4b17023SJohn Marino   tree using_decl = NULL_TREE;
2124e4b17023SJohn Marino 
2125e4b17023SJohn Marino   if (error_operand_p (object) || error_operand_p (member))
2126e4b17023SJohn Marino     return error_mark_node;
2127e4b17023SJohn Marino 
2128e4b17023SJohn Marino   gcc_assert (DECL_P (member) || BASELINK_P (member));
2129e4b17023SJohn Marino 
2130e4b17023SJohn Marino   /* [expr.ref]
2131e4b17023SJohn Marino 
2132e4b17023SJohn Marino      The type of the first expression shall be "class object" (of a
2133e4b17023SJohn Marino      complete type).  */
2134e4b17023SJohn Marino   object_type = TREE_TYPE (object);
2135e4b17023SJohn Marino   if (!currently_open_class (object_type)
2136e4b17023SJohn Marino       && !complete_type_or_maybe_complain (object_type, object, complain))
2137e4b17023SJohn Marino     return error_mark_node;
2138e4b17023SJohn Marino   if (!CLASS_TYPE_P (object_type))
2139e4b17023SJohn Marino     {
2140e4b17023SJohn Marino       if (complain & tf_error)
2141e4b17023SJohn Marino 	{
2142e4b17023SJohn Marino 	  if (POINTER_TYPE_P (object_type)
2143e4b17023SJohn Marino 	      && CLASS_TYPE_P (TREE_TYPE (object_type)))
2144e4b17023SJohn Marino 	    error ("request for member %qD in %qE, which is of pointer "
2145e4b17023SJohn Marino 		   "type %qT (maybe you meant to use %<->%> ?)",
2146e4b17023SJohn Marino 		   member, object, object_type);
2147e4b17023SJohn Marino 	  else
2148e4b17023SJohn Marino 	    error ("request for member %qD in %qE, which is of non-class "
2149e4b17023SJohn Marino 		   "type %qT", member, object, object_type);
2150e4b17023SJohn Marino 	}
2151e4b17023SJohn Marino       return error_mark_node;
2152e4b17023SJohn Marino     }
2153e4b17023SJohn Marino 
2154e4b17023SJohn Marino   /* The standard does not seem to actually say that MEMBER must be a
2155e4b17023SJohn Marino      member of OBJECT_TYPE.  However, that is clearly what is
2156e4b17023SJohn Marino      intended.  */
2157e4b17023SJohn Marino   if (DECL_P (member))
2158e4b17023SJohn Marino     {
2159e4b17023SJohn Marino       member_scope = DECL_CLASS_CONTEXT (member);
2160e4b17023SJohn Marino       mark_used (member);
2161e4b17023SJohn Marino       if (TREE_DEPRECATED (member))
2162e4b17023SJohn Marino 	warn_deprecated_use (member, NULL_TREE);
2163e4b17023SJohn Marino     }
2164e4b17023SJohn Marino   else
2165e4b17023SJohn Marino     member_scope = BINFO_TYPE (BASELINK_ACCESS_BINFO (member));
2166e4b17023SJohn Marino   /* If MEMBER is from an anonymous aggregate, MEMBER_SCOPE will
2167e4b17023SJohn Marino      presently be the anonymous union.  Go outwards until we find a
2168e4b17023SJohn Marino      type related to OBJECT_TYPE.  */
2169e4b17023SJohn Marino   while (ANON_AGGR_TYPE_P (member_scope)
2170e4b17023SJohn Marino 	 && !same_type_ignoring_top_level_qualifiers_p (member_scope,
2171e4b17023SJohn Marino 							object_type))
2172e4b17023SJohn Marino     member_scope = TYPE_CONTEXT (member_scope);
2173e4b17023SJohn Marino   if (!member_scope || !DERIVED_FROM_P (member_scope, object_type))
2174e4b17023SJohn Marino     {
2175e4b17023SJohn Marino       if (complain & tf_error)
2176e4b17023SJohn Marino 	{
2177e4b17023SJohn Marino 	  if (TREE_CODE (member) == FIELD_DECL)
2178e4b17023SJohn Marino 	    error ("invalid use of nonstatic data member %qE", member);
2179e4b17023SJohn Marino 	  else
2180e4b17023SJohn Marino 	    error ("%qD is not a member of %qT", member, object_type);
2181e4b17023SJohn Marino 	}
2182e4b17023SJohn Marino       return error_mark_node;
2183e4b17023SJohn Marino     }
2184e4b17023SJohn Marino 
2185e4b17023SJohn Marino   /* Transform `(a, b).x' into `(*(a, &b)).x', `(a ? b : c).x' into
2186e4b17023SJohn Marino      `(*(a ?  &b : &c)).x', and so on.  A COND_EXPR is only an lvalue
2187e4b17023SJohn Marino      in the front end; only _DECLs and _REFs are lvalues in the back end.  */
2188e4b17023SJohn Marino   {
2189e4b17023SJohn Marino     tree temp = unary_complex_lvalue (ADDR_EXPR, object);
2190e4b17023SJohn Marino     if (temp)
2191e4b17023SJohn Marino       object = cp_build_indirect_ref (temp, RO_NULL, complain);
2192e4b17023SJohn Marino   }
2193e4b17023SJohn Marino 
2194e4b17023SJohn Marino   /* In [expr.ref], there is an explicit list of the valid choices for
2195e4b17023SJohn Marino      MEMBER.  We check for each of those cases here.  */
2196e4b17023SJohn Marino   if (TREE_CODE (member) == VAR_DECL)
2197e4b17023SJohn Marino     {
2198e4b17023SJohn Marino       /* A static data member.  */
2199e4b17023SJohn Marino       result = member;
2200e4b17023SJohn Marino       mark_exp_read (object);
2201e4b17023SJohn Marino       /* If OBJECT has side-effects, they are supposed to occur.  */
2202e4b17023SJohn Marino       if (TREE_SIDE_EFFECTS (object))
2203e4b17023SJohn Marino 	result = build2 (COMPOUND_EXPR, TREE_TYPE (result), object, result);
2204e4b17023SJohn Marino     }
2205e4b17023SJohn Marino   else if (TREE_CODE (member) == FIELD_DECL)
2206e4b17023SJohn Marino     {
2207e4b17023SJohn Marino       /* A non-static data member.  */
2208e4b17023SJohn Marino       bool null_object_p;
2209e4b17023SJohn Marino       int type_quals;
2210e4b17023SJohn Marino       tree member_type;
2211e4b17023SJohn Marino 
2212e4b17023SJohn Marino       null_object_p = (TREE_CODE (object) == INDIRECT_REF
2213e4b17023SJohn Marino 		       && integer_zerop (TREE_OPERAND (object, 0)));
2214e4b17023SJohn Marino 
2215e4b17023SJohn Marino       /* Convert OBJECT to the type of MEMBER.  */
2216e4b17023SJohn Marino       if (!same_type_p (TYPE_MAIN_VARIANT (object_type),
2217e4b17023SJohn Marino 			TYPE_MAIN_VARIANT (member_scope)))
2218e4b17023SJohn Marino 	{
2219e4b17023SJohn Marino 	  tree binfo;
2220e4b17023SJohn Marino 	  base_kind kind;
2221e4b17023SJohn Marino 
2222e4b17023SJohn Marino 	  binfo = lookup_base (access_path ? access_path : object_type,
2223e4b17023SJohn Marino 			       member_scope, ba_unique,  &kind);
2224e4b17023SJohn Marino 	  if (binfo == error_mark_node)
2225e4b17023SJohn Marino 	    return error_mark_node;
2226e4b17023SJohn Marino 
2227e4b17023SJohn Marino 	  /* It is invalid to try to get to a virtual base of a
2228e4b17023SJohn Marino 	     NULL object.  The most common cause is invalid use of
2229e4b17023SJohn Marino 	     offsetof macro.  */
2230e4b17023SJohn Marino 	  if (null_object_p && kind == bk_via_virtual)
2231e4b17023SJohn Marino 	    {
2232e4b17023SJohn Marino 	      if (complain & tf_error)
2233e4b17023SJohn Marino 		{
2234e4b17023SJohn Marino 		  error ("invalid access to non-static data member %qD of "
2235e4b17023SJohn Marino 			 "NULL object",
2236e4b17023SJohn Marino 			 member);
2237e4b17023SJohn Marino 		  error ("(perhaps the %<offsetof%> macro was used incorrectly)");
2238e4b17023SJohn Marino 		}
2239e4b17023SJohn Marino 	      return error_mark_node;
2240e4b17023SJohn Marino 	    }
2241e4b17023SJohn Marino 
2242e4b17023SJohn Marino 	  /* Convert to the base.  */
2243e4b17023SJohn Marino 	  object = build_base_path (PLUS_EXPR, object, binfo,
2244e4b17023SJohn Marino 				    /*nonnull=*/1, complain);
2245e4b17023SJohn Marino 	  /* If we found the base successfully then we should be able
2246e4b17023SJohn Marino 	     to convert to it successfully.  */
2247e4b17023SJohn Marino 	  gcc_assert (object != error_mark_node);
2248e4b17023SJohn Marino 	}
2249e4b17023SJohn Marino 
2250e4b17023SJohn Marino       /* Complain about other invalid uses of offsetof, even though they will
2251e4b17023SJohn Marino 	 give the right answer.  Note that we complain whether or not they
2252e4b17023SJohn Marino 	 actually used the offsetof macro, since there's no way to know at this
2253e4b17023SJohn Marino 	 point.  So we just give a warning, instead of a pedwarn.  */
2254e4b17023SJohn Marino       /* Do not produce this warning for base class field references, because
2255e4b17023SJohn Marino 	 we know for a fact that didn't come from offsetof.  This does occur
2256e4b17023SJohn Marino 	 in various testsuite cases where a null object is passed where a
2257e4b17023SJohn Marino 	 vtable access is required.  */
2258e4b17023SJohn Marino       if (null_object_p && warn_invalid_offsetof
2259e4b17023SJohn Marino 	  && CLASSTYPE_NON_STD_LAYOUT (object_type)
2260e4b17023SJohn Marino 	  && !DECL_FIELD_IS_BASE (member)
2261e4b17023SJohn Marino 	  && cp_unevaluated_operand == 0
2262e4b17023SJohn Marino 	  && (complain & tf_warning))
2263e4b17023SJohn Marino 	{
2264e4b17023SJohn Marino 	  warning (OPT_Winvalid_offsetof,
2265e4b17023SJohn Marino                    "invalid access to non-static data member %qD "
2266e4b17023SJohn Marino                    " of NULL object", member);
2267e4b17023SJohn Marino 	  warning (OPT_Winvalid_offsetof,
2268e4b17023SJohn Marino                    "(perhaps the %<offsetof%> macro was used incorrectly)");
2269e4b17023SJohn Marino 	}
2270e4b17023SJohn Marino 
2271e4b17023SJohn Marino       /* If MEMBER is from an anonymous aggregate, we have converted
2272e4b17023SJohn Marino 	 OBJECT so that it refers to the class containing the
2273e4b17023SJohn Marino 	 anonymous union.  Generate a reference to the anonymous union
2274e4b17023SJohn Marino 	 itself, and recur to find MEMBER.  */
2275e4b17023SJohn Marino       if (ANON_AGGR_TYPE_P (DECL_CONTEXT (member))
2276e4b17023SJohn Marino 	  /* When this code is called from build_field_call, the
2277e4b17023SJohn Marino 	     object already has the type of the anonymous union.
2278e4b17023SJohn Marino 	     That is because the COMPONENT_REF was already
2279e4b17023SJohn Marino 	     constructed, and was then disassembled before calling
2280e4b17023SJohn Marino 	     build_field_call.  After the function-call code is
2281e4b17023SJohn Marino 	     cleaned up, this waste can be eliminated.  */
2282e4b17023SJohn Marino 	  && (!same_type_ignoring_top_level_qualifiers_p
2283e4b17023SJohn Marino 	      (TREE_TYPE (object), DECL_CONTEXT (member))))
2284e4b17023SJohn Marino 	{
2285e4b17023SJohn Marino 	  tree anonymous_union;
2286e4b17023SJohn Marino 
2287e4b17023SJohn Marino 	  anonymous_union = lookup_anon_field (TREE_TYPE (object),
2288e4b17023SJohn Marino 					       DECL_CONTEXT (member));
2289e4b17023SJohn Marino 	  object = build_class_member_access_expr (object,
2290e4b17023SJohn Marino 						   anonymous_union,
2291e4b17023SJohn Marino 						   /*access_path=*/NULL_TREE,
2292e4b17023SJohn Marino 						   preserve_reference,
2293e4b17023SJohn Marino 						   complain);
2294e4b17023SJohn Marino 	}
2295e4b17023SJohn Marino 
2296e4b17023SJohn Marino       /* Compute the type of the field, as described in [expr.ref].  */
2297e4b17023SJohn Marino       type_quals = TYPE_UNQUALIFIED;
2298e4b17023SJohn Marino       member_type = TREE_TYPE (member);
2299e4b17023SJohn Marino       if (TREE_CODE (member_type) != REFERENCE_TYPE)
2300e4b17023SJohn Marino 	{
2301e4b17023SJohn Marino 	  type_quals = (cp_type_quals (member_type)
2302e4b17023SJohn Marino 			| cp_type_quals (object_type));
2303e4b17023SJohn Marino 
2304e4b17023SJohn Marino 	  /* A field is const (volatile) if the enclosing object, or the
2305e4b17023SJohn Marino 	     field itself, is const (volatile).  But, a mutable field is
2306e4b17023SJohn Marino 	     not const, even within a const object.  */
2307e4b17023SJohn Marino 	  if (DECL_MUTABLE_P (member))
2308e4b17023SJohn Marino 	    type_quals &= ~TYPE_QUAL_CONST;
2309e4b17023SJohn Marino 	  member_type = cp_build_qualified_type (member_type, type_quals);
2310e4b17023SJohn Marino 	}
2311e4b17023SJohn Marino 
2312e4b17023SJohn Marino       result = build3 (COMPONENT_REF, member_type, object, member,
2313e4b17023SJohn Marino 		       NULL_TREE);
2314e4b17023SJohn Marino       result = fold_if_not_in_template (result);
2315e4b17023SJohn Marino 
2316e4b17023SJohn Marino       /* Mark the expression const or volatile, as appropriate.  Even
2317e4b17023SJohn Marino 	 though we've dealt with the type above, we still have to mark the
2318e4b17023SJohn Marino 	 expression itself.  */
2319e4b17023SJohn Marino       if (type_quals & TYPE_QUAL_CONST)
2320e4b17023SJohn Marino 	TREE_READONLY (result) = 1;
2321e4b17023SJohn Marino       if (type_quals & TYPE_QUAL_VOLATILE)
2322e4b17023SJohn Marino 	TREE_THIS_VOLATILE (result) = 1;
2323e4b17023SJohn Marino     }
2324e4b17023SJohn Marino   else if (BASELINK_P (member))
2325e4b17023SJohn Marino     {
2326e4b17023SJohn Marino       /* The member is a (possibly overloaded) member function.  */
2327e4b17023SJohn Marino       tree functions;
2328e4b17023SJohn Marino       tree type;
2329e4b17023SJohn Marino 
2330e4b17023SJohn Marino       /* If the MEMBER is exactly one static member function, then we
2331e4b17023SJohn Marino 	 know the type of the expression.  Otherwise, we must wait
2332e4b17023SJohn Marino 	 until overload resolution has been performed.  */
2333e4b17023SJohn Marino       functions = BASELINK_FUNCTIONS (member);
2334e4b17023SJohn Marino       if (TREE_CODE (functions) == FUNCTION_DECL
2335e4b17023SJohn Marino 	  && DECL_STATIC_FUNCTION_P (functions))
2336e4b17023SJohn Marino 	type = TREE_TYPE (functions);
2337e4b17023SJohn Marino       else
2338e4b17023SJohn Marino 	type = unknown_type_node;
2339e4b17023SJohn Marino       /* Note that we do not convert OBJECT to the BASELINK_BINFO
2340e4b17023SJohn Marino 	 base.  That will happen when the function is called.  */
2341e4b17023SJohn Marino       result = build3 (COMPONENT_REF, type, object, member, NULL_TREE);
2342e4b17023SJohn Marino     }
2343e4b17023SJohn Marino   else if (TREE_CODE (member) == CONST_DECL)
2344e4b17023SJohn Marino     {
2345e4b17023SJohn Marino       /* The member is an enumerator.  */
2346e4b17023SJohn Marino       result = member;
2347e4b17023SJohn Marino       /* If OBJECT has side-effects, they are supposed to occur.  */
2348e4b17023SJohn Marino       if (TREE_SIDE_EFFECTS (object))
2349e4b17023SJohn Marino 	result = build2 (COMPOUND_EXPR, TREE_TYPE (result),
2350e4b17023SJohn Marino 			 object, result);
2351e4b17023SJohn Marino     }
2352e4b17023SJohn Marino   else if ((using_decl = strip_using_decl (member)) != member)
2353e4b17023SJohn Marino     result = build_class_member_access_expr (object,
2354e4b17023SJohn Marino 					     using_decl,
2355e4b17023SJohn Marino 					     access_path, preserve_reference,
2356e4b17023SJohn Marino 					     complain);
2357e4b17023SJohn Marino   else
2358e4b17023SJohn Marino     {
2359e4b17023SJohn Marino       if (complain & tf_error)
2360e4b17023SJohn Marino 	error ("invalid use of %qD", member);
2361e4b17023SJohn Marino       return error_mark_node;
2362e4b17023SJohn Marino     }
2363e4b17023SJohn Marino 
2364e4b17023SJohn Marino   if (!preserve_reference)
2365e4b17023SJohn Marino     /* [expr.ref]
2366e4b17023SJohn Marino 
2367e4b17023SJohn Marino        If E2 is declared to have type "reference to T", then ... the
2368e4b17023SJohn Marino        type of E1.E2 is T.  */
2369e4b17023SJohn Marino     result = convert_from_reference (result);
2370e4b17023SJohn Marino 
2371e4b17023SJohn Marino   return result;
2372e4b17023SJohn Marino }
2373e4b17023SJohn Marino 
2374e4b17023SJohn Marino /* Return the destructor denoted by OBJECT.SCOPE::DTOR_NAME, or, if
2375e4b17023SJohn Marino    SCOPE is NULL, by OBJECT.DTOR_NAME, where DTOR_NAME is ~type.  */
2376e4b17023SJohn Marino 
2377e4b17023SJohn Marino static tree
lookup_destructor(tree object,tree scope,tree dtor_name)2378e4b17023SJohn Marino lookup_destructor (tree object, tree scope, tree dtor_name)
2379e4b17023SJohn Marino {
2380e4b17023SJohn Marino   tree object_type = TREE_TYPE (object);
2381e4b17023SJohn Marino   tree dtor_type = TREE_OPERAND (dtor_name, 0);
2382e4b17023SJohn Marino   tree expr;
2383e4b17023SJohn Marino 
2384e4b17023SJohn Marino   if (scope && !check_dtor_name (scope, dtor_type))
2385e4b17023SJohn Marino     {
2386e4b17023SJohn Marino       error ("qualified type %qT does not match destructor name ~%qT",
2387e4b17023SJohn Marino 	     scope, dtor_type);
2388e4b17023SJohn Marino       return error_mark_node;
2389e4b17023SJohn Marino     }
2390e4b17023SJohn Marino   if (TREE_CODE (dtor_type) == IDENTIFIER_NODE)
2391e4b17023SJohn Marino     {
2392e4b17023SJohn Marino       /* In a template, names we can't find a match for are still accepted
2393e4b17023SJohn Marino 	 destructor names, and we check them here.  */
2394e4b17023SJohn Marino       if (check_dtor_name (object_type, dtor_type))
2395e4b17023SJohn Marino 	dtor_type = object_type;
2396e4b17023SJohn Marino       else
2397e4b17023SJohn Marino 	{
2398e4b17023SJohn Marino 	  error ("object type %qT does not match destructor name ~%qT",
2399e4b17023SJohn Marino 		 object_type, dtor_type);
2400e4b17023SJohn Marino 	  return error_mark_node;
2401e4b17023SJohn Marino 	}
2402e4b17023SJohn Marino 
2403e4b17023SJohn Marino     }
2404e4b17023SJohn Marino   else if (!DERIVED_FROM_P (dtor_type, TYPE_MAIN_VARIANT (object_type)))
2405e4b17023SJohn Marino     {
2406e4b17023SJohn Marino       error ("the type being destroyed is %qT, but the destructor refers to %qT",
2407e4b17023SJohn Marino 	     TYPE_MAIN_VARIANT (object_type), dtor_type);
2408e4b17023SJohn Marino       return error_mark_node;
2409e4b17023SJohn Marino     }
2410e4b17023SJohn Marino   expr = lookup_member (dtor_type, complete_dtor_identifier,
2411e4b17023SJohn Marino 			/*protect=*/1, /*want_type=*/false,
2412e4b17023SJohn Marino 			tf_warning_or_error);
2413e4b17023SJohn Marino   expr = (adjust_result_of_qualified_name_lookup
2414e4b17023SJohn Marino 	  (expr, dtor_type, object_type));
2415e4b17023SJohn Marino   if (scope == NULL_TREE)
2416e4b17023SJohn Marino     /* We need to call adjust_result_of_qualified_name_lookup in case the
2417e4b17023SJohn Marino        destructor names a base class, but we unset BASELINK_QUALIFIED_P so
2418e4b17023SJohn Marino        that we still get virtual function binding.  */
2419e4b17023SJohn Marino     BASELINK_QUALIFIED_P (expr) = false;
2420e4b17023SJohn Marino   return expr;
2421e4b17023SJohn Marino }
2422e4b17023SJohn Marino 
2423e4b17023SJohn Marino /* An expression of the form "A::template B" has been resolved to
2424e4b17023SJohn Marino    DECL.  Issue a diagnostic if B is not a template or template
2425e4b17023SJohn Marino    specialization.  */
2426e4b17023SJohn Marino 
2427e4b17023SJohn Marino void
check_template_keyword(tree decl)2428e4b17023SJohn Marino check_template_keyword (tree decl)
2429e4b17023SJohn Marino {
2430e4b17023SJohn Marino   /* The standard says:
2431e4b17023SJohn Marino 
2432e4b17023SJohn Marino       [temp.names]
2433e4b17023SJohn Marino 
2434e4b17023SJohn Marino       If a name prefixed by the keyword template is not a member
2435e4b17023SJohn Marino       template, the program is ill-formed.
2436e4b17023SJohn Marino 
2437e4b17023SJohn Marino      DR 228 removed the restriction that the template be a member
2438e4b17023SJohn Marino      template.
2439e4b17023SJohn Marino 
2440e4b17023SJohn Marino      DR 96, if accepted would add the further restriction that explicit
2441e4b17023SJohn Marino      template arguments must be provided if the template keyword is
2442e4b17023SJohn Marino      used, but, as of 2005-10-16, that DR is still in "drafting".  If
2443e4b17023SJohn Marino      this DR is accepted, then the semantic checks here can be
2444e4b17023SJohn Marino      simplified, as the entity named must in fact be a template
2445e4b17023SJohn Marino      specialization, rather than, as at present, a set of overloaded
2446e4b17023SJohn Marino      functions containing at least one template function.  */
2447e4b17023SJohn Marino   if (TREE_CODE (decl) != TEMPLATE_DECL
2448e4b17023SJohn Marino       && TREE_CODE (decl) != TEMPLATE_ID_EXPR)
2449e4b17023SJohn Marino     {
2450e4b17023SJohn Marino       if (!is_overloaded_fn (decl))
2451e4b17023SJohn Marino 	permerror (input_location, "%qD is not a template", decl);
2452e4b17023SJohn Marino       else
2453e4b17023SJohn Marino 	{
2454e4b17023SJohn Marino 	  tree fns;
2455e4b17023SJohn Marino 	  fns = decl;
2456e4b17023SJohn Marino 	  if (BASELINK_P (fns))
2457e4b17023SJohn Marino 	    fns = BASELINK_FUNCTIONS (fns);
2458e4b17023SJohn Marino 	  while (fns)
2459e4b17023SJohn Marino 	    {
2460e4b17023SJohn Marino 	      tree fn = OVL_CURRENT (fns);
2461e4b17023SJohn Marino 	      if (TREE_CODE (fn) == TEMPLATE_DECL
2462e4b17023SJohn Marino 		  || TREE_CODE (fn) == TEMPLATE_ID_EXPR)
2463e4b17023SJohn Marino 		break;
2464e4b17023SJohn Marino 	      if (TREE_CODE (fn) == FUNCTION_DECL
2465e4b17023SJohn Marino 		  && DECL_USE_TEMPLATE (fn)
2466e4b17023SJohn Marino 		  && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (fn)))
2467e4b17023SJohn Marino 		break;
2468e4b17023SJohn Marino 	      fns = OVL_NEXT (fns);
2469e4b17023SJohn Marino 	    }
2470e4b17023SJohn Marino 	  if (!fns)
2471e4b17023SJohn Marino 	    permerror (input_location, "%qD is not a template", decl);
2472e4b17023SJohn Marino 	}
2473e4b17023SJohn Marino     }
2474e4b17023SJohn Marino }
2475e4b17023SJohn Marino 
2476e4b17023SJohn Marino /* This function is called by the parser to process a class member
2477e4b17023SJohn Marino    access expression of the form OBJECT.NAME.  NAME is a node used by
2478e4b17023SJohn Marino    the parser to represent a name; it is not yet a DECL.  It may,
2479e4b17023SJohn Marino    however, be a BASELINK where the BASELINK_FUNCTIONS is a
2480e4b17023SJohn Marino    TEMPLATE_ID_EXPR.  Templates must be looked up by the parser, and
2481e4b17023SJohn Marino    there is no reason to do the lookup twice, so the parser keeps the
2482e4b17023SJohn Marino    BASELINK.  TEMPLATE_P is true iff NAME was explicitly declared to
2483e4b17023SJohn Marino    be a template via the use of the "A::template B" syntax.  */
2484e4b17023SJohn Marino 
2485e4b17023SJohn Marino tree
finish_class_member_access_expr(tree object,tree name,bool template_p,tsubst_flags_t complain)2486e4b17023SJohn Marino finish_class_member_access_expr (tree object, tree name, bool template_p,
2487e4b17023SJohn Marino 				 tsubst_flags_t complain)
2488e4b17023SJohn Marino {
2489e4b17023SJohn Marino   tree expr;
2490e4b17023SJohn Marino   tree object_type;
2491e4b17023SJohn Marino   tree member;
2492e4b17023SJohn Marino   tree access_path = NULL_TREE;
2493e4b17023SJohn Marino   tree orig_object = object;
2494e4b17023SJohn Marino   tree orig_name = name;
2495e4b17023SJohn Marino 
2496e4b17023SJohn Marino   if (object == error_mark_node || name == error_mark_node)
2497e4b17023SJohn Marino     return error_mark_node;
2498e4b17023SJohn Marino 
2499e4b17023SJohn Marino   /* If OBJECT is an ObjC class instance, we must obey ObjC access rules.  */
2500e4b17023SJohn Marino   if (!objc_is_public (object, name))
2501e4b17023SJohn Marino     return error_mark_node;
2502e4b17023SJohn Marino 
2503e4b17023SJohn Marino   object_type = TREE_TYPE (object);
2504e4b17023SJohn Marino 
2505e4b17023SJohn Marino   if (processing_template_decl)
2506e4b17023SJohn Marino     {
2507e4b17023SJohn Marino       if (/* If OBJECT_TYPE is dependent, so is OBJECT.NAME.  */
2508e4b17023SJohn Marino 	  dependent_type_p (object_type)
2509e4b17023SJohn Marino 	  /* If NAME is just an IDENTIFIER_NODE, then the expression
2510e4b17023SJohn Marino 	     is dependent.  */
2511e4b17023SJohn Marino 	  || TREE_CODE (object) == IDENTIFIER_NODE
2512e4b17023SJohn Marino 	  /* If NAME is "f<args>", where either 'f' or 'args' is
2513e4b17023SJohn Marino 	     dependent, then the expression is dependent.  */
2514e4b17023SJohn Marino 	  || (TREE_CODE (name) == TEMPLATE_ID_EXPR
2515e4b17023SJohn Marino 	      && dependent_template_id_p (TREE_OPERAND (name, 0),
2516e4b17023SJohn Marino 					  TREE_OPERAND (name, 1)))
2517e4b17023SJohn Marino 	  /* If NAME is "T::X" where "T" is dependent, then the
2518e4b17023SJohn Marino 	     expression is dependent.  */
2519e4b17023SJohn Marino 	  || (TREE_CODE (name) == SCOPE_REF
2520e4b17023SJohn Marino 	      && TYPE_P (TREE_OPERAND (name, 0))
2521e4b17023SJohn Marino 	      && dependent_type_p (TREE_OPERAND (name, 0))))
2522e4b17023SJohn Marino 	return build_min_nt (COMPONENT_REF, object, name, NULL_TREE);
2523e4b17023SJohn Marino       object = build_non_dependent_expr (object);
2524e4b17023SJohn Marino     }
2525e4b17023SJohn Marino   else if (c_dialect_objc ()
2526e4b17023SJohn Marino 	   && TREE_CODE (name) == IDENTIFIER_NODE
2527e4b17023SJohn Marino 	   && (expr = objc_maybe_build_component_ref (object, name)))
2528e4b17023SJohn Marino     return expr;
2529e4b17023SJohn Marino 
2530e4b17023SJohn Marino   /* [expr.ref]
2531e4b17023SJohn Marino 
2532e4b17023SJohn Marino      The type of the first expression shall be "class object" (of a
2533e4b17023SJohn Marino      complete type).  */
2534e4b17023SJohn Marino   if (!currently_open_class (object_type)
2535e4b17023SJohn Marino       && !complete_type_or_maybe_complain (object_type, object, complain))
2536e4b17023SJohn Marino     return error_mark_node;
2537e4b17023SJohn Marino   if (!CLASS_TYPE_P (object_type))
2538e4b17023SJohn Marino     {
2539e4b17023SJohn Marino       if (complain & tf_error)
2540e4b17023SJohn Marino 	{
2541e4b17023SJohn Marino 	  if (POINTER_TYPE_P (object_type)
2542e4b17023SJohn Marino 	      && CLASS_TYPE_P (TREE_TYPE (object_type)))
2543e4b17023SJohn Marino 	    error ("request for member %qD in %qE, which is of pointer "
2544e4b17023SJohn Marino 		   "type %qT (maybe you meant to use %<->%> ?)",
2545e4b17023SJohn Marino 		   name, object, object_type);
2546e4b17023SJohn Marino 	  else
2547e4b17023SJohn Marino 	    error ("request for member %qD in %qE, which is of non-class "
2548e4b17023SJohn Marino 		   "type %qT", name, object, object_type);
2549e4b17023SJohn Marino 	}
2550e4b17023SJohn Marino       return error_mark_node;
2551e4b17023SJohn Marino     }
2552e4b17023SJohn Marino 
2553e4b17023SJohn Marino   if (BASELINK_P (name))
2554e4b17023SJohn Marino     /* A member function that has already been looked up.  */
2555e4b17023SJohn Marino     member = name;
2556e4b17023SJohn Marino   else
2557e4b17023SJohn Marino     {
2558e4b17023SJohn Marino       bool is_template_id = false;
2559e4b17023SJohn Marino       tree template_args = NULL_TREE;
2560e4b17023SJohn Marino       tree scope;
2561e4b17023SJohn Marino 
2562e4b17023SJohn Marino       if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
2563e4b17023SJohn Marino 	{
2564e4b17023SJohn Marino 	  is_template_id = true;
2565e4b17023SJohn Marino 	  template_args = TREE_OPERAND (name, 1);
2566e4b17023SJohn Marino 	  name = TREE_OPERAND (name, 0);
2567e4b17023SJohn Marino 
2568e4b17023SJohn Marino 	  if (TREE_CODE (name) == OVERLOAD)
2569e4b17023SJohn Marino 	    name = DECL_NAME (get_first_fn (name));
2570e4b17023SJohn Marino 	  else if (DECL_P (name))
2571e4b17023SJohn Marino 	    name = DECL_NAME (name);
2572e4b17023SJohn Marino 	}
2573e4b17023SJohn Marino 
2574e4b17023SJohn Marino       if (TREE_CODE (name) == SCOPE_REF)
2575e4b17023SJohn Marino 	{
2576e4b17023SJohn Marino 	  /* A qualified name.  The qualifying class or namespace `S'
2577e4b17023SJohn Marino 	     has already been looked up; it is either a TYPE or a
2578e4b17023SJohn Marino 	     NAMESPACE_DECL.  */
2579e4b17023SJohn Marino 	  scope = TREE_OPERAND (name, 0);
2580e4b17023SJohn Marino 	  name = TREE_OPERAND (name, 1);
2581e4b17023SJohn Marino 
2582e4b17023SJohn Marino 	  /* If SCOPE is a namespace, then the qualified name does not
2583e4b17023SJohn Marino 	     name a member of OBJECT_TYPE.  */
2584e4b17023SJohn Marino 	  if (TREE_CODE (scope) == NAMESPACE_DECL)
2585e4b17023SJohn Marino 	    {
2586e4b17023SJohn Marino 	      if (complain & tf_error)
2587e4b17023SJohn Marino 		error ("%<%D::%D%> is not a member of %qT",
2588e4b17023SJohn Marino 		       scope, name, object_type);
2589e4b17023SJohn Marino 	      return error_mark_node;
2590e4b17023SJohn Marino 	    }
2591e4b17023SJohn Marino 
2592e4b17023SJohn Marino 	  gcc_assert (CLASS_TYPE_P (scope));
2593e4b17023SJohn Marino 	  gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE
2594e4b17023SJohn Marino 		      || TREE_CODE (name) == BIT_NOT_EXPR);
2595e4b17023SJohn Marino 
2596e4b17023SJohn Marino 	  if (constructor_name_p (name, scope))
2597e4b17023SJohn Marino 	    {
2598e4b17023SJohn Marino 	      if (complain & tf_error)
2599e4b17023SJohn Marino 		error ("cannot call constructor %<%T::%D%> directly",
2600e4b17023SJohn Marino 		       scope, name);
2601e4b17023SJohn Marino 	      return error_mark_node;
2602e4b17023SJohn Marino 	    }
2603e4b17023SJohn Marino 
2604e4b17023SJohn Marino 	  /* Find the base of OBJECT_TYPE corresponding to SCOPE.  */
2605e4b17023SJohn Marino 	  access_path = lookup_base (object_type, scope, ba_check, NULL);
2606e4b17023SJohn Marino 	  if (access_path == error_mark_node)
2607e4b17023SJohn Marino 	    return error_mark_node;
2608e4b17023SJohn Marino 	  if (!access_path)
2609e4b17023SJohn Marino 	    {
2610e4b17023SJohn Marino 	      if (complain & tf_error)
2611e4b17023SJohn Marino 		error ("%qT is not a base of %qT", scope, object_type);
2612e4b17023SJohn Marino 	      return error_mark_node;
2613e4b17023SJohn Marino 	    }
2614e4b17023SJohn Marino 	}
2615e4b17023SJohn Marino       else
2616e4b17023SJohn Marino 	{
2617e4b17023SJohn Marino 	  scope = NULL_TREE;
2618e4b17023SJohn Marino 	  access_path = object_type;
2619e4b17023SJohn Marino 	}
2620e4b17023SJohn Marino 
2621e4b17023SJohn Marino       if (TREE_CODE (name) == BIT_NOT_EXPR)
2622e4b17023SJohn Marino 	member = lookup_destructor (object, scope, name);
2623e4b17023SJohn Marino       else
2624e4b17023SJohn Marino 	{
2625e4b17023SJohn Marino 	  /* Look up the member.  */
2626e4b17023SJohn Marino 	  member = lookup_member (access_path, name, /*protect=*/1,
2627e4b17023SJohn Marino 				  /*want_type=*/false, complain);
2628e4b17023SJohn Marino 	  if (member == NULL_TREE)
2629e4b17023SJohn Marino 	    {
2630e4b17023SJohn Marino 	      if (complain & tf_error)
2631e4b17023SJohn Marino 		error ("%qD has no member named %qE",
2632e4b17023SJohn Marino 		       TREE_CODE (access_path) == TREE_BINFO
2633e4b17023SJohn Marino 		       ? TREE_TYPE (access_path) : object_type, name);
2634e4b17023SJohn Marino 	      return error_mark_node;
2635e4b17023SJohn Marino 	    }
2636e4b17023SJohn Marino 	  if (member == error_mark_node)
2637e4b17023SJohn Marino 	    return error_mark_node;
2638e4b17023SJohn Marino 	}
2639e4b17023SJohn Marino 
2640e4b17023SJohn Marino       if (is_template_id)
2641e4b17023SJohn Marino 	{
2642e4b17023SJohn Marino 	  tree templ = member;
2643e4b17023SJohn Marino 
2644e4b17023SJohn Marino 	  if (BASELINK_P (templ))
2645e4b17023SJohn Marino 	    templ = lookup_template_function (templ, template_args);
2646e4b17023SJohn Marino 	  else
2647e4b17023SJohn Marino 	    {
2648e4b17023SJohn Marino 	      if (complain & tf_error)
2649e4b17023SJohn Marino 		error ("%qD is not a member template function", name);
2650e4b17023SJohn Marino 	      return error_mark_node;
2651e4b17023SJohn Marino 	    }
2652e4b17023SJohn Marino 	}
2653e4b17023SJohn Marino     }
2654e4b17023SJohn Marino 
2655e4b17023SJohn Marino   if (TREE_DEPRECATED (member))
2656e4b17023SJohn Marino     warn_deprecated_use (member, NULL_TREE);
2657e4b17023SJohn Marino 
2658e4b17023SJohn Marino   if (template_p)
2659e4b17023SJohn Marino     check_template_keyword (member);
2660e4b17023SJohn Marino 
2661e4b17023SJohn Marino   expr = build_class_member_access_expr (object, member, access_path,
2662e4b17023SJohn Marino 					 /*preserve_reference=*/false,
2663e4b17023SJohn Marino 					 complain);
2664e4b17023SJohn Marino   if (processing_template_decl && expr != error_mark_node)
2665e4b17023SJohn Marino     {
2666e4b17023SJohn Marino       if (BASELINK_P (member))
2667e4b17023SJohn Marino 	{
2668e4b17023SJohn Marino 	  if (TREE_CODE (orig_name) == SCOPE_REF)
2669e4b17023SJohn Marino 	    BASELINK_QUALIFIED_P (member) = 1;
2670e4b17023SJohn Marino 	  orig_name = member;
2671e4b17023SJohn Marino 	}
2672e4b17023SJohn Marino       return build_min_non_dep (COMPONENT_REF, expr,
2673e4b17023SJohn Marino 				orig_object, orig_name,
2674e4b17023SJohn Marino 				NULL_TREE);
2675e4b17023SJohn Marino     }
2676e4b17023SJohn Marino 
2677e4b17023SJohn Marino   return expr;
2678e4b17023SJohn Marino }
2679e4b17023SJohn Marino 
2680e4b17023SJohn Marino /* Return an expression for the MEMBER_NAME field in the internal
2681e4b17023SJohn Marino    representation of PTRMEM, a pointer-to-member function.  (Each
2682e4b17023SJohn Marino    pointer-to-member function type gets its own RECORD_TYPE so it is
2683e4b17023SJohn Marino    more convenient to access the fields by name than by FIELD_DECL.)
2684e4b17023SJohn Marino    This routine converts the NAME to a FIELD_DECL and then creates the
2685e4b17023SJohn Marino    node for the complete expression.  */
2686e4b17023SJohn Marino 
2687e4b17023SJohn Marino tree
build_ptrmemfunc_access_expr(tree ptrmem,tree member_name)2688e4b17023SJohn Marino build_ptrmemfunc_access_expr (tree ptrmem, tree member_name)
2689e4b17023SJohn Marino {
2690e4b17023SJohn Marino   tree ptrmem_type;
2691e4b17023SJohn Marino   tree member;
2692e4b17023SJohn Marino   tree member_type;
2693e4b17023SJohn Marino 
2694e4b17023SJohn Marino   /* This code is a stripped down version of
2695e4b17023SJohn Marino      build_class_member_access_expr.  It does not work to use that
2696e4b17023SJohn Marino      routine directly because it expects the object to be of class
2697e4b17023SJohn Marino      type.  */
2698e4b17023SJohn Marino   ptrmem_type = TREE_TYPE (ptrmem);
2699e4b17023SJohn Marino   gcc_assert (TYPE_PTRMEMFUNC_P (ptrmem_type));
2700e4b17023SJohn Marino   member = lookup_member (ptrmem_type, member_name, /*protect=*/0,
2701e4b17023SJohn Marino 			  /*want_type=*/false, tf_warning_or_error);
2702e4b17023SJohn Marino   member_type = cp_build_qualified_type (TREE_TYPE (member),
2703e4b17023SJohn Marino 					 cp_type_quals (ptrmem_type));
2704e4b17023SJohn Marino   return fold_build3_loc (input_location,
2705e4b17023SJohn Marino 		      COMPONENT_REF, member_type,
2706e4b17023SJohn Marino 		      ptrmem, member, NULL_TREE);
2707e4b17023SJohn Marino }
2708e4b17023SJohn Marino 
2709e4b17023SJohn Marino /* Given an expression PTR for a pointer, return an expression
2710e4b17023SJohn Marino    for the value pointed to.
2711e4b17023SJohn Marino    ERRORSTRING is the name of the operator to appear in error messages.
2712e4b17023SJohn Marino 
2713e4b17023SJohn Marino    This function may need to overload OPERATOR_FNNAME.
2714e4b17023SJohn Marino    Must also handle REFERENCE_TYPEs for C++.  */
2715e4b17023SJohn Marino 
2716e4b17023SJohn Marino tree
build_x_indirect_ref(tree expr,ref_operator errorstring,tsubst_flags_t complain)2717e4b17023SJohn Marino build_x_indirect_ref (tree expr, ref_operator errorstring,
2718e4b17023SJohn Marino                       tsubst_flags_t complain)
2719e4b17023SJohn Marino {
2720e4b17023SJohn Marino   tree orig_expr = expr;
2721e4b17023SJohn Marino   tree rval;
2722e4b17023SJohn Marino 
2723e4b17023SJohn Marino   if (processing_template_decl)
2724e4b17023SJohn Marino     {
2725e4b17023SJohn Marino       /* Retain the type if we know the operand is a pointer.  */
2726e4b17023SJohn Marino       if (TREE_TYPE (expr) && POINTER_TYPE_P (TREE_TYPE (expr)))
2727e4b17023SJohn Marino 	return build_min (INDIRECT_REF, TREE_TYPE (TREE_TYPE (expr)), expr);
2728e4b17023SJohn Marino       if (type_dependent_expression_p (expr))
2729e4b17023SJohn Marino 	return build_min_nt (INDIRECT_REF, expr);
2730e4b17023SJohn Marino       expr = build_non_dependent_expr (expr);
2731e4b17023SJohn Marino     }
2732e4b17023SJohn Marino 
2733e4b17023SJohn Marino   rval = build_new_op (INDIRECT_REF, LOOKUP_NORMAL, expr, NULL_TREE,
2734e4b17023SJohn Marino 		       NULL_TREE, /*overload=*/NULL, complain);
2735e4b17023SJohn Marino   if (!rval)
2736e4b17023SJohn Marino     rval = cp_build_indirect_ref (expr, errorstring, complain);
2737e4b17023SJohn Marino 
2738e4b17023SJohn Marino   if (processing_template_decl && rval != error_mark_node)
2739e4b17023SJohn Marino     return build_min_non_dep (INDIRECT_REF, rval, orig_expr);
2740e4b17023SJohn Marino   else
2741e4b17023SJohn Marino     return rval;
2742e4b17023SJohn Marino }
2743e4b17023SJohn Marino 
2744e4b17023SJohn Marino /* Helper function called from c-common.  */
2745e4b17023SJohn Marino tree
build_indirect_ref(location_t loc ATTRIBUTE_UNUSED,tree ptr,ref_operator errorstring)2746e4b17023SJohn Marino build_indirect_ref (location_t loc ATTRIBUTE_UNUSED,
2747e4b17023SJohn Marino 		    tree ptr, ref_operator errorstring)
2748e4b17023SJohn Marino {
2749e4b17023SJohn Marino   return cp_build_indirect_ref (ptr, errorstring, tf_warning_or_error);
2750e4b17023SJohn Marino }
2751e4b17023SJohn Marino 
2752e4b17023SJohn Marino tree
cp_build_indirect_ref(tree ptr,ref_operator errorstring,tsubst_flags_t complain)2753e4b17023SJohn Marino cp_build_indirect_ref (tree ptr, ref_operator errorstring,
2754e4b17023SJohn Marino                        tsubst_flags_t complain)
2755e4b17023SJohn Marino {
2756e4b17023SJohn Marino   tree pointer, type;
2757e4b17023SJohn Marino 
2758e4b17023SJohn Marino   if (ptr == error_mark_node)
2759e4b17023SJohn Marino     return error_mark_node;
2760e4b17023SJohn Marino 
2761e4b17023SJohn Marino   if (ptr == current_class_ptr)
2762e4b17023SJohn Marino     return current_class_ref;
2763e4b17023SJohn Marino 
2764e4b17023SJohn Marino   pointer = (TREE_CODE (TREE_TYPE (ptr)) == REFERENCE_TYPE
2765e4b17023SJohn Marino 	     ? ptr : decay_conversion (ptr));
2766e4b17023SJohn Marino   type = TREE_TYPE (pointer);
2767e4b17023SJohn Marino 
2768e4b17023SJohn Marino   if (POINTER_TYPE_P (type))
2769e4b17023SJohn Marino     {
2770e4b17023SJohn Marino       /* [expr.unary.op]
2771e4b17023SJohn Marino 
2772e4b17023SJohn Marino 	 If the type of the expression is "pointer to T," the type
2773e4b17023SJohn Marino 	 of  the  result  is  "T."  */
2774e4b17023SJohn Marino       tree t = TREE_TYPE (type);
2775e4b17023SJohn Marino 
2776e4b17023SJohn Marino       if (CONVERT_EXPR_P (ptr)
2777e4b17023SJohn Marino           || TREE_CODE (ptr) == VIEW_CONVERT_EXPR)
2778e4b17023SJohn Marino 	{
2779e4b17023SJohn Marino 	  /* If a warning is issued, mark it to avoid duplicates from
2780e4b17023SJohn Marino 	     the backend.  This only needs to be done at
2781e4b17023SJohn Marino 	     warn_strict_aliasing > 2.  */
2782e4b17023SJohn Marino 	  if (warn_strict_aliasing > 2)
2783e4b17023SJohn Marino 	    if (strict_aliasing_warning (TREE_TYPE (TREE_OPERAND (ptr, 0)),
2784e4b17023SJohn Marino 					 type, TREE_OPERAND (ptr, 0)))
2785e4b17023SJohn Marino 	      TREE_NO_WARNING (ptr) = 1;
2786e4b17023SJohn Marino 	}
2787e4b17023SJohn Marino 
2788e4b17023SJohn Marino       if (VOID_TYPE_P (t))
2789e4b17023SJohn Marino 	{
2790e4b17023SJohn Marino 	  /* A pointer to incomplete type (other than cv void) can be
2791e4b17023SJohn Marino 	     dereferenced [expr.unary.op]/1  */
2792e4b17023SJohn Marino           if (complain & tf_error)
2793e4b17023SJohn Marino             error ("%qT is not a pointer-to-object type", type);
2794e4b17023SJohn Marino 	  return error_mark_node;
2795e4b17023SJohn Marino 	}
2796e4b17023SJohn Marino       else if (TREE_CODE (pointer) == ADDR_EXPR
2797e4b17023SJohn Marino 	       && same_type_p (t, TREE_TYPE (TREE_OPERAND (pointer, 0))))
2798e4b17023SJohn Marino 	/* The POINTER was something like `&x'.  We simplify `*&x' to
2799e4b17023SJohn Marino 	   `x'.  */
2800e4b17023SJohn Marino 	return TREE_OPERAND (pointer, 0);
2801e4b17023SJohn Marino       else
2802e4b17023SJohn Marino 	{
2803e4b17023SJohn Marino 	  tree ref = build1 (INDIRECT_REF, t, pointer);
2804e4b17023SJohn Marino 
2805e4b17023SJohn Marino 	  /* We *must* set TREE_READONLY when dereferencing a pointer to const,
2806e4b17023SJohn Marino 	     so that we get the proper error message if the result is used
2807e4b17023SJohn Marino 	     to assign to.  Also, &* is supposed to be a no-op.  */
2808e4b17023SJohn Marino 	  TREE_READONLY (ref) = CP_TYPE_CONST_P (t);
2809e4b17023SJohn Marino 	  TREE_THIS_VOLATILE (ref) = CP_TYPE_VOLATILE_P (t);
2810e4b17023SJohn Marino 	  TREE_SIDE_EFFECTS (ref)
2811e4b17023SJohn Marino 	    = (TREE_THIS_VOLATILE (ref) || TREE_SIDE_EFFECTS (pointer));
2812e4b17023SJohn Marino 	  return ref;
2813e4b17023SJohn Marino 	}
2814e4b17023SJohn Marino     }
2815e4b17023SJohn Marino   else if (!(complain & tf_error))
2816e4b17023SJohn Marino     /* Don't emit any errors; we'll just return ERROR_MARK_NODE later.  */
2817e4b17023SJohn Marino     ;
2818e4b17023SJohn Marino   /* `pointer' won't be an error_mark_node if we were given a
2819e4b17023SJohn Marino      pointer to member, so it's cool to check for this here.  */
2820e4b17023SJohn Marino   else if (TYPE_PTR_TO_MEMBER_P (type))
2821e4b17023SJohn Marino     switch (errorstring)
2822e4b17023SJohn Marino       {
2823e4b17023SJohn Marino          case RO_ARRAY_INDEXING:
2824e4b17023SJohn Marino            error ("invalid use of array indexing on pointer to member");
2825e4b17023SJohn Marino            break;
2826e4b17023SJohn Marino          case RO_UNARY_STAR:
2827e4b17023SJohn Marino            error ("invalid use of unary %<*%> on pointer to member");
2828e4b17023SJohn Marino            break;
2829e4b17023SJohn Marino          case RO_IMPLICIT_CONVERSION:
2830e4b17023SJohn Marino            error ("invalid use of implicit conversion on pointer to member");
2831e4b17023SJohn Marino            break;
2832e4b17023SJohn Marino          default:
2833e4b17023SJohn Marino            gcc_unreachable ();
2834e4b17023SJohn Marino       }
2835e4b17023SJohn Marino   else if (pointer != error_mark_node)
2836e4b17023SJohn Marino     invalid_indirection_error (input_location, type, errorstring);
2837e4b17023SJohn Marino 
2838e4b17023SJohn Marino   return error_mark_node;
2839e4b17023SJohn Marino }
2840e4b17023SJohn Marino 
2841e4b17023SJohn Marino /* This handles expressions of the form "a[i]", which denotes
2842e4b17023SJohn Marino    an array reference.
2843e4b17023SJohn Marino 
2844e4b17023SJohn Marino    This is logically equivalent in C to *(a+i), but we may do it differently.
2845e4b17023SJohn Marino    If A is a variable or a member, we generate a primitive ARRAY_REF.
2846e4b17023SJohn Marino    This avoids forcing the array out of registers, and can work on
2847e4b17023SJohn Marino    arrays that are not lvalues (for example, members of structures returned
2848e4b17023SJohn Marino    by functions).
2849e4b17023SJohn Marino 
2850e4b17023SJohn Marino    If INDEX is of some user-defined type, it must be converted to
2851e4b17023SJohn Marino    integer type.  Otherwise, to make a compatible PLUS_EXPR, it
2852e4b17023SJohn Marino    will inherit the type of the array, which will be some pointer type.
2853e4b17023SJohn Marino 
2854e4b17023SJohn Marino    LOC is the location to use in building the array reference.  */
2855e4b17023SJohn Marino 
2856e4b17023SJohn Marino tree
cp_build_array_ref(location_t loc,tree array,tree idx,tsubst_flags_t complain)2857e4b17023SJohn Marino cp_build_array_ref (location_t loc, tree array, tree idx,
2858e4b17023SJohn Marino 		    tsubst_flags_t complain)
2859e4b17023SJohn Marino {
2860e4b17023SJohn Marino   tree ret;
2861e4b17023SJohn Marino 
2862e4b17023SJohn Marino   if (idx == 0)
2863e4b17023SJohn Marino     {
2864e4b17023SJohn Marino       if (complain & tf_error)
2865e4b17023SJohn Marino 	error_at (loc, "subscript missing in array reference");
2866e4b17023SJohn Marino       return error_mark_node;
2867e4b17023SJohn Marino     }
2868e4b17023SJohn Marino 
2869e4b17023SJohn Marino   if (TREE_TYPE (array) == error_mark_node
2870e4b17023SJohn Marino       || TREE_TYPE (idx) == error_mark_node)
2871e4b17023SJohn Marino     return error_mark_node;
2872e4b17023SJohn Marino 
2873e4b17023SJohn Marino   /* If ARRAY is a COMPOUND_EXPR or COND_EXPR, move our reference
2874e4b17023SJohn Marino      inside it.  */
2875e4b17023SJohn Marino   switch (TREE_CODE (array))
2876e4b17023SJohn Marino     {
2877e4b17023SJohn Marino     case COMPOUND_EXPR:
2878e4b17023SJohn Marino       {
2879e4b17023SJohn Marino 	tree value = cp_build_array_ref (loc, TREE_OPERAND (array, 1), idx,
2880e4b17023SJohn Marino 					 complain);
2881e4b17023SJohn Marino 	ret = build2 (COMPOUND_EXPR, TREE_TYPE (value),
2882e4b17023SJohn Marino 		      TREE_OPERAND (array, 0), value);
2883e4b17023SJohn Marino 	SET_EXPR_LOCATION (ret, loc);
2884e4b17023SJohn Marino 	return ret;
2885e4b17023SJohn Marino       }
2886e4b17023SJohn Marino 
2887e4b17023SJohn Marino     case COND_EXPR:
2888e4b17023SJohn Marino       ret = build_conditional_expr
2889e4b17023SJohn Marino 	      (TREE_OPERAND (array, 0),
2890e4b17023SJohn Marino 	       cp_build_array_ref (loc, TREE_OPERAND (array, 1), idx,
2891e4b17023SJohn Marino 				   complain),
2892e4b17023SJohn Marino 	       cp_build_array_ref (loc, TREE_OPERAND (array, 2), idx,
2893e4b17023SJohn Marino 				   complain),
2894e4b17023SJohn Marino 	       tf_warning_or_error);
2895e4b17023SJohn Marino       protected_set_expr_location (ret, loc);
2896e4b17023SJohn Marino       return ret;
2897e4b17023SJohn Marino 
2898e4b17023SJohn Marino     default:
2899e4b17023SJohn Marino       break;
2900e4b17023SJohn Marino     }
2901e4b17023SJohn Marino 
2902e4b17023SJohn Marino   if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE)
2903e4b17023SJohn Marino     {
2904e4b17023SJohn Marino       tree rval, type;
2905e4b17023SJohn Marino 
2906e4b17023SJohn Marino       warn_array_subscript_with_type_char (idx);
2907e4b17023SJohn Marino 
2908e4b17023SJohn Marino       if (!INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (idx)))
2909e4b17023SJohn Marino 	{
2910e4b17023SJohn Marino 	  if (complain & tf_error)
2911e4b17023SJohn Marino 	    error_at (loc, "array subscript is not an integer");
2912e4b17023SJohn Marino 	  return error_mark_node;
2913e4b17023SJohn Marino 	}
2914e4b17023SJohn Marino 
2915e4b17023SJohn Marino       /* Apply integral promotions *after* noticing character types.
2916e4b17023SJohn Marino 	 (It is unclear why we do these promotions -- the standard
2917e4b17023SJohn Marino 	 does not say that we should.  In fact, the natural thing would
2918e4b17023SJohn Marino 	 seem to be to convert IDX to ptrdiff_t; we're performing
2919e4b17023SJohn Marino 	 pointer arithmetic.)  */
2920e4b17023SJohn Marino       idx = perform_integral_promotions (idx);
2921e4b17023SJohn Marino 
2922e4b17023SJohn Marino       /* An array that is indexed by a non-constant
2923e4b17023SJohn Marino 	 cannot be stored in a register; we must be able to do
2924e4b17023SJohn Marino 	 address arithmetic on its address.
2925e4b17023SJohn Marino 	 Likewise an array of elements of variable size.  */
2926e4b17023SJohn Marino       if (TREE_CODE (idx) != INTEGER_CST
2927e4b17023SJohn Marino 	  || (COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (array)))
2928e4b17023SJohn Marino 	      && (TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))))
2929e4b17023SJohn Marino 		  != INTEGER_CST)))
2930e4b17023SJohn Marino 	{
2931e4b17023SJohn Marino 	  if (!cxx_mark_addressable (array))
2932e4b17023SJohn Marino 	    return error_mark_node;
2933e4b17023SJohn Marino 	}
2934e4b17023SJohn Marino 
2935e4b17023SJohn Marino       /* An array that is indexed by a constant value which is not within
2936e4b17023SJohn Marino 	 the array bounds cannot be stored in a register either; because we
2937e4b17023SJohn Marino 	 would get a crash in store_bit_field/extract_bit_field when trying
2938e4b17023SJohn Marino 	 to access a non-existent part of the register.  */
2939e4b17023SJohn Marino       if (TREE_CODE (idx) == INTEGER_CST
2940e4b17023SJohn Marino 	  && TYPE_DOMAIN (TREE_TYPE (array))
2941e4b17023SJohn Marino 	  && ! int_fits_type_p (idx, TYPE_DOMAIN (TREE_TYPE (array))))
2942e4b17023SJohn Marino 	{
2943e4b17023SJohn Marino 	  if (!cxx_mark_addressable (array))
2944e4b17023SJohn Marino 	    return error_mark_node;
2945e4b17023SJohn Marino 	}
2946e4b17023SJohn Marino 
2947e4b17023SJohn Marino       if (!lvalue_p (array) && (complain & tf_error))
2948e4b17023SJohn Marino 	pedwarn (loc, OPT_pedantic,
2949e4b17023SJohn Marino 	         "ISO C++ forbids subscripting non-lvalue array");
2950e4b17023SJohn Marino 
2951e4b17023SJohn Marino       /* Note in C++ it is valid to subscript a `register' array, since
2952e4b17023SJohn Marino 	 it is valid to take the address of something with that
2953e4b17023SJohn Marino 	 storage specification.  */
2954e4b17023SJohn Marino       if (extra_warnings)
2955e4b17023SJohn Marino 	{
2956e4b17023SJohn Marino 	  tree foo = array;
2957e4b17023SJohn Marino 	  while (TREE_CODE (foo) == COMPONENT_REF)
2958e4b17023SJohn Marino 	    foo = TREE_OPERAND (foo, 0);
2959e4b17023SJohn Marino 	  if (TREE_CODE (foo) == VAR_DECL && DECL_REGISTER (foo)
2960e4b17023SJohn Marino 	      && (complain & tf_warning))
2961e4b17023SJohn Marino 	    warning_at (loc, OPT_Wextra,
2962e4b17023SJohn Marino 			"subscripting array declared %<register%>");
2963e4b17023SJohn Marino 	}
2964e4b17023SJohn Marino 
2965e4b17023SJohn Marino       type = TREE_TYPE (TREE_TYPE (array));
2966e4b17023SJohn Marino       rval = build4 (ARRAY_REF, type, array, idx, NULL_TREE, NULL_TREE);
2967e4b17023SJohn Marino       /* Array ref is const/volatile if the array elements are
2968e4b17023SJohn Marino 	 or if the array is..  */
2969e4b17023SJohn Marino       TREE_READONLY (rval)
2970e4b17023SJohn Marino 	|= (CP_TYPE_CONST_P (type) | TREE_READONLY (array));
2971e4b17023SJohn Marino       TREE_SIDE_EFFECTS (rval)
2972e4b17023SJohn Marino 	|= (CP_TYPE_VOLATILE_P (type) | TREE_SIDE_EFFECTS (array));
2973e4b17023SJohn Marino       TREE_THIS_VOLATILE (rval)
2974e4b17023SJohn Marino 	|= (CP_TYPE_VOLATILE_P (type) | TREE_THIS_VOLATILE (array));
2975e4b17023SJohn Marino       ret = require_complete_type_sfinae (fold_if_not_in_template (rval),
2976e4b17023SJohn Marino 					  complain);
2977e4b17023SJohn Marino       protected_set_expr_location (ret, loc);
2978e4b17023SJohn Marino       return ret;
2979e4b17023SJohn Marino     }
2980e4b17023SJohn Marino 
2981e4b17023SJohn Marino   {
2982e4b17023SJohn Marino     tree ar = default_conversion (array);
2983e4b17023SJohn Marino     tree ind = default_conversion (idx);
2984e4b17023SJohn Marino 
2985e4b17023SJohn Marino     /* Put the integer in IND to simplify error checking.  */
2986e4b17023SJohn Marino     if (TREE_CODE (TREE_TYPE (ar)) == INTEGER_TYPE)
2987e4b17023SJohn Marino       {
2988e4b17023SJohn Marino 	tree temp = ar;
2989e4b17023SJohn Marino 	ar = ind;
2990e4b17023SJohn Marino 	ind = temp;
2991e4b17023SJohn Marino       }
2992e4b17023SJohn Marino 
2993e4b17023SJohn Marino     if (ar == error_mark_node)
2994e4b17023SJohn Marino       return ar;
2995e4b17023SJohn Marino 
2996e4b17023SJohn Marino     if (TREE_CODE (TREE_TYPE (ar)) != POINTER_TYPE)
2997e4b17023SJohn Marino       {
2998e4b17023SJohn Marino 	if (complain & tf_error)
2999e4b17023SJohn Marino 	  error_at (loc, "subscripted value is neither array nor pointer");
3000e4b17023SJohn Marino 	return error_mark_node;
3001e4b17023SJohn Marino       }
3002e4b17023SJohn Marino     if (TREE_CODE (TREE_TYPE (ind)) != INTEGER_TYPE)
3003e4b17023SJohn Marino       {
3004e4b17023SJohn Marino 	if (complain & tf_error)
3005e4b17023SJohn Marino 	  error_at (loc, "array subscript is not an integer");
3006e4b17023SJohn Marino 	return error_mark_node;
3007e4b17023SJohn Marino       }
3008e4b17023SJohn Marino 
3009e4b17023SJohn Marino     warn_array_subscript_with_type_char (idx);
3010e4b17023SJohn Marino 
3011e4b17023SJohn Marino     ret = cp_build_indirect_ref (cp_build_binary_op (input_location,
3012e4b17023SJohn Marino 						     PLUS_EXPR, ar, ind,
3013e4b17023SJohn Marino 						     complain),
3014e4b17023SJohn Marino                                  RO_ARRAY_INDEXING,
3015e4b17023SJohn Marino                                  complain);
3016e4b17023SJohn Marino     protected_set_expr_location (ret, loc);
3017e4b17023SJohn Marino     return ret;
3018e4b17023SJohn Marino   }
3019e4b17023SJohn Marino }
3020e4b17023SJohn Marino 
3021e4b17023SJohn Marino /* Entry point for Obj-C++.  */
3022e4b17023SJohn Marino 
3023e4b17023SJohn Marino tree
build_array_ref(location_t loc,tree array,tree idx)3024e4b17023SJohn Marino build_array_ref (location_t loc, tree array, tree idx)
3025e4b17023SJohn Marino {
3026e4b17023SJohn Marino   return cp_build_array_ref (loc, array, idx, tf_warning_or_error);
3027e4b17023SJohn Marino }
3028e4b17023SJohn Marino 
3029e4b17023SJohn Marino /* Resolve a pointer to member function.  INSTANCE is the object
3030e4b17023SJohn Marino    instance to use, if the member points to a virtual member.
3031e4b17023SJohn Marino 
3032e4b17023SJohn Marino    This used to avoid checking for virtual functions if basetype
3033e4b17023SJohn Marino    has no virtual functions, according to an earlier ANSI draft.
3034e4b17023SJohn Marino    With the final ISO C++ rules, such an optimization is
3035e4b17023SJohn Marino    incorrect: A pointer to a derived member can be static_cast
3036e4b17023SJohn Marino    to pointer-to-base-member, as long as the dynamic object
3037e4b17023SJohn Marino    later has the right member.  */
3038e4b17023SJohn Marino 
3039e4b17023SJohn Marino tree
get_member_function_from_ptrfunc(tree * instance_ptrptr,tree function)3040e4b17023SJohn Marino get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function)
3041e4b17023SJohn Marino {
3042e4b17023SJohn Marino   if (TREE_CODE (function) == OFFSET_REF)
3043e4b17023SJohn Marino     function = TREE_OPERAND (function, 1);
3044e4b17023SJohn Marino 
3045e4b17023SJohn Marino   if (TYPE_PTRMEMFUNC_P (TREE_TYPE (function)))
3046e4b17023SJohn Marino     {
3047e4b17023SJohn Marino       tree idx, delta, e1, e2, e3, vtbl, basetype;
3048e4b17023SJohn Marino       tree fntype = TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (function));
3049e4b17023SJohn Marino 
3050e4b17023SJohn Marino       tree instance_ptr = *instance_ptrptr;
3051e4b17023SJohn Marino       tree instance_save_expr = 0;
3052e4b17023SJohn Marino       if (instance_ptr == error_mark_node)
3053e4b17023SJohn Marino 	{
3054e4b17023SJohn Marino 	  if (TREE_CODE (function) == PTRMEM_CST)
3055e4b17023SJohn Marino 	    {
3056e4b17023SJohn Marino 	      /* Extracting the function address from a pmf is only
3057e4b17023SJohn Marino 		 allowed with -Wno-pmf-conversions. It only works for
3058e4b17023SJohn Marino 		 pmf constants.  */
3059e4b17023SJohn Marino 	      e1 = build_addr_func (PTRMEM_CST_MEMBER (function));
3060e4b17023SJohn Marino 	      e1 = convert (fntype, e1);
3061e4b17023SJohn Marino 	      return e1;
3062e4b17023SJohn Marino 	    }
3063e4b17023SJohn Marino 	  else
3064e4b17023SJohn Marino 	    {
3065e4b17023SJohn Marino 	      error ("object missing in use of %qE", function);
3066e4b17023SJohn Marino 	      return error_mark_node;
3067e4b17023SJohn Marino 	    }
3068e4b17023SJohn Marino 	}
3069e4b17023SJohn Marino 
3070e4b17023SJohn Marino       if (TREE_SIDE_EFFECTS (instance_ptr))
3071e4b17023SJohn Marino 	instance_ptr = instance_save_expr = save_expr (instance_ptr);
3072e4b17023SJohn Marino 
3073e4b17023SJohn Marino       if (TREE_SIDE_EFFECTS (function))
3074e4b17023SJohn Marino 	function = save_expr (function);
3075e4b17023SJohn Marino 
3076e4b17023SJohn Marino       /* Start by extracting all the information from the PMF itself.  */
3077e4b17023SJohn Marino       e3 = pfn_from_ptrmemfunc (function);
3078e4b17023SJohn Marino       delta = delta_from_ptrmemfunc (function);
3079e4b17023SJohn Marino       idx = build1 (NOP_EXPR, vtable_index_type, e3);
3080e4b17023SJohn Marino       switch (TARGET_PTRMEMFUNC_VBIT_LOCATION)
3081e4b17023SJohn Marino 	{
3082e4b17023SJohn Marino 	case ptrmemfunc_vbit_in_pfn:
3083e4b17023SJohn Marino 	  e1 = cp_build_binary_op (input_location,
3084e4b17023SJohn Marino 				   BIT_AND_EXPR, idx, integer_one_node,
3085e4b17023SJohn Marino 				   tf_warning_or_error);
3086e4b17023SJohn Marino 	  idx = cp_build_binary_op (input_location,
3087e4b17023SJohn Marino 				    MINUS_EXPR, idx, integer_one_node,
3088e4b17023SJohn Marino 				    tf_warning_or_error);
3089e4b17023SJohn Marino 	  break;
3090e4b17023SJohn Marino 
3091e4b17023SJohn Marino 	case ptrmemfunc_vbit_in_delta:
3092e4b17023SJohn Marino 	  e1 = cp_build_binary_op (input_location,
3093e4b17023SJohn Marino 				   BIT_AND_EXPR, delta, integer_one_node,
3094e4b17023SJohn Marino 				   tf_warning_or_error);
3095e4b17023SJohn Marino 	  delta = cp_build_binary_op (input_location,
3096e4b17023SJohn Marino 				      RSHIFT_EXPR, delta, integer_one_node,
3097e4b17023SJohn Marino 				      tf_warning_or_error);
3098e4b17023SJohn Marino 	  break;
3099e4b17023SJohn Marino 
3100e4b17023SJohn Marino 	default:
3101e4b17023SJohn Marino 	  gcc_unreachable ();
3102e4b17023SJohn Marino 	}
3103e4b17023SJohn Marino 
3104e4b17023SJohn Marino       /* Convert down to the right base before using the instance.  A
3105e4b17023SJohn Marino 	 special case is that in a pointer to member of class C, C may
3106e4b17023SJohn Marino 	 be incomplete.  In that case, the function will of course be
3107e4b17023SJohn Marino 	 a member of C, and no conversion is required.  In fact,
3108e4b17023SJohn Marino 	 lookup_base will fail in that case, because incomplete
3109e4b17023SJohn Marino 	 classes do not have BINFOs.  */
3110e4b17023SJohn Marino       basetype = TYPE_METHOD_BASETYPE (TREE_TYPE (fntype));
3111e4b17023SJohn Marino       if (!same_type_ignoring_top_level_qualifiers_p
3112e4b17023SJohn Marino 	  (basetype, TREE_TYPE (TREE_TYPE (instance_ptr))))
3113e4b17023SJohn Marino 	{
3114e4b17023SJohn Marino 	  basetype = lookup_base (TREE_TYPE (TREE_TYPE (instance_ptr)),
3115e4b17023SJohn Marino 				  basetype, ba_check, NULL);
3116e4b17023SJohn Marino 	  instance_ptr = build_base_path (PLUS_EXPR, instance_ptr, basetype,
3117e4b17023SJohn Marino 					  1, tf_warning_or_error);
3118e4b17023SJohn Marino 	  if (instance_ptr == error_mark_node)
3119e4b17023SJohn Marino 	    return error_mark_node;
3120e4b17023SJohn Marino 	}
3121e4b17023SJohn Marino       /* ...and then the delta in the PMF.  */
31225ce9237cSJohn Marino       instance_ptr = build2 (POINTER_PLUS_EXPR, TREE_TYPE (instance_ptr),
31235ce9237cSJohn Marino 			     instance_ptr, fold_convert (sizetype, delta));
3124e4b17023SJohn Marino 
3125e4b17023SJohn Marino       /* Hand back the adjusted 'this' argument to our caller.  */
3126e4b17023SJohn Marino       *instance_ptrptr = instance_ptr;
3127e4b17023SJohn Marino 
3128e4b17023SJohn Marino       /* Next extract the vtable pointer from the object.  */
3129e4b17023SJohn Marino       vtbl = build1 (NOP_EXPR, build_pointer_type (vtbl_ptr_type_node),
3130e4b17023SJohn Marino 		     instance_ptr);
3131e4b17023SJohn Marino       vtbl = cp_build_indirect_ref (vtbl, RO_NULL, tf_warning_or_error);
3132e4b17023SJohn Marino       /* If the object is not dynamic the access invokes undefined
3133e4b17023SJohn Marino 	 behavior.  As it is not executed in this case silence the
3134e4b17023SJohn Marino 	 spurious warnings it may provoke.  */
3135e4b17023SJohn Marino       TREE_NO_WARNING (vtbl) = 1;
3136e4b17023SJohn Marino 
3137e4b17023SJohn Marino       /* Finally, extract the function pointer from the vtable.  */
3138e4b17023SJohn Marino       e2 = fold_build_pointer_plus_loc (input_location, vtbl, idx);
3139e4b17023SJohn Marino       e2 = cp_build_indirect_ref (e2, RO_NULL, tf_warning_or_error);
3140e4b17023SJohn Marino       TREE_CONSTANT (e2) = 1;
3141e4b17023SJohn Marino 
3142e4b17023SJohn Marino       /* When using function descriptors, the address of the
3143e4b17023SJohn Marino 	 vtable entry is treated as a function pointer.  */
3144e4b17023SJohn Marino       if (TARGET_VTABLE_USES_DESCRIPTORS)
3145e4b17023SJohn Marino 	e2 = build1 (NOP_EXPR, TREE_TYPE (e2),
3146e4b17023SJohn Marino 		     cp_build_addr_expr (e2, tf_warning_or_error));
3147e4b17023SJohn Marino 
3148e4b17023SJohn Marino       e2 = fold_convert (TREE_TYPE (e3), e2);
3149e4b17023SJohn Marino       e1 = build_conditional_expr (e1, e2, e3, tf_warning_or_error);
3150e4b17023SJohn Marino 
3151e4b17023SJohn Marino       /* Make sure this doesn't get evaluated first inside one of the
3152e4b17023SJohn Marino 	 branches of the COND_EXPR.  */
3153e4b17023SJohn Marino       if (instance_save_expr)
3154e4b17023SJohn Marino 	e1 = build2 (COMPOUND_EXPR, TREE_TYPE (e1),
3155e4b17023SJohn Marino 		     instance_save_expr, e1);
3156e4b17023SJohn Marino 
3157e4b17023SJohn Marino       function = e1;
3158e4b17023SJohn Marino     }
3159e4b17023SJohn Marino   return function;
3160e4b17023SJohn Marino }
3161e4b17023SJohn Marino 
3162e4b17023SJohn Marino /* Used by the C-common bits.  */
3163e4b17023SJohn Marino tree
build_function_call(location_t loc ATTRIBUTE_UNUSED,tree function,tree params)3164e4b17023SJohn Marino build_function_call (location_t loc ATTRIBUTE_UNUSED,
3165e4b17023SJohn Marino 		     tree function, tree params)
3166e4b17023SJohn Marino {
3167e4b17023SJohn Marino   return cp_build_function_call (function, params, tf_warning_or_error);
3168e4b17023SJohn Marino }
3169e4b17023SJohn Marino 
3170e4b17023SJohn Marino /* Used by the C-common bits.  */
3171e4b17023SJohn Marino tree
build_function_call_vec(location_t loc ATTRIBUTE_UNUSED,tree function,VEC (tree,gc)* params,VEC (tree,gc)* origtypes ATTRIBUTE_UNUSED)3172e4b17023SJohn Marino build_function_call_vec (location_t loc ATTRIBUTE_UNUSED,
3173e4b17023SJohn Marino 			 tree function, VEC(tree,gc) *params,
3174e4b17023SJohn Marino 			 VEC(tree,gc) *origtypes ATTRIBUTE_UNUSED)
3175e4b17023SJohn Marino {
3176e4b17023SJohn Marino   VEC(tree,gc) *orig_params = params;
3177e4b17023SJohn Marino   tree ret = cp_build_function_call_vec (function, &params,
3178e4b17023SJohn Marino 					 tf_warning_or_error);
3179e4b17023SJohn Marino 
3180e4b17023SJohn Marino   /* cp_build_function_call_vec can reallocate PARAMS by adding
3181e4b17023SJohn Marino      default arguments.  That should never happen here.  Verify
3182e4b17023SJohn Marino      that.  */
3183e4b17023SJohn Marino   gcc_assert (params == orig_params);
3184e4b17023SJohn Marino 
3185e4b17023SJohn Marino   return ret;
3186e4b17023SJohn Marino }
3187e4b17023SJohn Marino 
3188e4b17023SJohn Marino /* Build a function call using a tree list of arguments.  */
3189e4b17023SJohn Marino 
3190e4b17023SJohn Marino tree
cp_build_function_call(tree function,tree params,tsubst_flags_t complain)3191e4b17023SJohn Marino cp_build_function_call (tree function, tree params, tsubst_flags_t complain)
3192e4b17023SJohn Marino {
3193e4b17023SJohn Marino   VEC(tree,gc) *vec;
3194e4b17023SJohn Marino   tree ret;
3195e4b17023SJohn Marino 
3196e4b17023SJohn Marino   vec = make_tree_vector ();
3197e4b17023SJohn Marino   for (; params != NULL_TREE; params = TREE_CHAIN (params))
3198e4b17023SJohn Marino     VEC_safe_push (tree, gc, vec, TREE_VALUE (params));
3199e4b17023SJohn Marino   ret = cp_build_function_call_vec (function, &vec, complain);
3200e4b17023SJohn Marino   release_tree_vector (vec);
3201e4b17023SJohn Marino   return ret;
3202e4b17023SJohn Marino }
3203e4b17023SJohn Marino 
3204e4b17023SJohn Marino /* Build a function call using varargs.  */
3205e4b17023SJohn Marino 
3206e4b17023SJohn Marino tree
cp_build_function_call_nary(tree function,tsubst_flags_t complain,...)3207e4b17023SJohn Marino cp_build_function_call_nary (tree function, tsubst_flags_t complain, ...)
3208e4b17023SJohn Marino {
3209e4b17023SJohn Marino   VEC(tree,gc) *vec;
3210e4b17023SJohn Marino   va_list args;
3211e4b17023SJohn Marino   tree ret, t;
3212e4b17023SJohn Marino 
3213e4b17023SJohn Marino   vec = make_tree_vector ();
3214e4b17023SJohn Marino   va_start (args, complain);
3215e4b17023SJohn Marino   for (t = va_arg (args, tree); t != NULL_TREE; t = va_arg (args, tree))
3216e4b17023SJohn Marino     VEC_safe_push (tree, gc, vec, t);
3217e4b17023SJohn Marino   va_end (args);
3218e4b17023SJohn Marino   ret = cp_build_function_call_vec (function, &vec, complain);
3219e4b17023SJohn Marino   release_tree_vector (vec);
3220e4b17023SJohn Marino   return ret;
3221e4b17023SJohn Marino }
3222e4b17023SJohn Marino 
3223e4b17023SJohn Marino /* Build a function call using a vector of arguments.  PARAMS may be
3224e4b17023SJohn Marino    NULL if there are no parameters.  This changes the contents of
3225e4b17023SJohn Marino    PARAMS.  */
3226e4b17023SJohn Marino 
3227e4b17023SJohn Marino tree
cp_build_function_call_vec(tree function,VEC (tree,gc)** params,tsubst_flags_t complain)3228e4b17023SJohn Marino cp_build_function_call_vec (tree function, VEC(tree,gc) **params,
3229e4b17023SJohn Marino 			    tsubst_flags_t complain)
3230e4b17023SJohn Marino {
3231e4b17023SJohn Marino   tree fntype, fndecl;
3232e4b17023SJohn Marino   int is_method;
3233e4b17023SJohn Marino   tree original = function;
3234e4b17023SJohn Marino   int nargs;
3235e4b17023SJohn Marino   tree *argarray;
3236e4b17023SJohn Marino   tree parm_types;
3237e4b17023SJohn Marino   VEC(tree,gc) *allocated = NULL;
3238e4b17023SJohn Marino   tree ret;
3239e4b17023SJohn Marino 
3240e4b17023SJohn Marino   /* For Objective-C, convert any calls via a cast to OBJC_TYPE_REF
3241e4b17023SJohn Marino      expressions, like those used for ObjC messenger dispatches.  */
3242e4b17023SJohn Marino   if (params != NULL && !VEC_empty (tree, *params))
3243e4b17023SJohn Marino     function = objc_rewrite_function_call (function,
3244e4b17023SJohn Marino 					   VEC_index (tree, *params, 0));
3245e4b17023SJohn Marino 
3246e4b17023SJohn Marino   /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
3247e4b17023SJohn Marino      Strip such NOP_EXPRs, since FUNCTION is used in non-lvalue context.  */
3248e4b17023SJohn Marino   if (TREE_CODE (function) == NOP_EXPR
3249e4b17023SJohn Marino       && TREE_TYPE (function) == TREE_TYPE (TREE_OPERAND (function, 0)))
3250e4b17023SJohn Marino     function = TREE_OPERAND (function, 0);
3251e4b17023SJohn Marino 
3252e4b17023SJohn Marino   if (TREE_CODE (function) == FUNCTION_DECL)
3253e4b17023SJohn Marino     {
3254e4b17023SJohn Marino       mark_used (function);
3255e4b17023SJohn Marino       fndecl = function;
3256e4b17023SJohn Marino 
3257e4b17023SJohn Marino       /* Convert anything with function type to a pointer-to-function.  */
3258e4b17023SJohn Marino       if (DECL_MAIN_P (function) && (complain & tf_error))
3259e4b17023SJohn Marino 	pedwarn (input_location, OPT_pedantic,
3260e4b17023SJohn Marino 		 "ISO C++ forbids calling %<::main%> from within program");
3261e4b17023SJohn Marino 
3262e4b17023SJohn Marino       function = build_addr_func (function);
3263e4b17023SJohn Marino     }
3264e4b17023SJohn Marino   else
3265e4b17023SJohn Marino     {
3266e4b17023SJohn Marino       fndecl = NULL_TREE;
3267e4b17023SJohn Marino 
3268e4b17023SJohn Marino       function = build_addr_func (function);
3269e4b17023SJohn Marino     }
3270e4b17023SJohn Marino 
3271e4b17023SJohn Marino   if (function == error_mark_node)
3272e4b17023SJohn Marino     return error_mark_node;
3273e4b17023SJohn Marino 
3274e4b17023SJohn Marino   fntype = TREE_TYPE (function);
3275e4b17023SJohn Marino 
3276e4b17023SJohn Marino   if (TYPE_PTRMEMFUNC_P (fntype))
3277e4b17023SJohn Marino     {
3278e4b17023SJohn Marino       if (complain & tf_error)
3279e4b17023SJohn Marino 	error ("must use %<.*%> or %<->*%> to call pointer-to-member "
3280e4b17023SJohn Marino 	       "function in %<%E (...)%>, e.g. %<(... ->* %E) (...)%>",
3281e4b17023SJohn Marino 	       original, original);
3282e4b17023SJohn Marino       return error_mark_node;
3283e4b17023SJohn Marino     }
3284e4b17023SJohn Marino 
3285e4b17023SJohn Marino   is_method = (TREE_CODE (fntype) == POINTER_TYPE
3286e4b17023SJohn Marino 	       && TREE_CODE (TREE_TYPE (fntype)) == METHOD_TYPE);
3287e4b17023SJohn Marino 
3288e4b17023SJohn Marino   if (!((TREE_CODE (fntype) == POINTER_TYPE
3289e4b17023SJohn Marino 	 && TREE_CODE (TREE_TYPE (fntype)) == FUNCTION_TYPE)
3290e4b17023SJohn Marino 	|| is_method
3291e4b17023SJohn Marino 	|| TREE_CODE (function) == TEMPLATE_ID_EXPR))
3292e4b17023SJohn Marino     {
3293e4b17023SJohn Marino       if (complain & tf_error)
3294e4b17023SJohn Marino 	error ("%qE cannot be used as a function", original);
3295e4b17023SJohn Marino       return error_mark_node;
3296e4b17023SJohn Marino     }
3297e4b17023SJohn Marino 
3298e4b17023SJohn Marino   /* fntype now gets the type of function pointed to.  */
3299e4b17023SJohn Marino   fntype = TREE_TYPE (fntype);
3300e4b17023SJohn Marino   parm_types = TYPE_ARG_TYPES (fntype);
3301e4b17023SJohn Marino 
3302e4b17023SJohn Marino   if (params == NULL)
3303e4b17023SJohn Marino     {
3304e4b17023SJohn Marino       allocated = make_tree_vector ();
3305e4b17023SJohn Marino       params = &allocated;
3306e4b17023SJohn Marino     }
3307e4b17023SJohn Marino 
3308e4b17023SJohn Marino   nargs = convert_arguments (parm_types, params, fndecl, LOOKUP_NORMAL,
3309e4b17023SJohn Marino 			     complain);
3310e4b17023SJohn Marino   if (nargs < 0)
3311e4b17023SJohn Marino     return error_mark_node;
3312e4b17023SJohn Marino 
3313e4b17023SJohn Marino   argarray = VEC_address (tree, *params);
3314e4b17023SJohn Marino 
3315e4b17023SJohn Marino   /* Check for errors in format strings and inappropriately
3316e4b17023SJohn Marino      null parameters.  */
3317e4b17023SJohn Marino   check_function_arguments (fntype, nargs, argarray);
3318e4b17023SJohn Marino 
3319e4b17023SJohn Marino   ret = build_cxx_call (function, nargs, argarray);
3320e4b17023SJohn Marino 
3321e4b17023SJohn Marino   if (allocated != NULL)
3322e4b17023SJohn Marino     release_tree_vector (allocated);
3323e4b17023SJohn Marino 
3324e4b17023SJohn Marino   return ret;
3325e4b17023SJohn Marino }
3326e4b17023SJohn Marino 
3327e4b17023SJohn Marino /* Subroutine of convert_arguments.
3328e4b17023SJohn Marino    Warn about wrong number of args are genereted. */
3329e4b17023SJohn Marino 
3330e4b17023SJohn Marino static void
warn_args_num(location_t loc,tree fndecl,bool too_many_p)3331e4b17023SJohn Marino warn_args_num (location_t loc, tree fndecl, bool too_many_p)
3332e4b17023SJohn Marino {
3333e4b17023SJohn Marino   if (fndecl)
3334e4b17023SJohn Marino     {
3335e4b17023SJohn Marino       if (TREE_CODE (TREE_TYPE (fndecl)) == METHOD_TYPE)
3336e4b17023SJohn Marino 	{
3337e4b17023SJohn Marino 	  if (DECL_NAME (fndecl) == NULL_TREE
3338e4b17023SJohn Marino 	      || IDENTIFIER_HAS_TYPE_VALUE (DECL_NAME (fndecl)))
3339e4b17023SJohn Marino 	    error_at (loc,
3340e4b17023SJohn Marino 		      too_many_p
3341e4b17023SJohn Marino 		      ? G_("too many arguments to constructor %q#D")
3342e4b17023SJohn Marino 		      : G_("too few arguments to constructor %q#D"),
3343e4b17023SJohn Marino 		      fndecl);
3344e4b17023SJohn Marino 	  else
3345e4b17023SJohn Marino 	    error_at (loc,
3346e4b17023SJohn Marino 		      too_many_p
3347e4b17023SJohn Marino 		      ? G_("too many arguments to member function %q#D")
3348e4b17023SJohn Marino 		      : G_("too few arguments to member function %q#D"),
3349e4b17023SJohn Marino 		      fndecl);
3350e4b17023SJohn Marino 	}
3351e4b17023SJohn Marino       else
3352e4b17023SJohn Marino 	error_at (loc,
3353e4b17023SJohn Marino 		  too_many_p
3354e4b17023SJohn Marino 		  ? G_("too many arguments to function %q#D")
3355e4b17023SJohn Marino 		  : G_("too few arguments to function %q#D"),
3356e4b17023SJohn Marino 		  fndecl);
3357e4b17023SJohn Marino       inform (DECL_SOURCE_LOCATION (fndecl),
3358e4b17023SJohn Marino 	      "declared here");
3359e4b17023SJohn Marino     }
3360e4b17023SJohn Marino   else
3361e4b17023SJohn Marino     {
3362e4b17023SJohn Marino       if (c_dialect_objc ()  &&  objc_message_selector ())
3363e4b17023SJohn Marino 	error_at (loc,
3364e4b17023SJohn Marino 		  too_many_p
3365e4b17023SJohn Marino 		  ? G_("too many arguments to method %q#D")
3366e4b17023SJohn Marino 		  : G_("too few arguments to method %q#D"),
3367e4b17023SJohn Marino 		  objc_message_selector ());
3368e4b17023SJohn Marino       else
3369e4b17023SJohn Marino 	error_at (loc, too_many_p ? G_("too many arguments to function")
3370e4b17023SJohn Marino 		                  : G_("too few arguments to function"));
3371e4b17023SJohn Marino     }
3372e4b17023SJohn Marino }
3373e4b17023SJohn Marino 
3374e4b17023SJohn Marino /* Convert the actual parameter expressions in the list VALUES to the
3375e4b17023SJohn Marino    types in the list TYPELIST.  The converted expressions are stored
3376e4b17023SJohn Marino    back in the VALUES vector.
3377e4b17023SJohn Marino    If parmdecls is exhausted, or when an element has NULL as its type,
3378e4b17023SJohn Marino    perform the default conversions.
3379e4b17023SJohn Marino 
3380e4b17023SJohn Marino    NAME is an IDENTIFIER_NODE or 0.  It is used only for error messages.
3381e4b17023SJohn Marino 
3382e4b17023SJohn Marino    This is also where warnings about wrong number of args are generated.
3383e4b17023SJohn Marino 
3384e4b17023SJohn Marino    Returns the actual number of arguments processed (which might be less
3385e4b17023SJohn Marino    than the length of the vector), or -1 on error.
3386e4b17023SJohn Marino 
3387e4b17023SJohn Marino    In C++, unspecified trailing parameters can be filled in with their
3388e4b17023SJohn Marino    default arguments, if such were specified.  Do so here.  */
3389e4b17023SJohn Marino 
3390e4b17023SJohn Marino static int
convert_arguments(tree typelist,VEC (tree,gc)** values,tree fndecl,int flags,tsubst_flags_t complain)3391e4b17023SJohn Marino convert_arguments (tree typelist, VEC(tree,gc) **values, tree fndecl,
3392e4b17023SJohn Marino 		   int flags, tsubst_flags_t complain)
3393e4b17023SJohn Marino {
3394e4b17023SJohn Marino   tree typetail;
3395e4b17023SJohn Marino   unsigned int i;
3396e4b17023SJohn Marino 
3397e4b17023SJohn Marino   /* Argument passing is always copy-initialization.  */
3398e4b17023SJohn Marino   flags |= LOOKUP_ONLYCONVERTING;
3399e4b17023SJohn Marino 
3400e4b17023SJohn Marino   for (i = 0, typetail = typelist;
3401e4b17023SJohn Marino        i < VEC_length (tree, *values);
3402e4b17023SJohn Marino        i++)
3403e4b17023SJohn Marino     {
3404e4b17023SJohn Marino       tree type = typetail ? TREE_VALUE (typetail) : 0;
3405e4b17023SJohn Marino       tree val = VEC_index (tree, *values, i);
3406e4b17023SJohn Marino 
3407e4b17023SJohn Marino       if (val == error_mark_node || type == error_mark_node)
3408e4b17023SJohn Marino 	return -1;
3409e4b17023SJohn Marino 
3410e4b17023SJohn Marino       if (type == void_type_node)
3411e4b17023SJohn Marino 	{
3412e4b17023SJohn Marino           if (complain & tf_error)
3413e4b17023SJohn Marino             {
3414e4b17023SJohn Marino 	      warn_args_num (input_location, fndecl, /*too_many_p=*/true);
3415e4b17023SJohn Marino               return i;
3416e4b17023SJohn Marino             }
3417e4b17023SJohn Marino           else
3418e4b17023SJohn Marino             return -1;
3419e4b17023SJohn Marino 	}
3420e4b17023SJohn Marino 
3421e4b17023SJohn Marino       /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
3422e4b17023SJohn Marino 	 Strip such NOP_EXPRs, since VAL is used in non-lvalue context.  */
3423e4b17023SJohn Marino       if (TREE_CODE (val) == NOP_EXPR
3424e4b17023SJohn Marino 	  && TREE_TYPE (val) == TREE_TYPE (TREE_OPERAND (val, 0))
3425e4b17023SJohn Marino 	  && (type == 0 || TREE_CODE (type) != REFERENCE_TYPE))
3426e4b17023SJohn Marino 	val = TREE_OPERAND (val, 0);
3427e4b17023SJohn Marino 
3428e4b17023SJohn Marino       if (type == 0 || TREE_CODE (type) != REFERENCE_TYPE)
3429e4b17023SJohn Marino 	{
3430e4b17023SJohn Marino 	  if (TREE_CODE (TREE_TYPE (val)) == ARRAY_TYPE
3431e4b17023SJohn Marino 	      || TREE_CODE (TREE_TYPE (val)) == FUNCTION_TYPE
3432e4b17023SJohn Marino 	      || TREE_CODE (TREE_TYPE (val)) == METHOD_TYPE)
3433e4b17023SJohn Marino 	    val = decay_conversion (val);
3434e4b17023SJohn Marino 	}
3435e4b17023SJohn Marino 
3436e4b17023SJohn Marino       if (val == error_mark_node)
3437e4b17023SJohn Marino 	return -1;
3438e4b17023SJohn Marino 
3439e4b17023SJohn Marino       if (type != 0)
3440e4b17023SJohn Marino 	{
3441e4b17023SJohn Marino 	  /* Formal parm type is specified by a function prototype.  */
3442e4b17023SJohn Marino 	  tree parmval;
3443e4b17023SJohn Marino 
3444e4b17023SJohn Marino 	  if (!COMPLETE_TYPE_P (complete_type (type)))
3445e4b17023SJohn Marino 	    {
3446e4b17023SJohn Marino               if (complain & tf_error)
3447e4b17023SJohn Marino                 {
3448e4b17023SJohn Marino                   if (fndecl)
3449e4b17023SJohn Marino                     error ("parameter %P of %qD has incomplete type %qT",
3450e4b17023SJohn Marino                            i, fndecl, type);
3451e4b17023SJohn Marino                   else
3452e4b17023SJohn Marino                     error ("parameter %P has incomplete type %qT", i, type);
3453e4b17023SJohn Marino                 }
3454e4b17023SJohn Marino 	      parmval = error_mark_node;
3455e4b17023SJohn Marino 	    }
3456e4b17023SJohn Marino 	  else
3457e4b17023SJohn Marino 	    {
3458e4b17023SJohn Marino 	      parmval = convert_for_initialization
3459e4b17023SJohn Marino 		(NULL_TREE, type, val, flags,
3460e4b17023SJohn Marino 		 ICR_ARGPASS, fndecl, i, complain);
3461e4b17023SJohn Marino 	      parmval = convert_for_arg_passing (type, parmval);
3462e4b17023SJohn Marino 	    }
3463e4b17023SJohn Marino 
3464e4b17023SJohn Marino 	  if (parmval == error_mark_node)
3465e4b17023SJohn Marino 	    return -1;
3466e4b17023SJohn Marino 
3467e4b17023SJohn Marino 	  VEC_replace (tree, *values, i, parmval);
3468e4b17023SJohn Marino 	}
3469e4b17023SJohn Marino       else
3470e4b17023SJohn Marino 	{
3471e4b17023SJohn Marino 	  if (fndecl && DECL_BUILT_IN (fndecl)
3472e4b17023SJohn Marino 	      && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CONSTANT_P)
3473e4b17023SJohn Marino 	    /* Don't do ellipsis conversion for __built_in_constant_p
3474e4b17023SJohn Marino 	       as this will result in spurious errors for non-trivial
3475e4b17023SJohn Marino 	       types.  */
3476e4b17023SJohn Marino 	    val = require_complete_type_sfinae (val, complain);
3477e4b17023SJohn Marino 	  else
3478e4b17023SJohn Marino 	    val = convert_arg_to_ellipsis (val);
3479e4b17023SJohn Marino 
3480e4b17023SJohn Marino 	  VEC_replace (tree, *values, i, val);
3481e4b17023SJohn Marino 	}
3482e4b17023SJohn Marino 
3483e4b17023SJohn Marino       if (typetail)
3484e4b17023SJohn Marino 	typetail = TREE_CHAIN (typetail);
3485e4b17023SJohn Marino     }
3486e4b17023SJohn Marino 
3487e4b17023SJohn Marino   if (typetail != 0 && typetail != void_list_node)
3488e4b17023SJohn Marino     {
3489e4b17023SJohn Marino       /* See if there are default arguments that can be used.  Because
3490e4b17023SJohn Marino 	 we hold default arguments in the FUNCTION_TYPE (which is so
3491e4b17023SJohn Marino 	 wrong), we can see default parameters here from deduced
3492e4b17023SJohn Marino 	 contexts (and via typeof) for indirect function calls.
3493e4b17023SJohn Marino 	 Fortunately we know whether we have a function decl to
3494e4b17023SJohn Marino 	 provide default arguments in a language conformant
3495e4b17023SJohn Marino 	 manner.  */
3496e4b17023SJohn Marino       if (fndecl && TREE_PURPOSE (typetail)
3497e4b17023SJohn Marino 	  && TREE_CODE (TREE_PURPOSE (typetail)) != DEFAULT_ARG)
3498e4b17023SJohn Marino 	{
3499e4b17023SJohn Marino 	  for (; typetail != void_list_node; ++i)
3500e4b17023SJohn Marino 	    {
3501e4b17023SJohn Marino 	      tree parmval
3502e4b17023SJohn Marino 		= convert_default_arg (TREE_VALUE (typetail),
3503e4b17023SJohn Marino 				       TREE_PURPOSE (typetail),
3504e4b17023SJohn Marino 				       fndecl, i);
3505e4b17023SJohn Marino 
3506e4b17023SJohn Marino 	      if (parmval == error_mark_node)
3507e4b17023SJohn Marino 		return -1;
3508e4b17023SJohn Marino 
3509e4b17023SJohn Marino 	      VEC_safe_push (tree, gc, *values, parmval);
3510e4b17023SJohn Marino 	      typetail = TREE_CHAIN (typetail);
3511e4b17023SJohn Marino 	      /* ends with `...'.  */
3512e4b17023SJohn Marino 	      if (typetail == NULL_TREE)
3513e4b17023SJohn Marino 		break;
3514e4b17023SJohn Marino 	    }
3515e4b17023SJohn Marino 	}
3516e4b17023SJohn Marino       else
3517e4b17023SJohn Marino 	{
3518e4b17023SJohn Marino           if (complain & tf_error)
3519e4b17023SJohn Marino 	    warn_args_num (input_location, fndecl, /*too_many_p=*/false);
3520e4b17023SJohn Marino 	  return -1;
3521e4b17023SJohn Marino 	}
3522e4b17023SJohn Marino     }
3523e4b17023SJohn Marino 
3524e4b17023SJohn Marino   return (int) i;
3525e4b17023SJohn Marino }
3526e4b17023SJohn Marino 
3527e4b17023SJohn Marino /* Build a binary-operation expression, after performing default
3528e4b17023SJohn Marino    conversions on the operands.  CODE is the kind of expression to
3529e4b17023SJohn Marino    build.  ARG1 and ARG2 are the arguments.  ARG1_CODE and ARG2_CODE
3530e4b17023SJohn Marino    are the tree codes which correspond to ARG1 and ARG2 when issuing
3531e4b17023SJohn Marino    warnings about possibly misplaced parentheses.  They may differ
3532e4b17023SJohn Marino    from the TREE_CODE of ARG1 and ARG2 if the parser has done constant
3533e4b17023SJohn Marino    folding (e.g., if the parser sees "a | 1 + 1", it may call this
3534e4b17023SJohn Marino    routine with ARG2 being an INTEGER_CST and ARG2_CODE == PLUS_EXPR).
3535e4b17023SJohn Marino    To avoid issuing any parentheses warnings, pass ARG1_CODE and/or
3536e4b17023SJohn Marino    ARG2_CODE as ERROR_MARK.  */
3537e4b17023SJohn Marino 
3538e4b17023SJohn Marino tree
build_x_binary_op(enum tree_code code,tree arg1,enum tree_code arg1_code,tree arg2,enum tree_code arg2_code,tree * overload,tsubst_flags_t complain)3539e4b17023SJohn Marino build_x_binary_op (enum tree_code code, tree arg1, enum tree_code arg1_code,
3540e4b17023SJohn Marino 		   tree arg2, enum tree_code arg2_code, tree *overload,
3541e4b17023SJohn Marino 		   tsubst_flags_t complain)
3542e4b17023SJohn Marino {
3543e4b17023SJohn Marino   tree orig_arg1;
3544e4b17023SJohn Marino   tree orig_arg2;
3545e4b17023SJohn Marino   tree expr;
3546e4b17023SJohn Marino 
3547e4b17023SJohn Marino   orig_arg1 = arg1;
3548e4b17023SJohn Marino   orig_arg2 = arg2;
3549e4b17023SJohn Marino 
3550e4b17023SJohn Marino   if (processing_template_decl)
3551e4b17023SJohn Marino     {
3552e4b17023SJohn Marino       if (type_dependent_expression_p (arg1)
3553e4b17023SJohn Marino 	  || type_dependent_expression_p (arg2))
3554e4b17023SJohn Marino 	return build_min_nt (code, arg1, arg2);
3555e4b17023SJohn Marino       arg1 = build_non_dependent_expr (arg1);
3556e4b17023SJohn Marino       arg2 = build_non_dependent_expr (arg2);
3557e4b17023SJohn Marino     }
3558e4b17023SJohn Marino 
3559e4b17023SJohn Marino   if (code == DOTSTAR_EXPR)
3560e4b17023SJohn Marino     expr = build_m_component_ref (arg1, arg2);
3561e4b17023SJohn Marino   else
3562e4b17023SJohn Marino     expr = build_new_op (code, LOOKUP_NORMAL, arg1, arg2, NULL_TREE,
3563e4b17023SJohn Marino 			 overload, complain);
3564e4b17023SJohn Marino 
3565e4b17023SJohn Marino   /* Check for cases such as x+y<<z which users are likely to
3566e4b17023SJohn Marino      misinterpret.  But don't warn about obj << x + y, since that is a
3567e4b17023SJohn Marino      common idiom for I/O.  */
3568e4b17023SJohn Marino   if (warn_parentheses
3569e4b17023SJohn Marino       && (complain & tf_warning)
3570e4b17023SJohn Marino       && !processing_template_decl
3571e4b17023SJohn Marino       && !error_operand_p (arg1)
3572e4b17023SJohn Marino       && !error_operand_p (arg2)
3573e4b17023SJohn Marino       && (code != LSHIFT_EXPR
3574e4b17023SJohn Marino 	  || !CLASS_TYPE_P (TREE_TYPE (arg1))))
3575e4b17023SJohn Marino     warn_about_parentheses (code, arg1_code, orig_arg1, arg2_code, orig_arg2);
3576e4b17023SJohn Marino 
3577e4b17023SJohn Marino   if (processing_template_decl && expr != error_mark_node)
3578e4b17023SJohn Marino     return build_min_non_dep (code, expr, orig_arg1, orig_arg2);
3579e4b17023SJohn Marino 
3580e4b17023SJohn Marino   return expr;
3581e4b17023SJohn Marino }
3582e4b17023SJohn Marino 
3583e4b17023SJohn Marino /* Build and return an ARRAY_REF expression.  */
3584e4b17023SJohn Marino 
3585e4b17023SJohn Marino tree
build_x_array_ref(tree arg1,tree arg2,tsubst_flags_t complain)3586e4b17023SJohn Marino build_x_array_ref (tree arg1, tree arg2, tsubst_flags_t complain)
3587e4b17023SJohn Marino {
3588e4b17023SJohn Marino   tree orig_arg1 = arg1;
3589e4b17023SJohn Marino   tree orig_arg2 = arg2;
3590e4b17023SJohn Marino   tree expr;
3591e4b17023SJohn Marino 
3592e4b17023SJohn Marino   if (processing_template_decl)
3593e4b17023SJohn Marino     {
3594e4b17023SJohn Marino       if (type_dependent_expression_p (arg1)
3595e4b17023SJohn Marino 	  || type_dependent_expression_p (arg2))
3596e4b17023SJohn Marino 	return build_min_nt (ARRAY_REF, arg1, arg2,
3597e4b17023SJohn Marino 			     NULL_TREE, NULL_TREE);
3598e4b17023SJohn Marino       arg1 = build_non_dependent_expr (arg1);
3599e4b17023SJohn Marino       arg2 = build_non_dependent_expr (arg2);
3600e4b17023SJohn Marino     }
3601e4b17023SJohn Marino 
3602e4b17023SJohn Marino   expr = build_new_op (ARRAY_REF, LOOKUP_NORMAL, arg1, arg2, NULL_TREE,
3603e4b17023SJohn Marino 		       /*overload=*/NULL, complain);
3604e4b17023SJohn Marino 
3605e4b17023SJohn Marino   if (processing_template_decl && expr != error_mark_node)
3606e4b17023SJohn Marino     return build_min_non_dep (ARRAY_REF, expr, orig_arg1, orig_arg2,
3607e4b17023SJohn Marino 			      NULL_TREE, NULL_TREE);
3608e4b17023SJohn Marino   return expr;
3609e4b17023SJohn Marino }
3610e4b17023SJohn Marino 
3611e4b17023SJohn Marino /* Return whether OP is an expression of enum type cast to integer
3612e4b17023SJohn Marino    type.  In C++ even unsigned enum types are cast to signed integer
3613e4b17023SJohn Marino    types.  We do not want to issue warnings about comparisons between
3614e4b17023SJohn Marino    signed and unsigned types when one of the types is an enum type.
3615e4b17023SJohn Marino    Those warnings are always false positives in practice.  */
3616e4b17023SJohn Marino 
3617e4b17023SJohn Marino static bool
enum_cast_to_int(tree op)3618e4b17023SJohn Marino enum_cast_to_int (tree op)
3619e4b17023SJohn Marino {
3620e4b17023SJohn Marino   if (TREE_CODE (op) == NOP_EXPR
3621e4b17023SJohn Marino       && TREE_TYPE (op) == integer_type_node
3622e4b17023SJohn Marino       && TREE_CODE (TREE_TYPE (TREE_OPERAND (op, 0))) == ENUMERAL_TYPE
3623e4b17023SJohn Marino       && TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op, 0))))
3624e4b17023SJohn Marino     return true;
3625e4b17023SJohn Marino 
3626e4b17023SJohn Marino   /* The cast may have been pushed into a COND_EXPR.  */
3627e4b17023SJohn Marino   if (TREE_CODE (op) == COND_EXPR)
3628e4b17023SJohn Marino     return (enum_cast_to_int (TREE_OPERAND (op, 1))
3629e4b17023SJohn Marino 	    || enum_cast_to_int (TREE_OPERAND (op, 2)));
3630e4b17023SJohn Marino 
3631e4b17023SJohn Marino   return false;
3632e4b17023SJohn Marino }
3633e4b17023SJohn Marino 
3634e4b17023SJohn Marino /* For the c-common bits.  */
3635e4b17023SJohn Marino tree
build_binary_op(location_t location,enum tree_code code,tree op0,tree op1,int convert_p ATTRIBUTE_UNUSED)3636e4b17023SJohn Marino build_binary_op (location_t location, enum tree_code code, tree op0, tree op1,
3637e4b17023SJohn Marino 		 int convert_p ATTRIBUTE_UNUSED)
3638e4b17023SJohn Marino {
3639e4b17023SJohn Marino   return cp_build_binary_op (location, code, op0, op1, tf_warning_or_error);
3640e4b17023SJohn Marino }
3641e4b17023SJohn Marino 
3642e4b17023SJohn Marino 
3643e4b17023SJohn Marino /* Build a binary-operation expression without default conversions.
3644e4b17023SJohn Marino    CODE is the kind of expression to build.
3645e4b17023SJohn Marino    LOCATION is the location_t of the operator in the source code.
3646e4b17023SJohn Marino    This function differs from `build' in several ways:
3647e4b17023SJohn Marino    the data type of the result is computed and recorded in it,
3648e4b17023SJohn Marino    warnings are generated if arg data types are invalid,
3649e4b17023SJohn Marino    special handling for addition and subtraction of pointers is known,
3650e4b17023SJohn Marino    and some optimization is done (operations on narrow ints
3651e4b17023SJohn Marino    are done in the narrower type when that gives the same result).
3652e4b17023SJohn Marino    Constant folding is also done before the result is returned.
3653e4b17023SJohn Marino 
3654e4b17023SJohn Marino    Note that the operands will never have enumeral types
3655e4b17023SJohn Marino    because either they have just had the default conversions performed
3656e4b17023SJohn Marino    or they have both just been converted to some other type in which
3657e4b17023SJohn Marino    the arithmetic is to be done.
3658e4b17023SJohn Marino 
3659e4b17023SJohn Marino    C++: must do special pointer arithmetic when implementing
3660e4b17023SJohn Marino    multiple inheritance, and deal with pointer to member functions.  */
3661e4b17023SJohn Marino 
3662e4b17023SJohn Marino tree
cp_build_binary_op(location_t location,enum tree_code code,tree orig_op0,tree orig_op1,tsubst_flags_t complain)3663e4b17023SJohn Marino cp_build_binary_op (location_t location,
3664e4b17023SJohn Marino 		    enum tree_code code, tree orig_op0, tree orig_op1,
3665e4b17023SJohn Marino 		    tsubst_flags_t complain)
3666e4b17023SJohn Marino {
3667e4b17023SJohn Marino   tree op0, op1;
3668e4b17023SJohn Marino   enum tree_code code0, code1;
3669e4b17023SJohn Marino   tree type0, type1;
3670e4b17023SJohn Marino   const char *invalid_op_diag;
3671e4b17023SJohn Marino 
3672e4b17023SJohn Marino   /* Expression code to give to the expression when it is built.
3673e4b17023SJohn Marino      Normally this is CODE, which is what the caller asked for,
3674e4b17023SJohn Marino      but in some special cases we change it.  */
3675e4b17023SJohn Marino   enum tree_code resultcode = code;
3676e4b17023SJohn Marino 
3677e4b17023SJohn Marino   /* Data type in which the computation is to be performed.
3678e4b17023SJohn Marino      In the simplest cases this is the common type of the arguments.  */
3679e4b17023SJohn Marino   tree result_type = NULL;
3680e4b17023SJohn Marino 
3681e4b17023SJohn Marino   /* Nonzero means operands have already been type-converted
3682e4b17023SJohn Marino      in whatever way is necessary.
3683e4b17023SJohn Marino      Zero means they need to be converted to RESULT_TYPE.  */
3684e4b17023SJohn Marino   int converted = 0;
3685e4b17023SJohn Marino 
3686e4b17023SJohn Marino   /* Nonzero means create the expression with this type, rather than
3687e4b17023SJohn Marino      RESULT_TYPE.  */
3688e4b17023SJohn Marino   tree build_type = 0;
3689e4b17023SJohn Marino 
3690e4b17023SJohn Marino   /* Nonzero means after finally constructing the expression
3691e4b17023SJohn Marino      convert it to this type.  */
3692e4b17023SJohn Marino   tree final_type = 0;
3693e4b17023SJohn Marino 
3694e4b17023SJohn Marino   tree result;
3695e4b17023SJohn Marino 
3696e4b17023SJohn Marino   /* Nonzero if this is an operation like MIN or MAX which can
3697e4b17023SJohn Marino      safely be computed in short if both args are promoted shorts.
3698e4b17023SJohn Marino      Also implies COMMON.
3699e4b17023SJohn Marino      -1 indicates a bitwise operation; this makes a difference
3700e4b17023SJohn Marino      in the exact conditions for when it is safe to do the operation
3701e4b17023SJohn Marino      in a narrower mode.  */
3702e4b17023SJohn Marino   int shorten = 0;
3703e4b17023SJohn Marino 
3704e4b17023SJohn Marino   /* Nonzero if this is a comparison operation;
3705e4b17023SJohn Marino      if both args are promoted shorts, compare the original shorts.
3706e4b17023SJohn Marino      Also implies COMMON.  */
3707e4b17023SJohn Marino   int short_compare = 0;
3708e4b17023SJohn Marino 
3709e4b17023SJohn Marino   /* Nonzero means set RESULT_TYPE to the common type of the args.  */
3710e4b17023SJohn Marino   int common = 0;
3711e4b17023SJohn Marino 
3712e4b17023SJohn Marino   /* True if both operands have arithmetic type.  */
3713e4b17023SJohn Marino   bool arithmetic_types_p;
3714e4b17023SJohn Marino 
3715e4b17023SJohn Marino   /* Apply default conversions.  */
3716e4b17023SJohn Marino   op0 = orig_op0;
3717e4b17023SJohn Marino   op1 = orig_op1;
3718e4b17023SJohn Marino 
3719e4b17023SJohn Marino   if (code == TRUTH_AND_EXPR || code == TRUTH_ANDIF_EXPR
3720e4b17023SJohn Marino       || code == TRUTH_OR_EXPR || code == TRUTH_ORIF_EXPR
3721e4b17023SJohn Marino       || code == TRUTH_XOR_EXPR)
3722e4b17023SJohn Marino     {
3723e4b17023SJohn Marino       if (!really_overloaded_fn (op0) && !VOID_TYPE_P (TREE_TYPE (op0)))
3724e4b17023SJohn Marino 	op0 = decay_conversion (op0);
3725e4b17023SJohn Marino       if (!really_overloaded_fn (op1) && !VOID_TYPE_P (TREE_TYPE (op1)))
3726e4b17023SJohn Marino 	op1 = decay_conversion (op1);
3727e4b17023SJohn Marino     }
3728e4b17023SJohn Marino   else
3729e4b17023SJohn Marino     {
3730e4b17023SJohn Marino       if (!really_overloaded_fn (op0) && !VOID_TYPE_P (TREE_TYPE (op0)))
3731e4b17023SJohn Marino 	op0 = default_conversion (op0);
3732e4b17023SJohn Marino       if (!really_overloaded_fn (op1) && !VOID_TYPE_P (TREE_TYPE (op1)))
3733e4b17023SJohn Marino 	op1 = default_conversion (op1);
3734e4b17023SJohn Marino     }
3735e4b17023SJohn Marino 
3736e4b17023SJohn Marino   /* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue.  */
3737e4b17023SJohn Marino   STRIP_TYPE_NOPS (op0);
3738e4b17023SJohn Marino   STRIP_TYPE_NOPS (op1);
3739e4b17023SJohn Marino 
3740e4b17023SJohn Marino   /* DTRT if one side is an overloaded function, but complain about it.  */
3741e4b17023SJohn Marino   if (type_unknown_p (op0))
3742e4b17023SJohn Marino     {
3743e4b17023SJohn Marino       tree t = instantiate_type (TREE_TYPE (op1), op0, tf_none);
3744e4b17023SJohn Marino       if (t != error_mark_node)
3745e4b17023SJohn Marino 	{
3746e4b17023SJohn Marino 	  if (complain & tf_error)
3747e4b17023SJohn Marino 	    permerror (input_location, "assuming cast to type %qT from overloaded function",
3748e4b17023SJohn Marino 		       TREE_TYPE (t));
3749e4b17023SJohn Marino 	  op0 = t;
3750e4b17023SJohn Marino 	}
3751e4b17023SJohn Marino     }
3752e4b17023SJohn Marino   if (type_unknown_p (op1))
3753e4b17023SJohn Marino     {
3754e4b17023SJohn Marino       tree t = instantiate_type (TREE_TYPE (op0), op1, tf_none);
3755e4b17023SJohn Marino       if (t != error_mark_node)
3756e4b17023SJohn Marino 	{
3757e4b17023SJohn Marino 	  if (complain & tf_error)
3758e4b17023SJohn Marino 	    permerror (input_location, "assuming cast to type %qT from overloaded function",
3759e4b17023SJohn Marino 		       TREE_TYPE (t));
3760e4b17023SJohn Marino 	  op1 = t;
3761e4b17023SJohn Marino 	}
3762e4b17023SJohn Marino     }
3763e4b17023SJohn Marino 
3764e4b17023SJohn Marino   type0 = TREE_TYPE (op0);
3765e4b17023SJohn Marino   type1 = TREE_TYPE (op1);
3766e4b17023SJohn Marino 
3767e4b17023SJohn Marino   /* The expression codes of the data types of the arguments tell us
3768e4b17023SJohn Marino      whether the arguments are integers, floating, pointers, etc.  */
3769e4b17023SJohn Marino   code0 = TREE_CODE (type0);
3770e4b17023SJohn Marino   code1 = TREE_CODE (type1);
3771e4b17023SJohn Marino 
3772e4b17023SJohn Marino   /* If an error was already reported for one of the arguments,
3773e4b17023SJohn Marino      avoid reporting another error.  */
3774e4b17023SJohn Marino   if (code0 == ERROR_MARK || code1 == ERROR_MARK)
3775e4b17023SJohn Marino     return error_mark_node;
3776e4b17023SJohn Marino 
3777e4b17023SJohn Marino   if ((invalid_op_diag
3778e4b17023SJohn Marino        = targetm.invalid_binary_op (code, type0, type1)))
3779e4b17023SJohn Marino     {
3780e4b17023SJohn Marino       error (invalid_op_diag);
3781e4b17023SJohn Marino       return error_mark_node;
3782e4b17023SJohn Marino     }
3783e4b17023SJohn Marino 
3784e4b17023SJohn Marino   /* Issue warnings about peculiar, but valid, uses of NULL.  */
3785e4b17023SJohn Marino   if ((orig_op0 == null_node || orig_op1 == null_node)
3786e4b17023SJohn Marino       /* It's reasonable to use pointer values as operands of &&
3787e4b17023SJohn Marino 	 and ||, so NULL is no exception.  */
3788e4b17023SJohn Marino       && code != TRUTH_ANDIF_EXPR && code != TRUTH_ORIF_EXPR
3789e4b17023SJohn Marino       && ( /* Both are NULL (or 0) and the operation was not a
3790e4b17023SJohn Marino 	      comparison or a pointer subtraction.  */
3791e4b17023SJohn Marino 	  (null_ptr_cst_p (orig_op0) && null_ptr_cst_p (orig_op1)
3792e4b17023SJohn Marino 	   && code != EQ_EXPR && code != NE_EXPR && code != MINUS_EXPR)
3793e4b17023SJohn Marino 	  /* Or if one of OP0 or OP1 is neither a pointer nor NULL.  */
3794e4b17023SJohn Marino 	  || (!null_ptr_cst_p (orig_op0)
3795e4b17023SJohn Marino 	      && !TYPE_PTR_P (type0) && !TYPE_PTR_TO_MEMBER_P (type0))
3796e4b17023SJohn Marino 	  || (!null_ptr_cst_p (orig_op1)
3797e4b17023SJohn Marino 	      && !TYPE_PTR_P (type1) && !TYPE_PTR_TO_MEMBER_P (type1)))
3798e4b17023SJohn Marino       && (complain & tf_warning))
3799e4b17023SJohn Marino     /* Some sort of arithmetic operation involving NULL was
3800e4b17023SJohn Marino        performed.  */
3801e4b17023SJohn Marino     warning (OPT_Wpointer_arith, "NULL used in arithmetic");
3802e4b17023SJohn Marino 
3803e4b17023SJohn Marino   switch (code)
3804e4b17023SJohn Marino     {
3805e4b17023SJohn Marino     case MINUS_EXPR:
3806e4b17023SJohn Marino       /* Subtraction of two similar pointers.
3807e4b17023SJohn Marino 	 We must subtract them as integers, then divide by object size.  */
3808e4b17023SJohn Marino       if (code0 == POINTER_TYPE && code1 == POINTER_TYPE
3809e4b17023SJohn Marino 	  && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (type0),
3810e4b17023SJohn Marino 							TREE_TYPE (type1)))
3811e4b17023SJohn Marino 	return pointer_diff (op0, op1, common_pointer_type (type0, type1));
3812e4b17023SJohn Marino       /* In all other cases except pointer - int, the usual arithmetic
3813e4b17023SJohn Marino 	 rules apply.  */
3814e4b17023SJohn Marino       else if (!(code0 == POINTER_TYPE && code1 == INTEGER_TYPE))
3815e4b17023SJohn Marino 	{
3816e4b17023SJohn Marino 	  common = 1;
3817e4b17023SJohn Marino 	  break;
3818e4b17023SJohn Marino 	}
3819e4b17023SJohn Marino       /* The pointer - int case is just like pointer + int; fall
3820e4b17023SJohn Marino 	 through.  */
3821e4b17023SJohn Marino     case PLUS_EXPR:
3822e4b17023SJohn Marino       if ((code0 == POINTER_TYPE || code1 == POINTER_TYPE)
3823e4b17023SJohn Marino 	  && (code0 == INTEGER_TYPE || code1 == INTEGER_TYPE))
3824e4b17023SJohn Marino 	{
3825e4b17023SJohn Marino 	  tree ptr_operand;
3826e4b17023SJohn Marino 	  tree int_operand;
3827e4b17023SJohn Marino 	  ptr_operand = ((code0 == POINTER_TYPE) ? op0 : op1);
3828e4b17023SJohn Marino 	  int_operand = ((code0 == INTEGER_TYPE) ? op0 : op1);
3829e4b17023SJohn Marino 	  if (processing_template_decl)
3830e4b17023SJohn Marino 	    {
3831e4b17023SJohn Marino 	      result_type = TREE_TYPE (ptr_operand);
3832e4b17023SJohn Marino 	      break;
3833e4b17023SJohn Marino 	    }
3834e4b17023SJohn Marino 	  return cp_pointer_int_sum (code,
3835e4b17023SJohn Marino 				     ptr_operand,
3836e4b17023SJohn Marino 				     int_operand);
3837e4b17023SJohn Marino 	}
3838e4b17023SJohn Marino       common = 1;
3839e4b17023SJohn Marino       break;
3840e4b17023SJohn Marino 
3841e4b17023SJohn Marino     case MULT_EXPR:
3842e4b17023SJohn Marino       common = 1;
3843e4b17023SJohn Marino       break;
3844e4b17023SJohn Marino 
3845e4b17023SJohn Marino     case TRUNC_DIV_EXPR:
3846e4b17023SJohn Marino     case CEIL_DIV_EXPR:
3847e4b17023SJohn Marino     case FLOOR_DIV_EXPR:
3848e4b17023SJohn Marino     case ROUND_DIV_EXPR:
3849e4b17023SJohn Marino     case EXACT_DIV_EXPR:
3850e4b17023SJohn Marino       if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
3851e4b17023SJohn Marino 	   || code0 == COMPLEX_TYPE || code0 == VECTOR_TYPE)
3852e4b17023SJohn Marino 	  && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
3853e4b17023SJohn Marino 	      || code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE))
3854e4b17023SJohn Marino 	{
3855e4b17023SJohn Marino 	  enum tree_code tcode0 = code0, tcode1 = code1;
3856e4b17023SJohn Marino 
3857e4b17023SJohn Marino 	  warn_for_div_by_zero (location, op1);
3858e4b17023SJohn Marino 
3859e4b17023SJohn Marino 	  if (tcode0 == COMPLEX_TYPE || tcode0 == VECTOR_TYPE)
3860e4b17023SJohn Marino 	    tcode0 = TREE_CODE (TREE_TYPE (TREE_TYPE (op0)));
3861e4b17023SJohn Marino 	  if (tcode1 == COMPLEX_TYPE || tcode1 == VECTOR_TYPE)
3862e4b17023SJohn Marino 	    tcode1 = TREE_CODE (TREE_TYPE (TREE_TYPE (op1)));
3863e4b17023SJohn Marino 
3864e4b17023SJohn Marino 	  if (!(tcode0 == INTEGER_TYPE && tcode1 == INTEGER_TYPE))
3865e4b17023SJohn Marino 	    resultcode = RDIV_EXPR;
3866e4b17023SJohn Marino 	  else
3867e4b17023SJohn Marino 	    /* When dividing two signed integers, we have to promote to int.
3868e4b17023SJohn Marino 	       unless we divide by a constant != -1.  Note that default
3869e4b17023SJohn Marino 	       conversion will have been performed on the operands at this
3870e4b17023SJohn Marino 	       point, so we have to dig out the original type to find out if
3871e4b17023SJohn Marino 	       it was unsigned.  */
3872e4b17023SJohn Marino 	    shorten = ((TREE_CODE (op0) == NOP_EXPR
3873e4b17023SJohn Marino 			&& TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op0, 0))))
3874e4b17023SJohn Marino 		       || (TREE_CODE (op1) == INTEGER_CST
3875e4b17023SJohn Marino 			   && ! integer_all_onesp (op1)));
3876e4b17023SJohn Marino 
3877e4b17023SJohn Marino 	  common = 1;
3878e4b17023SJohn Marino 	}
3879e4b17023SJohn Marino       break;
3880e4b17023SJohn Marino 
3881e4b17023SJohn Marino     case BIT_AND_EXPR:
3882e4b17023SJohn Marino     case BIT_IOR_EXPR:
3883e4b17023SJohn Marino     case BIT_XOR_EXPR:
3884e4b17023SJohn Marino       if ((code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
3885e4b17023SJohn Marino 	  || (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE
3886e4b17023SJohn Marino 	      && !VECTOR_FLOAT_TYPE_P (type0)
3887e4b17023SJohn Marino 	      && !VECTOR_FLOAT_TYPE_P (type1)))
3888e4b17023SJohn Marino 	shorten = -1;
3889e4b17023SJohn Marino       break;
3890e4b17023SJohn Marino 
3891e4b17023SJohn Marino     case TRUNC_MOD_EXPR:
3892e4b17023SJohn Marino     case FLOOR_MOD_EXPR:
3893e4b17023SJohn Marino       warn_for_div_by_zero (location, op1);
3894e4b17023SJohn Marino 
3895e4b17023SJohn Marino       if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE
3896e4b17023SJohn Marino 	  && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE
3897e4b17023SJohn Marino 	  && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE)
3898e4b17023SJohn Marino 	common = 1;
3899e4b17023SJohn Marino       else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
3900e4b17023SJohn Marino 	{
3901e4b17023SJohn Marino 	  /* Although it would be tempting to shorten always here, that loses
3902e4b17023SJohn Marino 	     on some targets, since the modulo instruction is undefined if the
3903e4b17023SJohn Marino 	     quotient can't be represented in the computation mode.  We shorten
3904e4b17023SJohn Marino 	     only if unsigned or if dividing by something we know != -1.  */
3905e4b17023SJohn Marino 	  shorten = ((TREE_CODE (op0) == NOP_EXPR
3906e4b17023SJohn Marino 		      && TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op0, 0))))
3907e4b17023SJohn Marino 		     || (TREE_CODE (op1) == INTEGER_CST
3908e4b17023SJohn Marino 			 && ! integer_all_onesp (op1)));
3909e4b17023SJohn Marino 	  common = 1;
3910e4b17023SJohn Marino 	}
3911e4b17023SJohn Marino       break;
3912e4b17023SJohn Marino 
3913e4b17023SJohn Marino     case TRUTH_ANDIF_EXPR:
3914e4b17023SJohn Marino     case TRUTH_ORIF_EXPR:
3915e4b17023SJohn Marino     case TRUTH_AND_EXPR:
3916e4b17023SJohn Marino     case TRUTH_OR_EXPR:
3917e4b17023SJohn Marino       result_type = boolean_type_node;
3918e4b17023SJohn Marino       break;
3919e4b17023SJohn Marino 
3920e4b17023SJohn Marino       /* Shift operations: result has same type as first operand;
3921e4b17023SJohn Marino 	 always convert second operand to int.
3922e4b17023SJohn Marino 	 Also set SHORT_SHIFT if shifting rightward.  */
3923e4b17023SJohn Marino 
3924e4b17023SJohn Marino     case RSHIFT_EXPR:
3925e4b17023SJohn Marino       if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
3926e4b17023SJohn Marino 	{
3927e4b17023SJohn Marino 	  result_type = type0;
3928e4b17023SJohn Marino 	  if (TREE_CODE (op1) == INTEGER_CST)
3929e4b17023SJohn Marino 	    {
3930e4b17023SJohn Marino 	      if (tree_int_cst_lt (op1, integer_zero_node))
3931e4b17023SJohn Marino 		{
3932e4b17023SJohn Marino 		  if ((complain & tf_warning)
3933e4b17023SJohn Marino 		      && c_inhibit_evaluation_warnings == 0)
3934e4b17023SJohn Marino 		    warning (0, "right shift count is negative");
3935e4b17023SJohn Marino 		}
3936e4b17023SJohn Marino 	      else
3937e4b17023SJohn Marino 		{
3938e4b17023SJohn Marino 		  if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0
3939e4b17023SJohn Marino 		      && (complain & tf_warning)
3940e4b17023SJohn Marino 		      && c_inhibit_evaluation_warnings == 0)
3941e4b17023SJohn Marino 		    warning (0, "right shift count >= width of type");
3942e4b17023SJohn Marino 		}
3943e4b17023SJohn Marino 	    }
3944e4b17023SJohn Marino 	  /* Convert the shift-count to an integer, regardless of
3945e4b17023SJohn Marino 	     size of value being shifted.  */
3946e4b17023SJohn Marino 	  if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
3947e4b17023SJohn Marino 	    op1 = cp_convert (integer_type_node, op1);
3948e4b17023SJohn Marino 	  /* Avoid converting op1 to result_type later.  */
3949e4b17023SJohn Marino 	  converted = 1;
3950e4b17023SJohn Marino 	}
3951e4b17023SJohn Marino       break;
3952e4b17023SJohn Marino 
3953e4b17023SJohn Marino     case LSHIFT_EXPR:
3954e4b17023SJohn Marino       if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
3955e4b17023SJohn Marino 	{
3956e4b17023SJohn Marino 	  result_type = type0;
3957e4b17023SJohn Marino 	  if (TREE_CODE (op1) == INTEGER_CST)
3958e4b17023SJohn Marino 	    {
3959e4b17023SJohn Marino 	      if (tree_int_cst_lt (op1, integer_zero_node))
3960e4b17023SJohn Marino 		{
3961e4b17023SJohn Marino 		  if ((complain & tf_warning)
3962e4b17023SJohn Marino 		      && c_inhibit_evaluation_warnings == 0)
3963e4b17023SJohn Marino 		    warning (0, "left shift count is negative");
3964e4b17023SJohn Marino 		}
3965e4b17023SJohn Marino 	      else if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0)
3966e4b17023SJohn Marino 		{
3967e4b17023SJohn Marino 		  if ((complain & tf_warning)
3968e4b17023SJohn Marino 		      && c_inhibit_evaluation_warnings == 0)
3969e4b17023SJohn Marino 		    warning (0, "left shift count >= width of type");
3970e4b17023SJohn Marino 		}
3971e4b17023SJohn Marino 	    }
3972e4b17023SJohn Marino 	  /* Convert the shift-count to an integer, regardless of
3973e4b17023SJohn Marino 	     size of value being shifted.  */
3974e4b17023SJohn Marino 	  if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
3975e4b17023SJohn Marino 	    op1 = cp_convert (integer_type_node, op1);
3976e4b17023SJohn Marino 	  /* Avoid converting op1 to result_type later.  */
3977e4b17023SJohn Marino 	  converted = 1;
3978e4b17023SJohn Marino 	}
3979e4b17023SJohn Marino       break;
3980e4b17023SJohn Marino 
3981e4b17023SJohn Marino     case RROTATE_EXPR:
3982e4b17023SJohn Marino     case LROTATE_EXPR:
3983e4b17023SJohn Marino       if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
3984e4b17023SJohn Marino 	{
3985e4b17023SJohn Marino 	  result_type = type0;
3986e4b17023SJohn Marino 	  if (TREE_CODE (op1) == INTEGER_CST)
3987e4b17023SJohn Marino 	    {
3988e4b17023SJohn Marino 	      if (tree_int_cst_lt (op1, integer_zero_node))
3989e4b17023SJohn Marino 		{
3990e4b17023SJohn Marino 		  if (complain & tf_warning)
3991e4b17023SJohn Marino 		    warning (0, (code == LROTATE_EXPR)
3992e4b17023SJohn Marino 			          ? G_("left rotate count is negative")
3993e4b17023SJohn Marino    			          : G_("right rotate count is negative"));
3994e4b17023SJohn Marino 		}
3995e4b17023SJohn Marino 	      else if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0)
3996e4b17023SJohn Marino 		{
3997e4b17023SJohn Marino 		  if (complain & tf_warning)
3998e4b17023SJohn Marino 		    warning (0, (code == LROTATE_EXPR)
3999e4b17023SJohn Marino                                   ? G_("left rotate count >= width of type")
4000e4b17023SJohn Marino                                   : G_("right rotate count >= width of type"));
4001e4b17023SJohn Marino 		}
4002e4b17023SJohn Marino 	    }
4003e4b17023SJohn Marino 	  /* Convert the shift-count to an integer, regardless of
4004e4b17023SJohn Marino 	     size of value being shifted.  */
4005e4b17023SJohn Marino 	  if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
4006e4b17023SJohn Marino 	    op1 = cp_convert (integer_type_node, op1);
4007e4b17023SJohn Marino 	}
4008e4b17023SJohn Marino       break;
4009e4b17023SJohn Marino 
4010e4b17023SJohn Marino     case EQ_EXPR:
4011e4b17023SJohn Marino     case NE_EXPR:
4012e4b17023SJohn Marino       if ((complain & tf_warning)
4013e4b17023SJohn Marino 	  && (FLOAT_TYPE_P (type0) || FLOAT_TYPE_P (type1)))
4014e4b17023SJohn Marino 	warning (OPT_Wfloat_equal,
4015e4b17023SJohn Marino 		 "comparing floating point with == or != is unsafe");
4016e4b17023SJohn Marino       if ((complain & tf_warning)
4017e4b17023SJohn Marino 	  && ((TREE_CODE (orig_op0) == STRING_CST && !integer_zerop (op1))
4018e4b17023SJohn Marino 	      || (TREE_CODE (orig_op1) == STRING_CST && !integer_zerop (op0))))
4019e4b17023SJohn Marino 	warning (OPT_Waddress, "comparison with string literal results in unspecified behaviour");
4020e4b17023SJohn Marino 
4021e4b17023SJohn Marino       build_type = boolean_type_node;
4022e4b17023SJohn Marino       if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
4023e4b17023SJohn Marino 	   || code0 == COMPLEX_TYPE || code0 == ENUMERAL_TYPE)
4024e4b17023SJohn Marino 	  && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
4025e4b17023SJohn Marino 	      || code1 == COMPLEX_TYPE || code1 == ENUMERAL_TYPE))
4026e4b17023SJohn Marino 	short_compare = 1;
4027e4b17023SJohn Marino       else if ((code0 == POINTER_TYPE && code1 == POINTER_TYPE)
4028e4b17023SJohn Marino 	       || (TYPE_PTRMEM_P (type0) && TYPE_PTRMEM_P (type1)))
4029e4b17023SJohn Marino 	result_type = composite_pointer_type (type0, type1, op0, op1,
4030e4b17023SJohn Marino 					      CPO_COMPARISON, complain);
4031e4b17023SJohn Marino       else if ((code0 == POINTER_TYPE || TYPE_PTRMEM_P (type0))
4032e4b17023SJohn Marino 	       && null_ptr_cst_p (op1))
4033e4b17023SJohn Marino 	{
4034e4b17023SJohn Marino 	  if (TREE_CODE (op0) == ADDR_EXPR
4035e4b17023SJohn Marino 	      && decl_with_nonnull_addr_p (TREE_OPERAND (op0, 0)))
4036e4b17023SJohn Marino 	    {
4037e4b17023SJohn Marino 	      if (complain & tf_warning)
4038e4b17023SJohn Marino 		warning (OPT_Waddress, "the address of %qD will never be NULL",
4039e4b17023SJohn Marino 			 TREE_OPERAND (op0, 0));
4040e4b17023SJohn Marino 	    }
4041e4b17023SJohn Marino 	  result_type = type0;
4042e4b17023SJohn Marino 	}
4043e4b17023SJohn Marino       else if ((code1 == POINTER_TYPE || TYPE_PTRMEM_P (type1))
4044e4b17023SJohn Marino 	       && null_ptr_cst_p (op0))
4045e4b17023SJohn Marino 	{
4046e4b17023SJohn Marino 	  if (TREE_CODE (op1) == ADDR_EXPR
4047e4b17023SJohn Marino 	      && decl_with_nonnull_addr_p (TREE_OPERAND (op1, 0)))
4048e4b17023SJohn Marino 	    {
4049e4b17023SJohn Marino 	      if (complain & tf_warning)
4050e4b17023SJohn Marino 		warning (OPT_Waddress, "the address of %qD will never be NULL",
4051e4b17023SJohn Marino 			 TREE_OPERAND (op1, 0));
4052e4b17023SJohn Marino 	    }
4053e4b17023SJohn Marino 	  result_type = type1;
4054e4b17023SJohn Marino 	}
4055e4b17023SJohn Marino       else if (null_ptr_cst_p (op0) && null_ptr_cst_p (op1))
4056e4b17023SJohn Marino 	/* One of the operands must be of nullptr_t type.  */
4057e4b17023SJohn Marino         result_type = TREE_TYPE (nullptr_node);
4058e4b17023SJohn Marino       else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
4059e4b17023SJohn Marino 	{
4060e4b17023SJohn Marino 	  result_type = type0;
4061e4b17023SJohn Marino 	  if (complain & tf_error)
4062e4b17023SJohn Marino             permerror (input_location, "ISO C++ forbids comparison between pointer and integer");
4063e4b17023SJohn Marino           else
4064e4b17023SJohn Marino             return error_mark_node;
4065e4b17023SJohn Marino 	}
4066e4b17023SJohn Marino       else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
4067e4b17023SJohn Marino 	{
4068e4b17023SJohn Marino 	  result_type = type1;
4069e4b17023SJohn Marino 	  if (complain & tf_error)
4070e4b17023SJohn Marino 	    permerror (input_location, "ISO C++ forbids comparison between pointer and integer");
4071e4b17023SJohn Marino           else
4072e4b17023SJohn Marino             return error_mark_node;
4073e4b17023SJohn Marino 	}
4074e4b17023SJohn Marino       else if (TYPE_PTRMEMFUNC_P (type0) && null_ptr_cst_p (op1))
4075e4b17023SJohn Marino 	{
4076e4b17023SJohn Marino 	  if (TARGET_PTRMEMFUNC_VBIT_LOCATION
4077e4b17023SJohn Marino 	      == ptrmemfunc_vbit_in_delta)
4078e4b17023SJohn Marino 	    {
4079e4b17023SJohn Marino 	      tree pfn0 = pfn_from_ptrmemfunc (op0);
4080e4b17023SJohn Marino 	      tree delta0 = delta_from_ptrmemfunc (op0);
4081e4b17023SJohn Marino 	      tree e1 = cp_build_binary_op (location,
4082e4b17023SJohn Marino 					    EQ_EXPR,
4083e4b17023SJohn Marino 	  			            pfn0,
4084e4b17023SJohn Marino 				      	    build_zero_cst (TREE_TYPE (pfn0)),
4085e4b17023SJohn Marino 					    complain);
4086e4b17023SJohn Marino 	      tree e2 = cp_build_binary_op (location,
4087e4b17023SJohn Marino 					    BIT_AND_EXPR,
4088e4b17023SJohn Marino 					    delta0,
4089e4b17023SJohn Marino 				            integer_one_node,
4090e4b17023SJohn Marino 					    complain);
4091e4b17023SJohn Marino 
4092e4b17023SJohn Marino 	      if ((complain & tf_warning)
4093e4b17023SJohn Marino 		  && c_inhibit_evaluation_warnings == 0
4094e4b17023SJohn Marino 		  && !NULLPTR_TYPE_P (TREE_TYPE (op1)))
4095e4b17023SJohn Marino 		warning (OPT_Wzero_as_null_pointer_constant,
4096e4b17023SJohn Marino 			 "zero as null pointer constant");
4097e4b17023SJohn Marino 
4098e4b17023SJohn Marino 	      e2 = cp_build_binary_op (location,
4099e4b17023SJohn Marino 				       EQ_EXPR, e2, integer_zero_node,
4100e4b17023SJohn Marino 				       complain);
4101e4b17023SJohn Marino 	      op0 = cp_build_binary_op (location,
4102e4b17023SJohn Marino 					TRUTH_ANDIF_EXPR, e1, e2,
4103e4b17023SJohn Marino 					complain);
4104e4b17023SJohn Marino 	      op1 = cp_convert (TREE_TYPE (op0), integer_one_node);
4105e4b17023SJohn Marino 	    }
4106e4b17023SJohn Marino      	  else
4107e4b17023SJohn Marino 	    {
4108e4b17023SJohn Marino 	      op0 = build_ptrmemfunc_access_expr (op0, pfn_identifier);
4109e4b17023SJohn Marino 	      op1 = cp_convert (TREE_TYPE (op0), op1);
4110e4b17023SJohn Marino 	    }
4111e4b17023SJohn Marino 	  result_type = TREE_TYPE (op0);
4112e4b17023SJohn Marino 	}
4113e4b17023SJohn Marino       else if (TYPE_PTRMEMFUNC_P (type1) && null_ptr_cst_p (op0))
4114e4b17023SJohn Marino 	return cp_build_binary_op (location, code, op1, op0, complain);
4115e4b17023SJohn Marino       else if (TYPE_PTRMEMFUNC_P (type0) && TYPE_PTRMEMFUNC_P (type1))
4116e4b17023SJohn Marino 	{
4117e4b17023SJohn Marino 	  tree type;
4118e4b17023SJohn Marino 	  /* E will be the final comparison.  */
4119e4b17023SJohn Marino 	  tree e;
4120e4b17023SJohn Marino 	  /* E1 and E2 are for scratch.  */
4121e4b17023SJohn Marino 	  tree e1;
4122e4b17023SJohn Marino 	  tree e2;
4123e4b17023SJohn Marino 	  tree pfn0;
4124e4b17023SJohn Marino 	  tree pfn1;
4125e4b17023SJohn Marino 	  tree delta0;
4126e4b17023SJohn Marino 	  tree delta1;
4127e4b17023SJohn Marino 
4128e4b17023SJohn Marino 	  type = composite_pointer_type (type0, type1, op0, op1,
4129e4b17023SJohn Marino 					 CPO_COMPARISON, complain);
4130e4b17023SJohn Marino 
4131e4b17023SJohn Marino 	  if (!same_type_p (TREE_TYPE (op0), type))
4132e4b17023SJohn Marino 	    op0 = cp_convert_and_check (type, op0);
4133e4b17023SJohn Marino 	  if (!same_type_p (TREE_TYPE (op1), type))
4134e4b17023SJohn Marino 	    op1 = cp_convert_and_check (type, op1);
4135e4b17023SJohn Marino 
4136e4b17023SJohn Marino 	  if (op0 == error_mark_node || op1 == error_mark_node)
4137e4b17023SJohn Marino 	    return error_mark_node;
4138e4b17023SJohn Marino 
4139e4b17023SJohn Marino 	  if (TREE_SIDE_EFFECTS (op0))
4140e4b17023SJohn Marino 	    op0 = save_expr (op0);
4141e4b17023SJohn Marino 	  if (TREE_SIDE_EFFECTS (op1))
4142e4b17023SJohn Marino 	    op1 = save_expr (op1);
4143e4b17023SJohn Marino 
4144e4b17023SJohn Marino 	  pfn0 = pfn_from_ptrmemfunc (op0);
4145e4b17023SJohn Marino 	  pfn1 = pfn_from_ptrmemfunc (op1);
4146e4b17023SJohn Marino 	  delta0 = delta_from_ptrmemfunc (op0);
4147e4b17023SJohn Marino 	  delta1 = delta_from_ptrmemfunc (op1);
4148e4b17023SJohn Marino 	  if (TARGET_PTRMEMFUNC_VBIT_LOCATION
4149e4b17023SJohn Marino 	      == ptrmemfunc_vbit_in_delta)
4150e4b17023SJohn Marino 	    {
4151e4b17023SJohn Marino 	      /* We generate:
4152e4b17023SJohn Marino 
4153e4b17023SJohn Marino 		 (op0.pfn == op1.pfn
4154e4b17023SJohn Marino 		  && ((op0.delta == op1.delta)
4155e4b17023SJohn Marino      		       || (!op0.pfn && op0.delta & 1 == 0
4156e4b17023SJohn Marino 			   && op1.delta & 1 == 0))
4157e4b17023SJohn Marino 
4158e4b17023SJohn Marino 	         The reason for the `!op0.pfn' bit is that a NULL
4159e4b17023SJohn Marino 	         pointer-to-member is any member with a zero PFN and
4160e4b17023SJohn Marino 	         LSB of the DELTA field is 0.  */
4161e4b17023SJohn Marino 
4162e4b17023SJohn Marino 	      e1 = cp_build_binary_op (location, BIT_AND_EXPR,
4163e4b17023SJohn Marino 				       delta0,
4164e4b17023SJohn Marino 				       integer_one_node,
4165e4b17023SJohn Marino 				       complain);
4166e4b17023SJohn Marino 	      e1 = cp_build_binary_op (location,
4167e4b17023SJohn Marino 				       EQ_EXPR, e1, integer_zero_node,
4168e4b17023SJohn Marino 				       complain);
4169e4b17023SJohn Marino 	      e2 = cp_build_binary_op (location, BIT_AND_EXPR,
4170e4b17023SJohn Marino 				       delta1,
4171e4b17023SJohn Marino 				       integer_one_node,
4172e4b17023SJohn Marino 				       complain);
4173e4b17023SJohn Marino 	      e2 = cp_build_binary_op (location,
4174e4b17023SJohn Marino 				       EQ_EXPR, e2, integer_zero_node,
4175e4b17023SJohn Marino 				       complain);
4176e4b17023SJohn Marino 	      e1 = cp_build_binary_op (location,
4177e4b17023SJohn Marino 				       TRUTH_ANDIF_EXPR, e2, e1,
4178e4b17023SJohn Marino 				       complain);
4179e4b17023SJohn Marino 	      e2 = cp_build_binary_op (location, EQ_EXPR,
4180e4b17023SJohn Marino 				       pfn0,
4181e4b17023SJohn Marino 				       build_zero_cst (TREE_TYPE (pfn0)),
4182e4b17023SJohn Marino 				       complain);
4183e4b17023SJohn Marino 	      e2 = cp_build_binary_op (location,
4184e4b17023SJohn Marino 				       TRUTH_ANDIF_EXPR, e2, e1, complain);
4185e4b17023SJohn Marino 	      e1 = cp_build_binary_op (location,
4186e4b17023SJohn Marino 				       EQ_EXPR, delta0, delta1, complain);
4187e4b17023SJohn Marino 	      e1 = cp_build_binary_op (location,
4188e4b17023SJohn Marino 				       TRUTH_ORIF_EXPR, e1, e2, complain);
4189e4b17023SJohn Marino 	    }
4190e4b17023SJohn Marino 	  else
4191e4b17023SJohn Marino 	    {
4192e4b17023SJohn Marino 	      /* We generate:
4193e4b17023SJohn Marino 
4194e4b17023SJohn Marino 	         (op0.pfn == op1.pfn
4195e4b17023SJohn Marino 	         && (!op0.pfn || op0.delta == op1.delta))
4196e4b17023SJohn Marino 
4197e4b17023SJohn Marino 	         The reason for the `!op0.pfn' bit is that a NULL
4198e4b17023SJohn Marino 	         pointer-to-member is any member with a zero PFN; the
4199e4b17023SJohn Marino 	         DELTA field is unspecified.  */
4200e4b17023SJohn Marino 
4201e4b17023SJohn Marino     	      e1 = cp_build_binary_op (location,
4202e4b17023SJohn Marino 				       EQ_EXPR, delta0, delta1, complain);
4203e4b17023SJohn Marino 	      e2 = cp_build_binary_op (location,
4204e4b17023SJohn Marino 				       EQ_EXPR,
4205e4b17023SJohn Marino 		      		       pfn0,
4206e4b17023SJohn Marino 			   	       build_zero_cst (TREE_TYPE (pfn0)),
4207e4b17023SJohn Marino 				       complain);
4208e4b17023SJohn Marino 	      e1 = cp_build_binary_op (location,
4209e4b17023SJohn Marino 				       TRUTH_ORIF_EXPR, e1, e2, complain);
4210e4b17023SJohn Marino 	    }
4211e4b17023SJohn Marino 	  e2 = build2 (EQ_EXPR, boolean_type_node, pfn0, pfn1);
4212e4b17023SJohn Marino 	  e = cp_build_binary_op (location,
4213e4b17023SJohn Marino 				  TRUTH_ANDIF_EXPR, e2, e1, complain);
4214e4b17023SJohn Marino 	  if (code == EQ_EXPR)
4215e4b17023SJohn Marino 	    return e;
4216e4b17023SJohn Marino 	  return cp_build_binary_op (location,
4217e4b17023SJohn Marino 				     EQ_EXPR, e, integer_zero_node, complain);
4218e4b17023SJohn Marino 	}
4219e4b17023SJohn Marino       else
4220e4b17023SJohn Marino 	{
4221e4b17023SJohn Marino 	  gcc_assert (!TYPE_PTRMEMFUNC_P (type0)
4222e4b17023SJohn Marino 		      || !same_type_p (TYPE_PTRMEMFUNC_FN_TYPE (type0),
4223e4b17023SJohn Marino 				       type1));
4224e4b17023SJohn Marino 	  gcc_assert (!TYPE_PTRMEMFUNC_P (type1)
4225e4b17023SJohn Marino 		      || !same_type_p (TYPE_PTRMEMFUNC_FN_TYPE (type1),
4226e4b17023SJohn Marino 				       type0));
4227e4b17023SJohn Marino 	}
4228e4b17023SJohn Marino 
4229e4b17023SJohn Marino       break;
4230e4b17023SJohn Marino 
4231e4b17023SJohn Marino     case MAX_EXPR:
4232e4b17023SJohn Marino     case MIN_EXPR:
4233e4b17023SJohn Marino       if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
4234e4b17023SJohn Marino 	   && (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
4235e4b17023SJohn Marino 	shorten = 1;
4236e4b17023SJohn Marino       else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
4237e4b17023SJohn Marino 	result_type = composite_pointer_type (type0, type1, op0, op1,
4238e4b17023SJohn Marino 					      CPO_COMPARISON, complain);
4239e4b17023SJohn Marino       break;
4240e4b17023SJohn Marino 
4241e4b17023SJohn Marino     case LE_EXPR:
4242e4b17023SJohn Marino     case GE_EXPR:
4243e4b17023SJohn Marino     case LT_EXPR:
4244e4b17023SJohn Marino     case GT_EXPR:
4245e4b17023SJohn Marino       if (TREE_CODE (orig_op0) == STRING_CST
4246e4b17023SJohn Marino 	  || TREE_CODE (orig_op1) == STRING_CST)
4247e4b17023SJohn Marino 	{
4248e4b17023SJohn Marino 	  if (complain & tf_warning)
4249e4b17023SJohn Marino 	    warning (OPT_Waddress, "comparison with string literal results in unspecified behaviour");
4250e4b17023SJohn Marino 	}
4251e4b17023SJohn Marino 
4252e4b17023SJohn Marino       build_type = boolean_type_node;
4253e4b17023SJohn Marino       if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
4254e4b17023SJohn Marino 	   || code0 == ENUMERAL_TYPE)
4255e4b17023SJohn Marino 	   && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
4256e4b17023SJohn Marino 	       || code1 == ENUMERAL_TYPE))
4257e4b17023SJohn Marino 	short_compare = 1;
4258e4b17023SJohn Marino       else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
4259e4b17023SJohn Marino 	result_type = composite_pointer_type (type0, type1, op0, op1,
4260e4b17023SJohn Marino 					      CPO_COMPARISON, complain);
4261e4b17023SJohn Marino       else if (code0 == POINTER_TYPE && null_ptr_cst_p (op1))
4262e4b17023SJohn Marino 	{
4263e4b17023SJohn Marino 	  result_type = type0;
4264e4b17023SJohn Marino 	  if (extra_warnings && (complain & tf_warning))
4265e4b17023SJohn Marino 	    warning (OPT_Wextra,
4266e4b17023SJohn Marino 		     "ordered comparison of pointer with integer zero");
4267e4b17023SJohn Marino 	}
4268e4b17023SJohn Marino       else if (code1 == POINTER_TYPE && null_ptr_cst_p (op0))
4269e4b17023SJohn Marino 	{
4270e4b17023SJohn Marino 	  result_type = type1;
4271e4b17023SJohn Marino 	  if (extra_warnings && (complain & tf_warning))
4272e4b17023SJohn Marino 	    warning (OPT_Wextra,
4273e4b17023SJohn Marino 		     "ordered comparison of pointer with integer zero");
4274e4b17023SJohn Marino 	}
4275e4b17023SJohn Marino       else if (null_ptr_cst_p (op0) && null_ptr_cst_p (op1))
4276e4b17023SJohn Marino 	/* One of the operands must be of nullptr_t type.  */
4277e4b17023SJohn Marino         result_type = TREE_TYPE (nullptr_node);
4278e4b17023SJohn Marino       else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
4279e4b17023SJohn Marino 	{
4280e4b17023SJohn Marino 	  result_type = type0;
4281e4b17023SJohn Marino 	  if (complain & tf_error)
4282e4b17023SJohn Marino 	    permerror (input_location, "ISO C++ forbids comparison between pointer and integer");
4283e4b17023SJohn Marino           else
4284e4b17023SJohn Marino             return error_mark_node;
4285e4b17023SJohn Marino 	}
4286e4b17023SJohn Marino       else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
4287e4b17023SJohn Marino 	{
4288e4b17023SJohn Marino 	  result_type = type1;
4289e4b17023SJohn Marino 	  if (complain & tf_error)
4290e4b17023SJohn Marino 	    permerror (input_location, "ISO C++ forbids comparison between pointer and integer");
4291e4b17023SJohn Marino           else
4292e4b17023SJohn Marino             return error_mark_node;
4293e4b17023SJohn Marino 	}
4294e4b17023SJohn Marino       break;
4295e4b17023SJohn Marino 
4296e4b17023SJohn Marino     case UNORDERED_EXPR:
4297e4b17023SJohn Marino     case ORDERED_EXPR:
4298e4b17023SJohn Marino     case UNLT_EXPR:
4299e4b17023SJohn Marino     case UNLE_EXPR:
4300e4b17023SJohn Marino     case UNGT_EXPR:
4301e4b17023SJohn Marino     case UNGE_EXPR:
4302e4b17023SJohn Marino     case UNEQ_EXPR:
4303e4b17023SJohn Marino       build_type = integer_type_node;
4304e4b17023SJohn Marino       if (code0 != REAL_TYPE || code1 != REAL_TYPE)
4305e4b17023SJohn Marino 	{
4306e4b17023SJohn Marino 	  if (complain & tf_error)
4307e4b17023SJohn Marino 	    error ("unordered comparison on non-floating point argument");
4308e4b17023SJohn Marino 	  return error_mark_node;
4309e4b17023SJohn Marino 	}
4310e4b17023SJohn Marino       common = 1;
4311e4b17023SJohn Marino       break;
4312e4b17023SJohn Marino 
4313e4b17023SJohn Marino     default:
4314e4b17023SJohn Marino       break;
4315e4b17023SJohn Marino     }
4316e4b17023SJohn Marino 
4317e4b17023SJohn Marino   if (((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE
4318e4b17023SJohn Marino 	|| code0 == ENUMERAL_TYPE)
4319e4b17023SJohn Marino        && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
4320e4b17023SJohn Marino 	   || code1 == COMPLEX_TYPE || code1 == ENUMERAL_TYPE)))
4321e4b17023SJohn Marino     arithmetic_types_p = 1;
4322e4b17023SJohn Marino   else
4323e4b17023SJohn Marino     {
4324e4b17023SJohn Marino       arithmetic_types_p = 0;
4325e4b17023SJohn Marino       /* Vector arithmetic is only allowed when both sides are vectors.  */
4326e4b17023SJohn Marino       if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE)
4327e4b17023SJohn Marino 	{
4328e4b17023SJohn Marino 	  if (!tree_int_cst_equal (TYPE_SIZE (type0), TYPE_SIZE (type1))
4329e4b17023SJohn Marino 	      || !same_scalar_type_ignoring_signedness (TREE_TYPE (type0),
4330e4b17023SJohn Marino 							TREE_TYPE (type1)))
4331e4b17023SJohn Marino 	    {
4332e4b17023SJohn Marino 	      binary_op_error (location, code, type0, type1);
4333e4b17023SJohn Marino 	      return error_mark_node;
4334e4b17023SJohn Marino 	    }
4335e4b17023SJohn Marino 	  arithmetic_types_p = 1;
4336e4b17023SJohn Marino 	}
4337e4b17023SJohn Marino     }
4338e4b17023SJohn Marino   /* Determine the RESULT_TYPE, if it is not already known.  */
4339e4b17023SJohn Marino   if (!result_type
4340e4b17023SJohn Marino       && arithmetic_types_p
4341e4b17023SJohn Marino       && (shorten || common || short_compare))
4342e4b17023SJohn Marino     {
4343e4b17023SJohn Marino       result_type = cp_common_type (type0, type1);
4344e4b17023SJohn Marino       do_warn_double_promotion (result_type, type0, type1,
4345e4b17023SJohn Marino 				"implicit conversion from %qT to %qT "
4346e4b17023SJohn Marino 				"to match other operand of binary "
4347e4b17023SJohn Marino 				"expression",
4348e4b17023SJohn Marino 				location);
4349e4b17023SJohn Marino     }
4350e4b17023SJohn Marino 
4351e4b17023SJohn Marino   if (!result_type)
4352e4b17023SJohn Marino     {
4353e4b17023SJohn Marino       if (complain & tf_error)
4354e4b17023SJohn Marino 	error ("invalid operands of types %qT and %qT to binary %qO",
4355e4b17023SJohn Marino 	       TREE_TYPE (orig_op0), TREE_TYPE (orig_op1), code);
4356e4b17023SJohn Marino       return error_mark_node;
4357e4b17023SJohn Marino     }
4358e4b17023SJohn Marino 
4359e4b17023SJohn Marino   /* If we're in a template, the only thing we need to know is the
4360e4b17023SJohn Marino      RESULT_TYPE.  */
4361e4b17023SJohn Marino   if (processing_template_decl)
4362e4b17023SJohn Marino     {
4363e4b17023SJohn Marino       /* Since the middle-end checks the type when doing a build2, we
4364e4b17023SJohn Marino 	 need to build the tree in pieces.  This built tree will never
4365e4b17023SJohn Marino 	 get out of the front-end as we replace it when instantiating
4366e4b17023SJohn Marino 	 the template.  */
4367e4b17023SJohn Marino       tree tmp = build2 (resultcode,
4368e4b17023SJohn Marino 			 build_type ? build_type : result_type,
4369e4b17023SJohn Marino 			 NULL_TREE, op1);
4370e4b17023SJohn Marino       TREE_OPERAND (tmp, 0) = op0;
4371e4b17023SJohn Marino       return tmp;
4372e4b17023SJohn Marino     }
4373e4b17023SJohn Marino 
4374e4b17023SJohn Marino   if (arithmetic_types_p)
4375e4b17023SJohn Marino     {
4376e4b17023SJohn Marino       bool first_complex = (code0 == COMPLEX_TYPE);
4377e4b17023SJohn Marino       bool second_complex = (code1 == COMPLEX_TYPE);
4378e4b17023SJohn Marino       int none_complex = (!first_complex && !second_complex);
4379e4b17023SJohn Marino 
4380e4b17023SJohn Marino       /* Adapted from patch for c/24581.  */
4381e4b17023SJohn Marino       if (first_complex != second_complex
4382e4b17023SJohn Marino 	  && (code == PLUS_EXPR
4383e4b17023SJohn Marino 	      || code == MINUS_EXPR
4384e4b17023SJohn Marino 	      || code == MULT_EXPR
4385e4b17023SJohn Marino 	      || (code == TRUNC_DIV_EXPR && first_complex))
4386e4b17023SJohn Marino 	  && TREE_CODE (TREE_TYPE (result_type)) == REAL_TYPE
4387e4b17023SJohn Marino 	  && flag_signed_zeros)
4388e4b17023SJohn Marino 	{
4389e4b17023SJohn Marino 	  /* An operation on mixed real/complex operands must be
4390e4b17023SJohn Marino 	     handled specially, but the language-independent code can
4391e4b17023SJohn Marino 	     more easily optimize the plain complex arithmetic if
4392e4b17023SJohn Marino 	     -fno-signed-zeros.  */
4393e4b17023SJohn Marino 	  tree real_type = TREE_TYPE (result_type);
4394e4b17023SJohn Marino 	  tree real, imag;
4395e4b17023SJohn Marino 	  if (first_complex)
4396e4b17023SJohn Marino 	    {
4397e4b17023SJohn Marino 	      if (TREE_TYPE (op0) != result_type)
4398e4b17023SJohn Marino 		op0 = cp_convert_and_check (result_type, op0);
4399e4b17023SJohn Marino 	      if (TREE_TYPE (op1) != real_type)
4400e4b17023SJohn Marino 		op1 = cp_convert_and_check (real_type, op1);
4401e4b17023SJohn Marino 	    }
4402e4b17023SJohn Marino 	  else
4403e4b17023SJohn Marino 	    {
4404e4b17023SJohn Marino 	      if (TREE_TYPE (op0) != real_type)
4405e4b17023SJohn Marino 		op0 = cp_convert_and_check (real_type, op0);
4406e4b17023SJohn Marino 	      if (TREE_TYPE (op1) != result_type)
4407e4b17023SJohn Marino 		op1 = cp_convert_and_check (result_type, op1);
4408e4b17023SJohn Marino 	    }
4409e4b17023SJohn Marino 	  if (TREE_CODE (op0) == ERROR_MARK || TREE_CODE (op1) == ERROR_MARK)
4410e4b17023SJohn Marino 	    return error_mark_node;
4411e4b17023SJohn Marino 	  if (first_complex)
4412e4b17023SJohn Marino 	    {
4413e4b17023SJohn Marino 	      op0 = save_expr (op0);
4414e4b17023SJohn Marino 	      real = cp_build_unary_op (REALPART_EXPR, op0, 1, complain);
4415e4b17023SJohn Marino 	      imag = cp_build_unary_op (IMAGPART_EXPR, op0, 1, complain);
4416e4b17023SJohn Marino 	      switch (code)
4417e4b17023SJohn Marino 		{
4418e4b17023SJohn Marino 		case MULT_EXPR:
4419e4b17023SJohn Marino 		case TRUNC_DIV_EXPR:
4420e4b17023SJohn Marino 		  op1 = save_expr (op1);
4421e4b17023SJohn Marino 		  imag = build2 (resultcode, real_type, imag, op1);
4422e4b17023SJohn Marino 		  /* Fall through.  */
4423e4b17023SJohn Marino 		case PLUS_EXPR:
4424e4b17023SJohn Marino 		case MINUS_EXPR:
4425e4b17023SJohn Marino 		  real = build2 (resultcode, real_type, real, op1);
4426e4b17023SJohn Marino 		  break;
4427e4b17023SJohn Marino 		default:
4428e4b17023SJohn Marino 		  gcc_unreachable();
4429e4b17023SJohn Marino 		}
4430e4b17023SJohn Marino 	    }
4431e4b17023SJohn Marino 	  else
4432e4b17023SJohn Marino 	    {
4433e4b17023SJohn Marino 	      op1 = save_expr (op1);
4434e4b17023SJohn Marino 	      real = cp_build_unary_op (REALPART_EXPR, op1, 1, complain);
4435e4b17023SJohn Marino 	      imag = cp_build_unary_op (IMAGPART_EXPR, op1, 1, complain);
4436e4b17023SJohn Marino 	      switch (code)
4437e4b17023SJohn Marino 		{
4438e4b17023SJohn Marino 		case MULT_EXPR:
4439e4b17023SJohn Marino 		  op0 = save_expr (op0);
4440e4b17023SJohn Marino 		  imag = build2 (resultcode, real_type, op0, imag);
4441e4b17023SJohn Marino 		  /* Fall through.  */
4442e4b17023SJohn Marino 		case PLUS_EXPR:
4443e4b17023SJohn Marino 		  real = build2 (resultcode, real_type, op0, real);
4444e4b17023SJohn Marino 		  break;
4445e4b17023SJohn Marino 		case MINUS_EXPR:
4446e4b17023SJohn Marino 		  real = build2 (resultcode, real_type, op0, real);
4447e4b17023SJohn Marino 		  imag = build1 (NEGATE_EXPR, real_type, imag);
4448e4b17023SJohn Marino 		  break;
4449e4b17023SJohn Marino 		default:
4450e4b17023SJohn Marino 		  gcc_unreachable();
4451e4b17023SJohn Marino 		}
4452e4b17023SJohn Marino 	    }
4453e4b17023SJohn Marino 	  real = fold_if_not_in_template (real);
4454e4b17023SJohn Marino 	  imag = fold_if_not_in_template (imag);
4455e4b17023SJohn Marino 	  result = build2 (COMPLEX_EXPR, result_type, real, imag);
4456e4b17023SJohn Marino 	  result = fold_if_not_in_template (result);
4457e4b17023SJohn Marino 	  return result;
4458e4b17023SJohn Marino 	}
4459e4b17023SJohn Marino 
4460e4b17023SJohn Marino       /* For certain operations (which identify themselves by shorten != 0)
4461e4b17023SJohn Marino 	 if both args were extended from the same smaller type,
4462e4b17023SJohn Marino 	 do the arithmetic in that type and then extend.
4463e4b17023SJohn Marino 
4464e4b17023SJohn Marino 	 shorten !=0 and !=1 indicates a bitwise operation.
4465e4b17023SJohn Marino 	 For them, this optimization is safe only if
4466e4b17023SJohn Marino 	 both args are zero-extended or both are sign-extended.
4467e4b17023SJohn Marino 	 Otherwise, we might change the result.
4468e4b17023SJohn Marino 	 E.g., (short)-1 | (unsigned short)-1 is (int)-1
4469e4b17023SJohn Marino 	 but calculated in (unsigned short) it would be (unsigned short)-1.  */
4470e4b17023SJohn Marino 
4471e4b17023SJohn Marino       if (shorten && none_complex)
4472e4b17023SJohn Marino 	{
4473e4b17023SJohn Marino 	  final_type = result_type;
4474e4b17023SJohn Marino 	  result_type = shorten_binary_op (result_type, op0, op1,
4475e4b17023SJohn Marino 					   shorten == -1);
4476e4b17023SJohn Marino 	}
4477e4b17023SJohn Marino 
4478e4b17023SJohn Marino       /* Comparison operations are shortened too but differently.
4479e4b17023SJohn Marino 	 They identify themselves by setting short_compare = 1.  */
4480e4b17023SJohn Marino 
4481e4b17023SJohn Marino       if (short_compare)
4482e4b17023SJohn Marino 	{
4483e4b17023SJohn Marino 	  /* Don't write &op0, etc., because that would prevent op0
4484e4b17023SJohn Marino 	     from being kept in a register.
4485e4b17023SJohn Marino 	     Instead, make copies of the our local variables and
4486e4b17023SJohn Marino 	     pass the copies by reference, then copy them back afterward.  */
4487e4b17023SJohn Marino 	  tree xop0 = op0, xop1 = op1, xresult_type = result_type;
4488e4b17023SJohn Marino 	  enum tree_code xresultcode = resultcode;
4489e4b17023SJohn Marino 	  tree val
4490e4b17023SJohn Marino 	    = shorten_compare (&xop0, &xop1, &xresult_type, &xresultcode);
4491e4b17023SJohn Marino 	  if (val != 0)
4492e4b17023SJohn Marino 	    return cp_convert (boolean_type_node, val);
4493e4b17023SJohn Marino 	  op0 = xop0, op1 = xop1;
4494e4b17023SJohn Marino 	  converted = 1;
4495e4b17023SJohn Marino 	  resultcode = xresultcode;
4496e4b17023SJohn Marino 	}
4497e4b17023SJohn Marino 
4498e4b17023SJohn Marino       if ((short_compare || code == MIN_EXPR || code == MAX_EXPR)
4499e4b17023SJohn Marino 	  && warn_sign_compare
4500e4b17023SJohn Marino 	  /* Do not warn until the template is instantiated; we cannot
4501e4b17023SJohn Marino 	     bound the ranges of the arguments until that point.  */
4502e4b17023SJohn Marino 	  && !processing_template_decl
4503e4b17023SJohn Marino           && (complain & tf_warning)
4504e4b17023SJohn Marino 	  && c_inhibit_evaluation_warnings == 0
4505e4b17023SJohn Marino 	  /* Even unsigned enum types promote to signed int.  We don't
4506e4b17023SJohn Marino 	     want to issue -Wsign-compare warnings for this case.  */
4507e4b17023SJohn Marino 	  && !enum_cast_to_int (orig_op0)
4508e4b17023SJohn Marino 	  && !enum_cast_to_int (orig_op1))
4509e4b17023SJohn Marino 	{
4510e4b17023SJohn Marino 	  warn_for_sign_compare (location, orig_op0, orig_op1, op0, op1,
4511e4b17023SJohn Marino 				 result_type, resultcode);
4512e4b17023SJohn Marino 	}
4513e4b17023SJohn Marino     }
4514e4b17023SJohn Marino 
4515e4b17023SJohn Marino   /* If CONVERTED is zero, both args will be converted to type RESULT_TYPE.
4516e4b17023SJohn Marino      Then the expression will be built.
4517e4b17023SJohn Marino      It will be given type FINAL_TYPE if that is nonzero;
4518e4b17023SJohn Marino      otherwise, it will be given type RESULT_TYPE.  */
4519e4b17023SJohn Marino   if (! converted)
4520e4b17023SJohn Marino     {
4521e4b17023SJohn Marino       if (TREE_TYPE (op0) != result_type)
4522e4b17023SJohn Marino 	op0 = cp_convert_and_check (result_type, op0);
4523e4b17023SJohn Marino       if (TREE_TYPE (op1) != result_type)
4524e4b17023SJohn Marino 	op1 = cp_convert_and_check (result_type, op1);
4525e4b17023SJohn Marino 
4526e4b17023SJohn Marino       if (op0 == error_mark_node || op1 == error_mark_node)
4527e4b17023SJohn Marino 	return error_mark_node;
4528e4b17023SJohn Marino     }
4529e4b17023SJohn Marino 
4530e4b17023SJohn Marino   if (build_type == NULL_TREE)
4531e4b17023SJohn Marino     build_type = result_type;
4532e4b17023SJohn Marino 
4533e4b17023SJohn Marino   result = build2 (resultcode, build_type, op0, op1);
4534e4b17023SJohn Marino   result = fold_if_not_in_template (result);
4535e4b17023SJohn Marino   if (final_type != 0)
4536e4b17023SJohn Marino     result = cp_convert (final_type, result);
4537e4b17023SJohn Marino 
4538e4b17023SJohn Marino   if (TREE_OVERFLOW_P (result)
4539e4b17023SJohn Marino       && !TREE_OVERFLOW_P (op0)
4540e4b17023SJohn Marino       && !TREE_OVERFLOW_P (op1))
4541e4b17023SJohn Marino     overflow_warning (location, result);
4542e4b17023SJohn Marino 
4543e4b17023SJohn Marino   return result;
4544e4b17023SJohn Marino }
4545e4b17023SJohn Marino 
4546e4b17023SJohn Marino /* Return a tree for the sum or difference (RESULTCODE says which)
4547e4b17023SJohn Marino    of pointer PTROP and integer INTOP.  */
4548e4b17023SJohn Marino 
4549e4b17023SJohn Marino static tree
cp_pointer_int_sum(enum tree_code resultcode,tree ptrop,tree intop)4550e4b17023SJohn Marino cp_pointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop)
4551e4b17023SJohn Marino {
4552e4b17023SJohn Marino   tree res_type = TREE_TYPE (ptrop);
4553e4b17023SJohn Marino 
4554e4b17023SJohn Marino   /* pointer_int_sum() uses size_in_bytes() on the TREE_TYPE(res_type)
4555e4b17023SJohn Marino      in certain circumstance (when it's valid to do so).  So we need
4556e4b17023SJohn Marino      to make sure it's complete.  We don't need to check here, if we
4557e4b17023SJohn Marino      can actually complete it at all, as those checks will be done in
4558e4b17023SJohn Marino      pointer_int_sum() anyway.  */
4559e4b17023SJohn Marino   complete_type (TREE_TYPE (res_type));
4560e4b17023SJohn Marino 
4561e4b17023SJohn Marino   return pointer_int_sum (input_location, resultcode, ptrop,
4562e4b17023SJohn Marino 			  fold_if_not_in_template (intop));
4563e4b17023SJohn Marino }
4564e4b17023SJohn Marino 
4565e4b17023SJohn Marino /* Return a tree for the difference of pointers OP0 and OP1.
4566e4b17023SJohn Marino    The resulting tree has type int.  */
4567e4b17023SJohn Marino 
4568e4b17023SJohn Marino static tree
pointer_diff(tree op0,tree op1,tree ptrtype)4569e4b17023SJohn Marino pointer_diff (tree op0, tree op1, tree ptrtype)
4570e4b17023SJohn Marino {
4571e4b17023SJohn Marino   tree result;
4572e4b17023SJohn Marino   tree restype = ptrdiff_type_node;
4573e4b17023SJohn Marino   tree target_type = TREE_TYPE (ptrtype);
4574e4b17023SJohn Marino 
4575e4b17023SJohn Marino   if (!complete_type_or_else (target_type, NULL_TREE))
4576e4b17023SJohn Marino     return error_mark_node;
4577e4b17023SJohn Marino 
4578e4b17023SJohn Marino   if (TREE_CODE (target_type) == VOID_TYPE)
4579e4b17023SJohn Marino     permerror (input_location, "ISO C++ forbids using pointer of type %<void *%> in subtraction");
4580e4b17023SJohn Marino   if (TREE_CODE (target_type) == FUNCTION_TYPE)
4581e4b17023SJohn Marino     permerror (input_location, "ISO C++ forbids using pointer to a function in subtraction");
4582e4b17023SJohn Marino   if (TREE_CODE (target_type) == METHOD_TYPE)
4583e4b17023SJohn Marino     permerror (input_location, "ISO C++ forbids using pointer to a method in subtraction");
4584e4b17023SJohn Marino 
4585e4b17023SJohn Marino   /* First do the subtraction as integers;
4586e4b17023SJohn Marino      then drop through to build the divide operator.  */
4587e4b17023SJohn Marino 
4588e4b17023SJohn Marino   op0 = cp_build_binary_op (input_location,
4589e4b17023SJohn Marino 			    MINUS_EXPR,
4590e4b17023SJohn Marino 			    cp_convert (restype, op0),
4591e4b17023SJohn Marino 			    cp_convert (restype, op1),
4592e4b17023SJohn Marino 			    tf_warning_or_error);
4593e4b17023SJohn Marino 
4594e4b17023SJohn Marino   /* This generates an error if op1 is a pointer to an incomplete type.  */
4595e4b17023SJohn Marino   if (!COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (op1))))
4596e4b17023SJohn Marino     error ("invalid use of a pointer to an incomplete type in pointer arithmetic");
4597e4b17023SJohn Marino 
4598e4b17023SJohn Marino   op1 = (TYPE_PTROB_P (ptrtype)
4599e4b17023SJohn Marino 	 ? size_in_bytes (target_type)
4600e4b17023SJohn Marino 	 : integer_one_node);
4601e4b17023SJohn Marino 
4602e4b17023SJohn Marino   /* Do the division.  */
4603e4b17023SJohn Marino 
4604e4b17023SJohn Marino   result = build2 (EXACT_DIV_EXPR, restype, op0, cp_convert (restype, op1));
4605e4b17023SJohn Marino   return fold_if_not_in_template (result);
4606e4b17023SJohn Marino }
4607e4b17023SJohn Marino 
4608e4b17023SJohn Marino /* Construct and perhaps optimize a tree representation
4609e4b17023SJohn Marino    for a unary operation.  CODE, a tree_code, specifies the operation
4610e4b17023SJohn Marino    and XARG is the operand.  */
4611e4b17023SJohn Marino 
4612e4b17023SJohn Marino tree
build_x_unary_op(enum tree_code code,tree xarg,tsubst_flags_t complain)4613e4b17023SJohn Marino build_x_unary_op (enum tree_code code, tree xarg, tsubst_flags_t complain)
4614e4b17023SJohn Marino {
4615e4b17023SJohn Marino   tree orig_expr = xarg;
4616e4b17023SJohn Marino   tree exp;
4617e4b17023SJohn Marino   int ptrmem = 0;
4618e4b17023SJohn Marino 
4619e4b17023SJohn Marino   if (processing_template_decl)
4620e4b17023SJohn Marino     {
4621e4b17023SJohn Marino       if (type_dependent_expression_p (xarg))
4622e4b17023SJohn Marino 	return build_min_nt (code, xarg, NULL_TREE);
4623e4b17023SJohn Marino 
4624e4b17023SJohn Marino       xarg = build_non_dependent_expr (xarg);
4625e4b17023SJohn Marino     }
4626e4b17023SJohn Marino 
4627e4b17023SJohn Marino   exp = NULL_TREE;
4628e4b17023SJohn Marino 
4629e4b17023SJohn Marino   /* [expr.unary.op] says:
4630e4b17023SJohn Marino 
4631e4b17023SJohn Marino        The address of an object of incomplete type can be taken.
4632e4b17023SJohn Marino 
4633e4b17023SJohn Marino      (And is just the ordinary address operator, not an overloaded
4634e4b17023SJohn Marino      "operator &".)  However, if the type is a template
4635e4b17023SJohn Marino      specialization, we must complete the type at this point so that
4636e4b17023SJohn Marino      an overloaded "operator &" will be available if required.  */
4637e4b17023SJohn Marino   if (code == ADDR_EXPR
4638e4b17023SJohn Marino       && TREE_CODE (xarg) != TEMPLATE_ID_EXPR
4639e4b17023SJohn Marino       && ((CLASS_TYPE_P (TREE_TYPE (xarg))
4640e4b17023SJohn Marino 	   && !COMPLETE_TYPE_P (complete_type (TREE_TYPE (xarg))))
4641e4b17023SJohn Marino 	  || (TREE_CODE (xarg) == OFFSET_REF)))
4642e4b17023SJohn Marino     /* Don't look for a function.  */;
4643e4b17023SJohn Marino   else
4644e4b17023SJohn Marino     exp = build_new_op (code, LOOKUP_NORMAL, xarg, NULL_TREE, NULL_TREE,
4645e4b17023SJohn Marino 			/*overload=*/NULL, complain);
4646e4b17023SJohn Marino   if (!exp && code == ADDR_EXPR)
4647e4b17023SJohn Marino     {
4648e4b17023SJohn Marino       if (is_overloaded_fn (xarg))
4649e4b17023SJohn Marino 	{
4650e4b17023SJohn Marino 	  tree fn = get_first_fn (xarg);
4651e4b17023SJohn Marino 	  if (DECL_CONSTRUCTOR_P (fn) || DECL_DESTRUCTOR_P (fn))
4652e4b17023SJohn Marino 	    {
4653e4b17023SJohn Marino 	      error (DECL_CONSTRUCTOR_P (fn)
4654e4b17023SJohn Marino                      ? G_("taking address of constructor %qE")
4655e4b17023SJohn Marino                      : G_("taking address of destructor %qE"),
4656e4b17023SJohn Marino                      xarg);
4657e4b17023SJohn Marino 	      return error_mark_node;
4658e4b17023SJohn Marino 	    }
4659e4b17023SJohn Marino 	}
4660e4b17023SJohn Marino 
4661e4b17023SJohn Marino       /* A pointer to member-function can be formed only by saying
4662e4b17023SJohn Marino 	 &X::mf.  */
4663e4b17023SJohn Marino       if (!flag_ms_extensions && TREE_CODE (TREE_TYPE (xarg)) == METHOD_TYPE
4664e4b17023SJohn Marino 	  && (TREE_CODE (xarg) != OFFSET_REF || !PTRMEM_OK_P (xarg)))
4665e4b17023SJohn Marino 	{
4666e4b17023SJohn Marino 	  if (TREE_CODE (xarg) != OFFSET_REF
4667e4b17023SJohn Marino 	      || !TYPE_P (TREE_OPERAND (xarg, 0)))
4668e4b17023SJohn Marino 	    {
4669e4b17023SJohn Marino               error ("invalid use of %qE to form a pointer-to-member-function",
4670e4b17023SJohn Marino                      xarg);
4671e4b17023SJohn Marino               if (TREE_CODE (xarg) != OFFSET_REF)
4672e4b17023SJohn Marino                 inform (input_location, "  a qualified-id is required");
4673e4b17023SJohn Marino 	      return error_mark_node;
4674e4b17023SJohn Marino 	    }
4675e4b17023SJohn Marino 	  else
4676e4b17023SJohn Marino 	    {
4677e4b17023SJohn Marino 	      error ("parentheses around %qE cannot be used to form a"
4678e4b17023SJohn Marino 		     " pointer-to-member-function",
4679e4b17023SJohn Marino 		     xarg);
4680e4b17023SJohn Marino 	      PTRMEM_OK_P (xarg) = 1;
4681e4b17023SJohn Marino 	    }
4682e4b17023SJohn Marino 	}
4683e4b17023SJohn Marino 
4684e4b17023SJohn Marino       if (TREE_CODE (xarg) == OFFSET_REF)
4685e4b17023SJohn Marino 	{
4686e4b17023SJohn Marino 	  ptrmem = PTRMEM_OK_P (xarg);
4687e4b17023SJohn Marino 
4688e4b17023SJohn Marino 	  if (!ptrmem && !flag_ms_extensions
4689e4b17023SJohn Marino 	      && TREE_CODE (TREE_TYPE (TREE_OPERAND (xarg, 1))) == METHOD_TYPE)
4690e4b17023SJohn Marino 	    {
4691e4b17023SJohn Marino 	      /* A single non-static member, make sure we don't allow a
4692e4b17023SJohn Marino 		 pointer-to-member.  */
4693e4b17023SJohn Marino 	      xarg = build2 (OFFSET_REF, TREE_TYPE (xarg),
4694e4b17023SJohn Marino 			     TREE_OPERAND (xarg, 0),
4695e4b17023SJohn Marino 			     ovl_cons (TREE_OPERAND (xarg, 1), NULL_TREE));
4696e4b17023SJohn Marino 	      PTRMEM_OK_P (xarg) = ptrmem;
4697e4b17023SJohn Marino 	    }
4698e4b17023SJohn Marino 	}
4699e4b17023SJohn Marino 
4700e4b17023SJohn Marino       exp = cp_build_addr_expr_strict (xarg, complain);
4701e4b17023SJohn Marino     }
4702e4b17023SJohn Marino 
4703e4b17023SJohn Marino   if (processing_template_decl && exp != error_mark_node)
4704e4b17023SJohn Marino     exp = build_min_non_dep (code, exp, orig_expr,
4705e4b17023SJohn Marino 			     /*For {PRE,POST}{INC,DEC}REMENT_EXPR*/NULL_TREE);
4706e4b17023SJohn Marino   if (TREE_CODE (exp) == ADDR_EXPR)
4707e4b17023SJohn Marino     PTRMEM_OK_P (exp) = ptrmem;
4708e4b17023SJohn Marino   return exp;
4709e4b17023SJohn Marino }
4710e4b17023SJohn Marino 
4711e4b17023SJohn Marino /* Like c_common_truthvalue_conversion, but handle pointer-to-member
4712e4b17023SJohn Marino    constants, where a null value is represented by an INTEGER_CST of
4713e4b17023SJohn Marino    -1.  */
4714e4b17023SJohn Marino 
4715e4b17023SJohn Marino tree
cp_truthvalue_conversion(tree expr)4716e4b17023SJohn Marino cp_truthvalue_conversion (tree expr)
4717e4b17023SJohn Marino {
4718e4b17023SJohn Marino   tree type = TREE_TYPE (expr);
4719e4b17023SJohn Marino   if (TYPE_PTRMEM_P (type))
4720e4b17023SJohn Marino     return build_binary_op (EXPR_LOCATION (expr),
4721e4b17023SJohn Marino 			    NE_EXPR, expr, nullptr_node, 1);
4722e4b17023SJohn Marino   else if (TYPE_PTR_P (type) || TYPE_PTRMEMFUNC_P (type))
4723e4b17023SJohn Marino     {
4724e4b17023SJohn Marino       /* With -Wzero-as-null-pointer-constant do not warn for an
4725e4b17023SJohn Marino 	 'if (p)' or a 'while (!p)', where p is a pointer.  */
4726e4b17023SJohn Marino       tree ret;
4727e4b17023SJohn Marino       ++c_inhibit_evaluation_warnings;
4728e4b17023SJohn Marino       ret = c_common_truthvalue_conversion (input_location, expr);
4729e4b17023SJohn Marino       --c_inhibit_evaluation_warnings;
4730e4b17023SJohn Marino       return ret;
4731e4b17023SJohn Marino     }
4732e4b17023SJohn Marino   else
4733e4b17023SJohn Marino     return c_common_truthvalue_conversion (input_location, expr);
4734e4b17023SJohn Marino }
4735e4b17023SJohn Marino 
4736e4b17023SJohn Marino /* Just like cp_truthvalue_conversion, but we want a CLEANUP_POINT_EXPR.  */
4737e4b17023SJohn Marino 
4738e4b17023SJohn Marino tree
condition_conversion(tree expr)4739e4b17023SJohn Marino condition_conversion (tree expr)
4740e4b17023SJohn Marino {
4741e4b17023SJohn Marino   tree t;
4742e4b17023SJohn Marino   if (processing_template_decl)
4743e4b17023SJohn Marino     return expr;
4744e4b17023SJohn Marino   t = perform_implicit_conversion_flags (boolean_type_node, expr,
4745e4b17023SJohn Marino 					 tf_warning_or_error, LOOKUP_NORMAL);
4746e4b17023SJohn Marino   t = fold_build_cleanup_point_expr (boolean_type_node, t);
4747e4b17023SJohn Marino   return t;
4748e4b17023SJohn Marino }
4749e4b17023SJohn Marino 
4750e4b17023SJohn Marino /* Returns the address of T.  This function will fold away
4751e4b17023SJohn Marino    ADDR_EXPR of INDIRECT_REF.  */
4752e4b17023SJohn Marino 
4753e4b17023SJohn Marino tree
build_address(tree t)4754e4b17023SJohn Marino build_address (tree t)
4755e4b17023SJohn Marino {
4756e4b17023SJohn Marino   if (error_operand_p (t) || !cxx_mark_addressable (t))
4757e4b17023SJohn Marino     return error_mark_node;
4758e4b17023SJohn Marino   t = build_fold_addr_expr (t);
4759e4b17023SJohn Marino   if (TREE_CODE (t) != ADDR_EXPR)
4760e4b17023SJohn Marino     t = rvalue (t);
4761e4b17023SJohn Marino   return t;
4762e4b17023SJohn Marino }
4763e4b17023SJohn Marino 
4764e4b17023SJohn Marino /* Returns the address of T with type TYPE.  */
4765e4b17023SJohn Marino 
4766e4b17023SJohn Marino tree
build_typed_address(tree t,tree type)4767e4b17023SJohn Marino build_typed_address (tree t, tree type)
4768e4b17023SJohn Marino {
4769e4b17023SJohn Marino   if (error_operand_p (t) || !cxx_mark_addressable (t))
4770e4b17023SJohn Marino     return error_mark_node;
4771e4b17023SJohn Marino   t = build_fold_addr_expr_with_type (t, type);
4772e4b17023SJohn Marino   if (TREE_CODE (t) != ADDR_EXPR)
4773e4b17023SJohn Marino     t = rvalue (t);
4774e4b17023SJohn Marino   return t;
4775e4b17023SJohn Marino }
4776e4b17023SJohn Marino 
4777e4b17023SJohn Marino /* Return a NOP_EXPR converting EXPR to TYPE.  */
4778e4b17023SJohn Marino 
4779e4b17023SJohn Marino tree
build_nop(tree type,tree expr)4780e4b17023SJohn Marino build_nop (tree type, tree expr)
4781e4b17023SJohn Marino {
4782e4b17023SJohn Marino   if (type == error_mark_node || error_operand_p (expr))
4783e4b17023SJohn Marino     return expr;
4784e4b17023SJohn Marino   return build1 (NOP_EXPR, type, expr);
4785e4b17023SJohn Marino }
4786e4b17023SJohn Marino 
4787e4b17023SJohn Marino /* Take the address of ARG, whatever that means under C++ semantics.
4788e4b17023SJohn Marino    If STRICT_LVALUE is true, require an lvalue; otherwise, allow xvalues
4789e4b17023SJohn Marino    and class rvalues as well.
4790e4b17023SJohn Marino 
4791e4b17023SJohn Marino    Nothing should call this function directly; instead, callers should use
4792e4b17023SJohn Marino    cp_build_addr_expr or cp_build_addr_expr_strict.  */
4793e4b17023SJohn Marino 
4794e4b17023SJohn Marino static tree
cp_build_addr_expr_1(tree arg,bool strict_lvalue,tsubst_flags_t complain)4795e4b17023SJohn Marino cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain)
4796e4b17023SJohn Marino {
4797e4b17023SJohn Marino   tree argtype;
4798e4b17023SJohn Marino   tree val;
4799e4b17023SJohn Marino 
4800e4b17023SJohn Marino   if (!arg || error_operand_p (arg))
4801e4b17023SJohn Marino     return error_mark_node;
4802e4b17023SJohn Marino 
4803e4b17023SJohn Marino   arg = mark_lvalue_use (arg);
4804e4b17023SJohn Marino   argtype = lvalue_type (arg);
4805e4b17023SJohn Marino 
4806e4b17023SJohn Marino   gcc_assert (TREE_CODE (arg) != IDENTIFIER_NODE
4807e4b17023SJohn Marino 	      || !IDENTIFIER_OPNAME_P (arg));
4808e4b17023SJohn Marino 
4809e4b17023SJohn Marino   if (TREE_CODE (arg) == COMPONENT_REF && type_unknown_p (arg)
4810e4b17023SJohn Marino       && !really_overloaded_fn (TREE_OPERAND (arg, 1)))
4811e4b17023SJohn Marino     {
4812e4b17023SJohn Marino       /* They're trying to take the address of a unique non-static
4813e4b17023SJohn Marino 	 member function.  This is ill-formed (except in MS-land),
4814e4b17023SJohn Marino 	 but let's try to DTRT.
4815e4b17023SJohn Marino 	 Note: We only handle unique functions here because we don't
4816e4b17023SJohn Marino 	 want to complain if there's a static overload; non-unique
4817e4b17023SJohn Marino 	 cases will be handled by instantiate_type.  But we need to
4818e4b17023SJohn Marino 	 handle this case here to allow casts on the resulting PMF.
4819e4b17023SJohn Marino 	 We could defer this in non-MS mode, but it's easier to give
4820e4b17023SJohn Marino 	 a useful error here.  */
4821e4b17023SJohn Marino 
4822e4b17023SJohn Marino       /* Inside constant member functions, the `this' pointer
4823e4b17023SJohn Marino 	 contains an extra const qualifier.  TYPE_MAIN_VARIANT
4824e4b17023SJohn Marino 	 is used here to remove this const from the diagnostics
4825e4b17023SJohn Marino 	 and the created OFFSET_REF.  */
4826e4b17023SJohn Marino       tree base = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (arg, 0)));
4827e4b17023SJohn Marino       tree fn = get_first_fn (TREE_OPERAND (arg, 1));
4828e4b17023SJohn Marino       mark_used (fn);
4829e4b17023SJohn Marino 
4830e4b17023SJohn Marino       if (! flag_ms_extensions)
4831e4b17023SJohn Marino 	{
4832e4b17023SJohn Marino 	  tree name = DECL_NAME (fn);
4833e4b17023SJohn Marino 	  if (!(complain & tf_error))
4834e4b17023SJohn Marino 	    return error_mark_node;
4835e4b17023SJohn Marino 	  else if (current_class_type
4836e4b17023SJohn Marino 		   && TREE_OPERAND (arg, 0) == current_class_ref)
4837e4b17023SJohn Marino 	    /* An expression like &memfn.  */
4838e4b17023SJohn Marino 	    permerror (input_location, "ISO C++ forbids taking the address of an unqualified"
4839e4b17023SJohn Marino 		       " or parenthesized non-static member function to form"
4840e4b17023SJohn Marino 		       " a pointer to member function.  Say %<&%T::%D%>",
4841e4b17023SJohn Marino 		       base, name);
4842e4b17023SJohn Marino 	  else
4843e4b17023SJohn Marino 	    permerror (input_location, "ISO C++ forbids taking the address of a bound member"
4844e4b17023SJohn Marino 		       " function to form a pointer to member function."
4845e4b17023SJohn Marino 		       "  Say %<&%T::%D%>",
4846e4b17023SJohn Marino 		       base, name);
4847e4b17023SJohn Marino 	}
4848e4b17023SJohn Marino       arg = build_offset_ref (base, fn, /*address_p=*/true);
4849e4b17023SJohn Marino     }
4850e4b17023SJohn Marino 
4851e4b17023SJohn Marino   /* Uninstantiated types are all functions.  Taking the
4852e4b17023SJohn Marino      address of a function is a no-op, so just return the
4853e4b17023SJohn Marino      argument.  */
4854e4b17023SJohn Marino   if (type_unknown_p (arg))
4855e4b17023SJohn Marino     return build1 (ADDR_EXPR, unknown_type_node, arg);
4856e4b17023SJohn Marino 
4857e4b17023SJohn Marino   if (TREE_CODE (arg) == OFFSET_REF)
4858e4b17023SJohn Marino     /* We want a pointer to member; bypass all the code for actually taking
4859e4b17023SJohn Marino        the address of something.  */
4860e4b17023SJohn Marino     goto offset_ref;
4861e4b17023SJohn Marino 
4862e4b17023SJohn Marino   /* Anything not already handled and not a true memory reference
4863e4b17023SJohn Marino      is an error.  */
4864e4b17023SJohn Marino   if (TREE_CODE (argtype) != FUNCTION_TYPE
4865e4b17023SJohn Marino       && TREE_CODE (argtype) != METHOD_TYPE)
4866e4b17023SJohn Marino     {
4867e4b17023SJohn Marino       cp_lvalue_kind kind = lvalue_kind (arg);
4868e4b17023SJohn Marino       if (kind == clk_none)
4869e4b17023SJohn Marino 	{
4870e4b17023SJohn Marino 	  if (complain & tf_error)
4871e4b17023SJohn Marino 	    lvalue_error (input_location, lv_addressof);
4872e4b17023SJohn Marino 	  return error_mark_node;
4873e4b17023SJohn Marino 	}
4874e4b17023SJohn Marino       if (strict_lvalue && (kind & (clk_rvalueref|clk_class)))
4875e4b17023SJohn Marino 	{
4876e4b17023SJohn Marino 	  if (!(complain & tf_error))
4877e4b17023SJohn Marino 	    return error_mark_node;
4878e4b17023SJohn Marino 	  if (kind & clk_class)
4879e4b17023SJohn Marino 	    /* Make this a permerror because we used to accept it.  */
4880e4b17023SJohn Marino 	    permerror (input_location, "taking address of temporary");
4881e4b17023SJohn Marino 	  else
4882e4b17023SJohn Marino 	    error ("taking address of xvalue (rvalue reference)");
4883e4b17023SJohn Marino 	}
4884e4b17023SJohn Marino     }
4885e4b17023SJohn Marino 
4886e4b17023SJohn Marino   if (TREE_CODE (argtype) == REFERENCE_TYPE)
4887e4b17023SJohn Marino     {
4888e4b17023SJohn Marino       tree type = build_pointer_type (TREE_TYPE (argtype));
4889e4b17023SJohn Marino       arg = build1 (CONVERT_EXPR, type, arg);
4890e4b17023SJohn Marino       return arg;
4891e4b17023SJohn Marino     }
4892e4b17023SJohn Marino   else if (pedantic && DECL_MAIN_P (arg))
4893e4b17023SJohn Marino     {
4894e4b17023SJohn Marino       /* ARM $3.4 */
4895e4b17023SJohn Marino       /* Apparently a lot of autoconf scripts for C++ packages do this,
4896e4b17023SJohn Marino 	 so only complain if -pedantic.  */
4897e4b17023SJohn Marino       if (complain & (flag_pedantic_errors ? tf_error : tf_warning))
4898e4b17023SJohn Marino 	pedwarn (input_location, OPT_pedantic,
4899e4b17023SJohn Marino 		 "ISO C++ forbids taking address of function %<::main%>");
4900e4b17023SJohn Marino       else if (flag_pedantic_errors)
4901e4b17023SJohn Marino 	return error_mark_node;
4902e4b17023SJohn Marino     }
4903e4b17023SJohn Marino 
4904e4b17023SJohn Marino   /* Let &* cancel out to simplify resulting code.  */
4905e4b17023SJohn Marino   if (TREE_CODE (arg) == INDIRECT_REF)
4906e4b17023SJohn Marino     {
4907e4b17023SJohn Marino       /* We don't need to have `current_class_ptr' wrapped in a
4908e4b17023SJohn Marino 	 NON_LVALUE_EXPR node.  */
4909e4b17023SJohn Marino       if (arg == current_class_ref)
4910e4b17023SJohn Marino 	return current_class_ptr;
4911e4b17023SJohn Marino 
4912e4b17023SJohn Marino       arg = TREE_OPERAND (arg, 0);
4913e4b17023SJohn Marino       if (TREE_CODE (TREE_TYPE (arg)) == REFERENCE_TYPE)
4914e4b17023SJohn Marino 	{
4915e4b17023SJohn Marino 	  tree type = build_pointer_type (TREE_TYPE (TREE_TYPE (arg)));
4916e4b17023SJohn Marino 	  arg = build1 (CONVERT_EXPR, type, arg);
4917e4b17023SJohn Marino 	}
4918e4b17023SJohn Marino       else
4919e4b17023SJohn Marino 	/* Don't let this be an lvalue.  */
4920e4b17023SJohn Marino 	arg = rvalue (arg);
4921e4b17023SJohn Marino       return arg;
4922e4b17023SJohn Marino     }
4923e4b17023SJohn Marino 
4924e4b17023SJohn Marino   /* ??? Cope with user tricks that amount to offsetof.  */
4925e4b17023SJohn Marino   if (TREE_CODE (argtype) != FUNCTION_TYPE
4926e4b17023SJohn Marino       && TREE_CODE (argtype) != METHOD_TYPE
4927e4b17023SJohn Marino       && argtype != unknown_type_node
4928e4b17023SJohn Marino       && (val = get_base_address (arg))
4929e4b17023SJohn Marino       && COMPLETE_TYPE_P (TREE_TYPE (val))
4930e4b17023SJohn Marino       && TREE_CODE (val) == INDIRECT_REF
4931e4b17023SJohn Marino       && TREE_CONSTANT (TREE_OPERAND (val, 0)))
4932e4b17023SJohn Marino     {
4933e4b17023SJohn Marino       tree type = build_pointer_type (argtype);
4934e4b17023SJohn Marino       return fold_convert (type, fold_offsetof_1 (arg));
4935e4b17023SJohn Marino     }
4936e4b17023SJohn Marino 
4937e4b17023SJohn Marino   /* Handle complex lvalues (when permitted)
4938e4b17023SJohn Marino      by reduction to simpler cases.  */
4939e4b17023SJohn Marino   val = unary_complex_lvalue (ADDR_EXPR, arg);
4940e4b17023SJohn Marino   if (val != 0)
4941e4b17023SJohn Marino     return val;
4942e4b17023SJohn Marino 
4943e4b17023SJohn Marino   switch (TREE_CODE (arg))
4944e4b17023SJohn Marino     {
4945e4b17023SJohn Marino     CASE_CONVERT:
4946e4b17023SJohn Marino     case FLOAT_EXPR:
4947e4b17023SJohn Marino     case FIX_TRUNC_EXPR:
4948e4b17023SJohn Marino       /* Even if we're not being pedantic, we cannot allow this
4949e4b17023SJohn Marino 	 extension when we're instantiating in a SFINAE
4950e4b17023SJohn Marino 	 context.  */
4951e4b17023SJohn Marino       if (! lvalue_p (arg) && complain == tf_none)
4952e4b17023SJohn Marino 	{
4953e4b17023SJohn Marino 	  if (complain & tf_error)
4954e4b17023SJohn Marino 	    permerror (input_location, "ISO C++ forbids taking the address of a cast to a non-lvalue expression");
4955e4b17023SJohn Marino 	  else
4956e4b17023SJohn Marino 	    return error_mark_node;
4957e4b17023SJohn Marino 	}
4958e4b17023SJohn Marino       break;
4959e4b17023SJohn Marino 
4960e4b17023SJohn Marino     case BASELINK:
4961e4b17023SJohn Marino       arg = BASELINK_FUNCTIONS (arg);
4962e4b17023SJohn Marino       /* Fall through.  */
4963e4b17023SJohn Marino 
4964e4b17023SJohn Marino     case OVERLOAD:
4965e4b17023SJohn Marino       arg = OVL_CURRENT (arg);
4966e4b17023SJohn Marino       break;
4967e4b17023SJohn Marino 
4968e4b17023SJohn Marino     case OFFSET_REF:
4969e4b17023SJohn Marino     offset_ref:
4970e4b17023SJohn Marino       /* Turn a reference to a non-static data member into a
4971e4b17023SJohn Marino 	 pointer-to-member.  */
4972e4b17023SJohn Marino       {
4973e4b17023SJohn Marino 	tree type;
4974e4b17023SJohn Marino 	tree t;
4975e4b17023SJohn Marino 
4976e4b17023SJohn Marino 	gcc_assert (PTRMEM_OK_P (arg));
4977e4b17023SJohn Marino 
4978e4b17023SJohn Marino 	t = TREE_OPERAND (arg, 1);
4979e4b17023SJohn Marino 	if (TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE)
4980e4b17023SJohn Marino 	  {
4981e4b17023SJohn Marino 	    if (complain & tf_error)
4982e4b17023SJohn Marino 	      error ("cannot create pointer to reference member %qD", t);
4983e4b17023SJohn Marino 	    return error_mark_node;
4984e4b17023SJohn Marino 	  }
4985e4b17023SJohn Marino 
4986e4b17023SJohn Marino 	type = build_ptrmem_type (context_for_name_lookup (t),
4987e4b17023SJohn Marino 				  TREE_TYPE (t));
4988e4b17023SJohn Marino 	t = make_ptrmem_cst (type, TREE_OPERAND (arg, 1));
4989e4b17023SJohn Marino 	return t;
4990e4b17023SJohn Marino       }
4991e4b17023SJohn Marino 
4992e4b17023SJohn Marino     default:
4993e4b17023SJohn Marino       break;
4994e4b17023SJohn Marino     }
4995e4b17023SJohn Marino 
4996e4b17023SJohn Marino   if (argtype != error_mark_node)
4997e4b17023SJohn Marino     argtype = build_pointer_type (argtype);
4998e4b17023SJohn Marino 
4999e4b17023SJohn Marino   /* In a template, we are processing a non-dependent expression
5000e4b17023SJohn Marino      so we can just form an ADDR_EXPR with the correct type.  */
5001e4b17023SJohn Marino   if (processing_template_decl || TREE_CODE (arg) != COMPONENT_REF)
5002e4b17023SJohn Marino     {
5003e4b17023SJohn Marino       val = build_address (arg);
5004e4b17023SJohn Marino       if (TREE_CODE (arg) == OFFSET_REF)
5005e4b17023SJohn Marino 	PTRMEM_OK_P (val) = PTRMEM_OK_P (arg);
5006e4b17023SJohn Marino     }
5007e4b17023SJohn Marino   else if (BASELINK_P (TREE_OPERAND (arg, 1)))
5008e4b17023SJohn Marino     {
5009e4b17023SJohn Marino       tree fn = BASELINK_FUNCTIONS (TREE_OPERAND (arg, 1));
5010e4b17023SJohn Marino 
5011e4b17023SJohn Marino       /* We can only get here with a single static member
5012e4b17023SJohn Marino 	 function.  */
5013e4b17023SJohn Marino       gcc_assert (TREE_CODE (fn) == FUNCTION_DECL
5014e4b17023SJohn Marino 		  && DECL_STATIC_FUNCTION_P (fn));
5015e4b17023SJohn Marino       mark_used (fn);
5016e4b17023SJohn Marino       val = build_address (fn);
5017e4b17023SJohn Marino       if (TREE_SIDE_EFFECTS (TREE_OPERAND (arg, 0)))
5018e4b17023SJohn Marino 	/* Do not lose object's side effects.  */
5019e4b17023SJohn Marino 	val = build2 (COMPOUND_EXPR, TREE_TYPE (val),
5020e4b17023SJohn Marino 		      TREE_OPERAND (arg, 0), val);
5021e4b17023SJohn Marino     }
5022e4b17023SJohn Marino   else if (DECL_C_BIT_FIELD (TREE_OPERAND (arg, 1)))
5023e4b17023SJohn Marino     {
5024e4b17023SJohn Marino       if (complain & tf_error)
5025e4b17023SJohn Marino 	error ("attempt to take address of bit-field structure member %qD",
5026e4b17023SJohn Marino 	       TREE_OPERAND (arg, 1));
5027e4b17023SJohn Marino       return error_mark_node;
5028e4b17023SJohn Marino     }
5029e4b17023SJohn Marino   else
5030e4b17023SJohn Marino     {
5031e4b17023SJohn Marino       tree object = TREE_OPERAND (arg, 0);
5032e4b17023SJohn Marino       tree field = TREE_OPERAND (arg, 1);
5033e4b17023SJohn Marino       gcc_assert (same_type_ignoring_top_level_qualifiers_p
5034e4b17023SJohn Marino 		  (TREE_TYPE (object), decl_type_context (field)));
5035e4b17023SJohn Marino       val = build_address (arg);
5036e4b17023SJohn Marino     }
5037e4b17023SJohn Marino 
5038e4b17023SJohn Marino   if (TREE_CODE (argtype) == POINTER_TYPE
5039e4b17023SJohn Marino       && TREE_CODE (TREE_TYPE (argtype)) == METHOD_TYPE)
5040e4b17023SJohn Marino     {
5041e4b17023SJohn Marino       build_ptrmemfunc_type (argtype);
5042e4b17023SJohn Marino       val = build_ptrmemfunc (argtype, val, 0,
5043e4b17023SJohn Marino 			      /*c_cast_p=*/false,
5044e4b17023SJohn Marino 			      tf_warning_or_error);
5045e4b17023SJohn Marino     }
5046e4b17023SJohn Marino 
5047e4b17023SJohn Marino   return val;
5048e4b17023SJohn Marino }
5049e4b17023SJohn Marino 
5050e4b17023SJohn Marino /* Take the address of ARG if it has one, even if it's an rvalue.  */
5051e4b17023SJohn Marino 
5052e4b17023SJohn Marino tree
cp_build_addr_expr(tree arg,tsubst_flags_t complain)5053e4b17023SJohn Marino cp_build_addr_expr (tree arg, tsubst_flags_t complain)
5054e4b17023SJohn Marino {
5055e4b17023SJohn Marino   return cp_build_addr_expr_1 (arg, 0, complain);
5056e4b17023SJohn Marino }
5057e4b17023SJohn Marino 
5058e4b17023SJohn Marino /* Take the address of ARG, but only if it's an lvalue.  */
5059e4b17023SJohn Marino 
5060e4b17023SJohn Marino tree
cp_build_addr_expr_strict(tree arg,tsubst_flags_t complain)5061e4b17023SJohn Marino cp_build_addr_expr_strict (tree arg, tsubst_flags_t complain)
5062e4b17023SJohn Marino {
5063e4b17023SJohn Marino   return cp_build_addr_expr_1 (arg, 1, complain);
5064e4b17023SJohn Marino }
5065e4b17023SJohn Marino 
5066e4b17023SJohn Marino /* C++: Must handle pointers to members.
5067e4b17023SJohn Marino 
5068e4b17023SJohn Marino    Perhaps type instantiation should be extended to handle conversion
5069e4b17023SJohn Marino    from aggregates to types we don't yet know we want?  (Or are those
5070e4b17023SJohn Marino    cases typically errors which should be reported?)
5071e4b17023SJohn Marino 
5072e4b17023SJohn Marino    NOCONVERT nonzero suppresses the default promotions
5073e4b17023SJohn Marino    (such as from short to int).  */
5074e4b17023SJohn Marino 
5075e4b17023SJohn Marino tree
cp_build_unary_op(enum tree_code code,tree xarg,int noconvert,tsubst_flags_t complain)5076e4b17023SJohn Marino cp_build_unary_op (enum tree_code code, tree xarg, int noconvert,
5077e4b17023SJohn Marino                    tsubst_flags_t complain)
5078e4b17023SJohn Marino {
5079e4b17023SJohn Marino   /* No default_conversion here.  It causes trouble for ADDR_EXPR.  */
5080e4b17023SJohn Marino   tree arg = xarg;
5081e4b17023SJohn Marino   tree argtype = 0;
5082e4b17023SJohn Marino   const char *errstring = NULL;
5083e4b17023SJohn Marino   tree val;
5084e4b17023SJohn Marino   const char *invalid_op_diag;
5085e4b17023SJohn Marino 
5086e4b17023SJohn Marino   if (!arg || error_operand_p (arg))
5087e4b17023SJohn Marino     return error_mark_node;
5088e4b17023SJohn Marino 
5089e4b17023SJohn Marino   if ((invalid_op_diag
5090e4b17023SJohn Marino        = targetm.invalid_unary_op ((code == UNARY_PLUS_EXPR
5091e4b17023SJohn Marino 				    ? CONVERT_EXPR
5092e4b17023SJohn Marino 				    : code),
5093e4b17023SJohn Marino 				   TREE_TYPE (xarg))))
5094e4b17023SJohn Marino     {
5095e4b17023SJohn Marino       error (invalid_op_diag);
5096e4b17023SJohn Marino       return error_mark_node;
5097e4b17023SJohn Marino     }
5098e4b17023SJohn Marino 
5099e4b17023SJohn Marino   switch (code)
5100e4b17023SJohn Marino     {
5101e4b17023SJohn Marino     case UNARY_PLUS_EXPR:
5102e4b17023SJohn Marino     case NEGATE_EXPR:
5103e4b17023SJohn Marino       {
5104e4b17023SJohn Marino 	int flags = WANT_ARITH | WANT_ENUM;
5105e4b17023SJohn Marino 	/* Unary plus (but not unary minus) is allowed on pointers.  */
5106e4b17023SJohn Marino 	if (code == UNARY_PLUS_EXPR)
5107e4b17023SJohn Marino 	  flags |= WANT_POINTER;
5108e4b17023SJohn Marino 	arg = build_expr_type_conversion (flags, arg, true);
5109e4b17023SJohn Marino 	if (!arg)
5110e4b17023SJohn Marino 	  errstring = (code == NEGATE_EXPR
5111e4b17023SJohn Marino 		       ? _("wrong type argument to unary minus")
5112e4b17023SJohn Marino 		       : _("wrong type argument to unary plus"));
5113e4b17023SJohn Marino 	else
5114e4b17023SJohn Marino 	  {
5115e4b17023SJohn Marino 	    if (!noconvert && CP_INTEGRAL_TYPE_P (TREE_TYPE (arg)))
5116e4b17023SJohn Marino 	      arg = perform_integral_promotions (arg);
5117e4b17023SJohn Marino 
5118e4b17023SJohn Marino 	    /* Make sure the result is not an lvalue: a unary plus or minus
5119e4b17023SJohn Marino 	       expression is always a rvalue.  */
5120e4b17023SJohn Marino 	    arg = rvalue (arg);
5121e4b17023SJohn Marino 	  }
5122e4b17023SJohn Marino       }
5123e4b17023SJohn Marino       break;
5124e4b17023SJohn Marino 
5125e4b17023SJohn Marino     case BIT_NOT_EXPR:
5126e4b17023SJohn Marino       if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
5127e4b17023SJohn Marino 	{
5128e4b17023SJohn Marino 	  code = CONJ_EXPR;
5129e4b17023SJohn Marino 	  if (!noconvert)
5130e4b17023SJohn Marino 	    arg = default_conversion (arg);
5131e4b17023SJohn Marino 	}
5132e4b17023SJohn Marino       else if (!(arg = build_expr_type_conversion (WANT_INT | WANT_ENUM
5133e4b17023SJohn Marino 						   | WANT_VECTOR_OR_COMPLEX,
5134e4b17023SJohn Marino 						   arg, true)))
5135e4b17023SJohn Marino 	errstring = _("wrong type argument to bit-complement");
5136e4b17023SJohn Marino       else if (!noconvert && CP_INTEGRAL_TYPE_P (TREE_TYPE (arg)))
5137e4b17023SJohn Marino 	arg = perform_integral_promotions (arg);
5138e4b17023SJohn Marino       break;
5139e4b17023SJohn Marino 
5140e4b17023SJohn Marino     case ABS_EXPR:
5141e4b17023SJohn Marino       if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, arg, true)))
5142e4b17023SJohn Marino 	errstring = _("wrong type argument to abs");
5143e4b17023SJohn Marino       else if (!noconvert)
5144e4b17023SJohn Marino 	arg = default_conversion (arg);
5145e4b17023SJohn Marino       break;
5146e4b17023SJohn Marino 
5147e4b17023SJohn Marino     case CONJ_EXPR:
5148e4b17023SJohn Marino       /* Conjugating a real value is a no-op, but allow it anyway.  */
5149e4b17023SJohn Marino       if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, arg, true)))
5150e4b17023SJohn Marino 	errstring = _("wrong type argument to conjugation");
5151e4b17023SJohn Marino       else if (!noconvert)
5152e4b17023SJohn Marino 	arg = default_conversion (arg);
5153e4b17023SJohn Marino       break;
5154e4b17023SJohn Marino 
5155e4b17023SJohn Marino     case TRUTH_NOT_EXPR:
5156e4b17023SJohn Marino       arg = perform_implicit_conversion (boolean_type_node, arg,
5157e4b17023SJohn Marino 					 complain);
5158e4b17023SJohn Marino       val = invert_truthvalue_loc (input_location, arg);
5159e4b17023SJohn Marino       if (arg != error_mark_node)
5160e4b17023SJohn Marino 	return val;
5161e4b17023SJohn Marino       errstring = _("in argument to unary !");
5162e4b17023SJohn Marino       break;
5163e4b17023SJohn Marino 
5164e4b17023SJohn Marino     case NOP_EXPR:
5165e4b17023SJohn Marino       break;
5166e4b17023SJohn Marino 
5167e4b17023SJohn Marino     case REALPART_EXPR:
5168e4b17023SJohn Marino     case IMAGPART_EXPR:
5169e4b17023SJohn Marino       arg = build_real_imag_expr (input_location, code, arg);
5170e4b17023SJohn Marino       if (arg == error_mark_node)
5171e4b17023SJohn Marino 	return arg;
5172e4b17023SJohn Marino       else
5173e4b17023SJohn Marino 	return fold_if_not_in_template (arg);
5174e4b17023SJohn Marino 
5175e4b17023SJohn Marino     case PREINCREMENT_EXPR:
5176e4b17023SJohn Marino     case POSTINCREMENT_EXPR:
5177e4b17023SJohn Marino     case PREDECREMENT_EXPR:
5178e4b17023SJohn Marino     case POSTDECREMENT_EXPR:
5179e4b17023SJohn Marino       /* Handle complex lvalues (when permitted)
5180e4b17023SJohn Marino 	 by reduction to simpler cases.  */
5181e4b17023SJohn Marino 
5182e4b17023SJohn Marino       val = unary_complex_lvalue (code, arg);
5183e4b17023SJohn Marino       if (val != 0)
5184e4b17023SJohn Marino 	return val;
5185e4b17023SJohn Marino 
5186e4b17023SJohn Marino       arg = mark_lvalue_use (arg);
5187e4b17023SJohn Marino 
5188e4b17023SJohn Marino       /* Increment or decrement the real part of the value,
5189e4b17023SJohn Marino 	 and don't change the imaginary part.  */
5190e4b17023SJohn Marino       if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
5191e4b17023SJohn Marino 	{
5192e4b17023SJohn Marino 	  tree real, imag;
5193e4b17023SJohn Marino 
5194e4b17023SJohn Marino 	  arg = stabilize_reference (arg);
5195e4b17023SJohn Marino 	  real = cp_build_unary_op (REALPART_EXPR, arg, 1, complain);
5196e4b17023SJohn Marino 	  imag = cp_build_unary_op (IMAGPART_EXPR, arg, 1, complain);
5197e4b17023SJohn Marino 	  real = cp_build_unary_op (code, real, 1, complain);
5198e4b17023SJohn Marino 	  if (real == error_mark_node || imag == error_mark_node)
5199e4b17023SJohn Marino 	    return error_mark_node;
5200e4b17023SJohn Marino 	  return build2 (COMPLEX_EXPR, TREE_TYPE (arg),
5201e4b17023SJohn Marino 			 real, imag);
5202e4b17023SJohn Marino 	}
5203e4b17023SJohn Marino 
5204e4b17023SJohn Marino       /* Report invalid types.  */
5205e4b17023SJohn Marino 
5206e4b17023SJohn Marino       if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_POINTER,
5207e4b17023SJohn Marino 					      arg, true)))
5208e4b17023SJohn Marino 	{
5209e4b17023SJohn Marino 	  if (code == PREINCREMENT_EXPR)
5210e4b17023SJohn Marino 	    errstring = _("no pre-increment operator for type");
5211e4b17023SJohn Marino 	  else if (code == POSTINCREMENT_EXPR)
5212e4b17023SJohn Marino 	    errstring = _("no post-increment operator for type");
5213e4b17023SJohn Marino 	  else if (code == PREDECREMENT_EXPR)
5214e4b17023SJohn Marino 	    errstring = _("no pre-decrement operator for type");
5215e4b17023SJohn Marino 	  else
5216e4b17023SJohn Marino 	    errstring = _("no post-decrement operator for type");
5217e4b17023SJohn Marino 	  break;
5218e4b17023SJohn Marino 	}
5219e4b17023SJohn Marino       else if (arg == error_mark_node)
5220e4b17023SJohn Marino 	return error_mark_node;
5221e4b17023SJohn Marino 
5222e4b17023SJohn Marino       /* Report something read-only.  */
5223e4b17023SJohn Marino 
5224e4b17023SJohn Marino       if (CP_TYPE_CONST_P (TREE_TYPE (arg))
5225e4b17023SJohn Marino 	  || TREE_READONLY (arg))
5226e4b17023SJohn Marino         {
5227e4b17023SJohn Marino           if (complain & tf_error)
5228e4b17023SJohn Marino             cxx_readonly_error (arg, ((code == PREINCREMENT_EXPR
5229e4b17023SJohn Marino 				      || code == POSTINCREMENT_EXPR)
5230e4b17023SJohn Marino 				     ? lv_increment : lv_decrement));
5231e4b17023SJohn Marino           else
5232e4b17023SJohn Marino             return error_mark_node;
5233e4b17023SJohn Marino         }
5234e4b17023SJohn Marino 
5235e4b17023SJohn Marino       {
5236e4b17023SJohn Marino 	tree inc;
5237e4b17023SJohn Marino 	tree declared_type = unlowered_expr_type (arg);
5238e4b17023SJohn Marino 
5239e4b17023SJohn Marino 	argtype = TREE_TYPE (arg);
5240e4b17023SJohn Marino 
5241e4b17023SJohn Marino 	/* ARM $5.2.5 last annotation says this should be forbidden.  */
5242e4b17023SJohn Marino 	if (TREE_CODE (argtype) == ENUMERAL_TYPE)
5243e4b17023SJohn Marino           {
5244e4b17023SJohn Marino             if (complain & tf_error)
5245e4b17023SJohn Marino               permerror (input_location, (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
5246e4b17023SJohn Marino                          ? G_("ISO C++ forbids incrementing an enum")
5247e4b17023SJohn Marino                          : G_("ISO C++ forbids decrementing an enum"));
5248e4b17023SJohn Marino             else
5249e4b17023SJohn Marino               return error_mark_node;
5250e4b17023SJohn Marino           }
5251e4b17023SJohn Marino 
5252e4b17023SJohn Marino 	/* Compute the increment.  */
5253e4b17023SJohn Marino 
5254e4b17023SJohn Marino 	if (TREE_CODE (argtype) == POINTER_TYPE)
5255e4b17023SJohn Marino 	  {
5256e4b17023SJohn Marino 	    tree type = complete_type (TREE_TYPE (argtype));
5257e4b17023SJohn Marino 
5258e4b17023SJohn Marino 	    if (!COMPLETE_OR_VOID_TYPE_P (type))
5259e4b17023SJohn Marino               {
5260e4b17023SJohn Marino                 if (complain & tf_error)
5261e4b17023SJohn Marino                   error (((code == PREINCREMENT_EXPR
5262e4b17023SJohn Marino                            || code == POSTINCREMENT_EXPR))
5263e4b17023SJohn Marino                          ? G_("cannot increment a pointer to incomplete type %qT")
5264e4b17023SJohn Marino                          : G_("cannot decrement a pointer to incomplete type %qT"),
5265e4b17023SJohn Marino                          TREE_TYPE (argtype));
5266e4b17023SJohn Marino                 else
5267e4b17023SJohn Marino                   return error_mark_node;
5268e4b17023SJohn Marino               }
5269e4b17023SJohn Marino 	    else if ((pedantic || warn_pointer_arith)
5270e4b17023SJohn Marino 		     && !TYPE_PTROB_P (argtype))
5271e4b17023SJohn Marino               {
5272e4b17023SJohn Marino                 if (complain & tf_error)
5273e4b17023SJohn Marino                   permerror (input_location, (code == PREINCREMENT_EXPR
5274e4b17023SJohn Marino                               || code == POSTINCREMENT_EXPR)
5275e4b17023SJohn Marino                              ? G_("ISO C++ forbids incrementing a pointer of type %qT")
5276e4b17023SJohn Marino                              : G_("ISO C++ forbids decrementing a pointer of type %qT"),
5277e4b17023SJohn Marino                              argtype);
5278e4b17023SJohn Marino                 else
5279e4b17023SJohn Marino                   return error_mark_node;
5280e4b17023SJohn Marino               }
5281e4b17023SJohn Marino 
5282e4b17023SJohn Marino 	    inc = cxx_sizeof_nowarn (TREE_TYPE (argtype));
5283e4b17023SJohn Marino 	  }
5284e4b17023SJohn Marino 	else
5285e4b17023SJohn Marino 	  inc = integer_one_node;
5286e4b17023SJohn Marino 
5287e4b17023SJohn Marino 	inc = cp_convert (argtype, inc);
5288e4b17023SJohn Marino 
5289e4b17023SJohn Marino 	/* If 'arg' is an Objective-C PROPERTY_REF expression, then we
5290e4b17023SJohn Marino 	   need to ask Objective-C to build the increment or decrement
5291e4b17023SJohn Marino 	   expression for it.  */
5292e4b17023SJohn Marino 	if (objc_is_property_ref (arg))
5293e4b17023SJohn Marino 	  return objc_build_incr_expr_for_property_ref (input_location, code,
5294e4b17023SJohn Marino 							arg, inc);
5295e4b17023SJohn Marino 
5296e4b17023SJohn Marino 	/* Complain about anything else that is not a true lvalue.  */
5297e4b17023SJohn Marino 	if (!lvalue_or_else (arg, ((code == PREINCREMENT_EXPR
5298e4b17023SJohn Marino 				    || code == POSTINCREMENT_EXPR)
5299e4b17023SJohn Marino 				   ? lv_increment : lv_decrement),
5300e4b17023SJohn Marino                              complain))
5301e4b17023SJohn Marino 	  return error_mark_node;
5302e4b17023SJohn Marino 
5303e4b17023SJohn Marino 	/* Forbid using -- on `bool'.  */
5304e4b17023SJohn Marino 	if (TREE_CODE (declared_type) == BOOLEAN_TYPE)
5305e4b17023SJohn Marino 	  {
5306e4b17023SJohn Marino 	    if (code == POSTDECREMENT_EXPR || code == PREDECREMENT_EXPR)
5307e4b17023SJohn Marino 	      {
5308e4b17023SJohn Marino                 if (complain & tf_error)
5309e4b17023SJohn Marino                   error ("invalid use of Boolean expression as operand "
5310e4b17023SJohn Marino                          "to %<operator--%>");
5311e4b17023SJohn Marino 		return error_mark_node;
5312e4b17023SJohn Marino 	      }
5313e4b17023SJohn Marino 	    val = boolean_increment (code, arg);
5314e4b17023SJohn Marino 	  }
5315e4b17023SJohn Marino 	else if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
5316e4b17023SJohn Marino 	  /* An rvalue has no cv-qualifiers.  */
5317e4b17023SJohn Marino 	  val = build2 (code, cv_unqualified (TREE_TYPE (arg)), arg, inc);
5318e4b17023SJohn Marino 	else
5319e4b17023SJohn Marino 	  val = build2 (code, TREE_TYPE (arg), arg, inc);
5320e4b17023SJohn Marino 
5321e4b17023SJohn Marino 	TREE_SIDE_EFFECTS (val) = 1;
5322e4b17023SJohn Marino 	return val;
5323e4b17023SJohn Marino       }
5324e4b17023SJohn Marino 
5325e4b17023SJohn Marino     case ADDR_EXPR:
5326e4b17023SJohn Marino       /* Note that this operation never does default_conversion
5327e4b17023SJohn Marino 	 regardless of NOCONVERT.  */
5328e4b17023SJohn Marino       return cp_build_addr_expr (arg, complain);
5329e4b17023SJohn Marino 
5330e4b17023SJohn Marino     default:
5331e4b17023SJohn Marino       break;
5332e4b17023SJohn Marino     }
5333e4b17023SJohn Marino 
5334e4b17023SJohn Marino   if (!errstring)
5335e4b17023SJohn Marino     {
5336e4b17023SJohn Marino       if (argtype == 0)
5337e4b17023SJohn Marino 	argtype = TREE_TYPE (arg);
5338e4b17023SJohn Marino       return fold_if_not_in_template (build1 (code, argtype, arg));
5339e4b17023SJohn Marino     }
5340e4b17023SJohn Marino 
5341e4b17023SJohn Marino   if (complain & tf_error)
5342e4b17023SJohn Marino     error ("%s", errstring);
5343e4b17023SJohn Marino   return error_mark_node;
5344e4b17023SJohn Marino }
5345e4b17023SJohn Marino 
5346e4b17023SJohn Marino /* Hook for the c-common bits that build a unary op.  */
5347e4b17023SJohn Marino tree
build_unary_op(location_t location ATTRIBUTE_UNUSED,enum tree_code code,tree xarg,int noconvert)5348e4b17023SJohn Marino build_unary_op (location_t location ATTRIBUTE_UNUSED,
5349e4b17023SJohn Marino 		enum tree_code code, tree xarg, int noconvert)
5350e4b17023SJohn Marino {
5351e4b17023SJohn Marino   return cp_build_unary_op (code, xarg, noconvert, tf_warning_or_error);
5352e4b17023SJohn Marino }
5353e4b17023SJohn Marino 
5354e4b17023SJohn Marino /* Apply unary lvalue-demanding operator CODE to the expression ARG
5355e4b17023SJohn Marino    for certain kinds of expressions which are not really lvalues
5356e4b17023SJohn Marino    but which we can accept as lvalues.
5357e4b17023SJohn Marino 
5358e4b17023SJohn Marino    If ARG is not a kind of expression we can handle, return
5359e4b17023SJohn Marino    NULL_TREE.  */
5360e4b17023SJohn Marino 
5361e4b17023SJohn Marino tree
unary_complex_lvalue(enum tree_code code,tree arg)5362e4b17023SJohn Marino unary_complex_lvalue (enum tree_code code, tree arg)
5363e4b17023SJohn Marino {
5364e4b17023SJohn Marino   /* Inside a template, making these kinds of adjustments is
5365e4b17023SJohn Marino      pointless; we are only concerned with the type of the
5366e4b17023SJohn Marino      expression.  */
5367e4b17023SJohn Marino   if (processing_template_decl)
5368e4b17023SJohn Marino     return NULL_TREE;
5369e4b17023SJohn Marino 
5370e4b17023SJohn Marino   /* Handle (a, b) used as an "lvalue".  */
5371e4b17023SJohn Marino   if (TREE_CODE (arg) == COMPOUND_EXPR)
5372e4b17023SJohn Marino     {
5373e4b17023SJohn Marino       tree real_result = cp_build_unary_op (code, TREE_OPERAND (arg, 1), 0,
5374e4b17023SJohn Marino                                             tf_warning_or_error);
5375e4b17023SJohn Marino       return build2 (COMPOUND_EXPR, TREE_TYPE (real_result),
5376e4b17023SJohn Marino 		     TREE_OPERAND (arg, 0), real_result);
5377e4b17023SJohn Marino     }
5378e4b17023SJohn Marino 
5379e4b17023SJohn Marino   /* Handle (a ? b : c) used as an "lvalue".  */
5380e4b17023SJohn Marino   if (TREE_CODE (arg) == COND_EXPR
5381e4b17023SJohn Marino       || TREE_CODE (arg) == MIN_EXPR || TREE_CODE (arg) == MAX_EXPR)
5382e4b17023SJohn Marino     return rationalize_conditional_expr (code, arg, tf_warning_or_error);
5383e4b17023SJohn Marino 
5384e4b17023SJohn Marino   /* Handle (a = b), (++a), and (--a) used as an "lvalue".  */
5385e4b17023SJohn Marino   if (TREE_CODE (arg) == MODIFY_EXPR
5386e4b17023SJohn Marino       || TREE_CODE (arg) == PREINCREMENT_EXPR
5387e4b17023SJohn Marino       || TREE_CODE (arg) == PREDECREMENT_EXPR)
5388e4b17023SJohn Marino     {
5389e4b17023SJohn Marino       tree lvalue = TREE_OPERAND (arg, 0);
5390e4b17023SJohn Marino       if (TREE_SIDE_EFFECTS (lvalue))
5391e4b17023SJohn Marino 	{
5392e4b17023SJohn Marino 	  lvalue = stabilize_reference (lvalue);
5393e4b17023SJohn Marino 	  arg = build2 (TREE_CODE (arg), TREE_TYPE (arg),
5394e4b17023SJohn Marino 			lvalue, TREE_OPERAND (arg, 1));
5395e4b17023SJohn Marino 	}
5396e4b17023SJohn Marino       return unary_complex_lvalue
5397e4b17023SJohn Marino 	(code, build2 (COMPOUND_EXPR, TREE_TYPE (lvalue), arg, lvalue));
5398e4b17023SJohn Marino     }
5399e4b17023SJohn Marino 
5400e4b17023SJohn Marino   if (code != ADDR_EXPR)
5401e4b17023SJohn Marino     return NULL_TREE;
5402e4b17023SJohn Marino 
5403e4b17023SJohn Marino   /* Handle (a = b) used as an "lvalue" for `&'.  */
5404e4b17023SJohn Marino   if (TREE_CODE (arg) == MODIFY_EXPR
5405e4b17023SJohn Marino       || TREE_CODE (arg) == INIT_EXPR)
5406e4b17023SJohn Marino     {
5407e4b17023SJohn Marino       tree real_result = cp_build_unary_op (code, TREE_OPERAND (arg, 0), 0,
5408e4b17023SJohn Marino                                             tf_warning_or_error);
5409e4b17023SJohn Marino       arg = build2 (COMPOUND_EXPR, TREE_TYPE (real_result),
5410e4b17023SJohn Marino 		    arg, real_result);
5411e4b17023SJohn Marino       TREE_NO_WARNING (arg) = 1;
5412e4b17023SJohn Marino       return arg;
5413e4b17023SJohn Marino     }
5414e4b17023SJohn Marino 
5415e4b17023SJohn Marino   if (TREE_CODE (TREE_TYPE (arg)) == FUNCTION_TYPE
5416e4b17023SJohn Marino       || TREE_CODE (TREE_TYPE (arg)) == METHOD_TYPE
5417e4b17023SJohn Marino       || TREE_CODE (arg) == OFFSET_REF)
5418e4b17023SJohn Marino     return NULL_TREE;
5419e4b17023SJohn Marino 
5420e4b17023SJohn Marino   /* We permit compiler to make function calls returning
5421e4b17023SJohn Marino      objects of aggregate type look like lvalues.  */
5422e4b17023SJohn Marino   {
5423e4b17023SJohn Marino     tree targ = arg;
5424e4b17023SJohn Marino 
5425e4b17023SJohn Marino     if (TREE_CODE (targ) == SAVE_EXPR)
5426e4b17023SJohn Marino       targ = TREE_OPERAND (targ, 0);
5427e4b17023SJohn Marino 
5428e4b17023SJohn Marino     if (TREE_CODE (targ) == CALL_EXPR && MAYBE_CLASS_TYPE_P (TREE_TYPE (targ)))
5429e4b17023SJohn Marino       {
5430e4b17023SJohn Marino 	if (TREE_CODE (arg) == SAVE_EXPR)
5431e4b17023SJohn Marino 	  targ = arg;
5432e4b17023SJohn Marino 	else
5433e4b17023SJohn Marino 	  targ = build_cplus_new (TREE_TYPE (arg), arg, tf_warning_or_error);
5434e4b17023SJohn Marino 	return build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg)), targ);
5435e4b17023SJohn Marino       }
5436e4b17023SJohn Marino 
5437e4b17023SJohn Marino     if (TREE_CODE (arg) == SAVE_EXPR && TREE_CODE (targ) == INDIRECT_REF)
5438e4b17023SJohn Marino       return build3 (SAVE_EXPR, build_pointer_type (TREE_TYPE (arg)),
5439e4b17023SJohn Marino 		     TREE_OPERAND (targ, 0), current_function_decl, NULL);
5440e4b17023SJohn Marino   }
5441e4b17023SJohn Marino 
5442e4b17023SJohn Marino   /* Don't let anything else be handled specially.  */
5443e4b17023SJohn Marino   return NULL_TREE;
5444e4b17023SJohn Marino }
5445e4b17023SJohn Marino 
5446e4b17023SJohn Marino /* Mark EXP saying that we need to be able to take the
5447e4b17023SJohn Marino    address of it; it should not be allocated in a register.
5448e4b17023SJohn Marino    Value is true if successful.
5449e4b17023SJohn Marino 
5450e4b17023SJohn Marino    C++: we do not allow `current_class_ptr' to be addressable.  */
5451e4b17023SJohn Marino 
5452e4b17023SJohn Marino bool
cxx_mark_addressable(tree exp)5453e4b17023SJohn Marino cxx_mark_addressable (tree exp)
5454e4b17023SJohn Marino {
5455e4b17023SJohn Marino   tree x = exp;
5456e4b17023SJohn Marino 
5457e4b17023SJohn Marino   while (1)
5458e4b17023SJohn Marino     switch (TREE_CODE (x))
5459e4b17023SJohn Marino       {
5460e4b17023SJohn Marino       case ADDR_EXPR:
5461e4b17023SJohn Marino       case COMPONENT_REF:
5462e4b17023SJohn Marino       case ARRAY_REF:
5463e4b17023SJohn Marino       case REALPART_EXPR:
5464e4b17023SJohn Marino       case IMAGPART_EXPR:
5465e4b17023SJohn Marino 	x = TREE_OPERAND (x, 0);
5466e4b17023SJohn Marino 	break;
5467e4b17023SJohn Marino 
5468e4b17023SJohn Marino       case PARM_DECL:
5469e4b17023SJohn Marino 	if (x == current_class_ptr)
5470e4b17023SJohn Marino 	  {
5471e4b17023SJohn Marino 	    error ("cannot take the address of %<this%>, which is an rvalue expression");
5472e4b17023SJohn Marino 	    TREE_ADDRESSABLE (x) = 1; /* so compiler doesn't die later.  */
5473e4b17023SJohn Marino 	    return true;
5474e4b17023SJohn Marino 	  }
5475e4b17023SJohn Marino 	/* Fall through.  */
5476e4b17023SJohn Marino 
5477e4b17023SJohn Marino       case VAR_DECL:
5478e4b17023SJohn Marino 	/* Caller should not be trying to mark initialized
5479e4b17023SJohn Marino 	   constant fields addressable.  */
5480e4b17023SJohn Marino 	gcc_assert (DECL_LANG_SPECIFIC (x) == 0
5481e4b17023SJohn Marino 		    || DECL_IN_AGGR_P (x) == 0
5482e4b17023SJohn Marino 		    || TREE_STATIC (x)
5483e4b17023SJohn Marino 		    || DECL_EXTERNAL (x));
5484e4b17023SJohn Marino 	/* Fall through.  */
5485e4b17023SJohn Marino 
5486e4b17023SJohn Marino       case RESULT_DECL:
5487e4b17023SJohn Marino 	if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)
5488e4b17023SJohn Marino 	    && !DECL_ARTIFICIAL (x))
5489e4b17023SJohn Marino 	  {
5490e4b17023SJohn Marino 	    if (TREE_CODE (x) == VAR_DECL && DECL_HARD_REGISTER (x))
5491e4b17023SJohn Marino 	      {
5492e4b17023SJohn Marino 		error
5493e4b17023SJohn Marino 		  ("address of explicit register variable %qD requested", x);
5494e4b17023SJohn Marino 		return false;
5495e4b17023SJohn Marino 	      }
5496e4b17023SJohn Marino 	    else if (extra_warnings)
5497e4b17023SJohn Marino 	      warning
5498e4b17023SJohn Marino 		(OPT_Wextra, "address requested for %qD, which is declared %<register%>", x);
5499e4b17023SJohn Marino 	  }
5500e4b17023SJohn Marino 	TREE_ADDRESSABLE (x) = 1;
5501e4b17023SJohn Marino 	return true;
5502e4b17023SJohn Marino 
5503e4b17023SJohn Marino       case CONST_DECL:
5504e4b17023SJohn Marino       case FUNCTION_DECL:
5505e4b17023SJohn Marino 	TREE_ADDRESSABLE (x) = 1;
5506e4b17023SJohn Marino 	return true;
5507e4b17023SJohn Marino 
5508e4b17023SJohn Marino       case CONSTRUCTOR:
5509e4b17023SJohn Marino 	TREE_ADDRESSABLE (x) = 1;
5510e4b17023SJohn Marino 	return true;
5511e4b17023SJohn Marino 
5512e4b17023SJohn Marino       case TARGET_EXPR:
5513e4b17023SJohn Marino 	TREE_ADDRESSABLE (x) = 1;
5514e4b17023SJohn Marino 	cxx_mark_addressable (TREE_OPERAND (x, 0));
5515e4b17023SJohn Marino 	return true;
5516e4b17023SJohn Marino 
5517e4b17023SJohn Marino       default:
5518e4b17023SJohn Marino 	return true;
5519e4b17023SJohn Marino     }
5520e4b17023SJohn Marino }
5521e4b17023SJohn Marino 
5522e4b17023SJohn Marino /* Build and return a conditional expression IFEXP ? OP1 : OP2.  */
5523e4b17023SJohn Marino 
5524e4b17023SJohn Marino tree
build_x_conditional_expr(tree ifexp,tree op1,tree op2,tsubst_flags_t complain)5525e4b17023SJohn Marino build_x_conditional_expr (tree ifexp, tree op1, tree op2,
5526e4b17023SJohn Marino                           tsubst_flags_t complain)
5527e4b17023SJohn Marino {
5528e4b17023SJohn Marino   tree orig_ifexp = ifexp;
5529e4b17023SJohn Marino   tree orig_op1 = op1;
5530e4b17023SJohn Marino   tree orig_op2 = op2;
5531e4b17023SJohn Marino   tree expr;
5532e4b17023SJohn Marino 
5533e4b17023SJohn Marino   if (processing_template_decl)
5534e4b17023SJohn Marino     {
5535e4b17023SJohn Marino       /* The standard says that the expression is type-dependent if
5536e4b17023SJohn Marino 	 IFEXP is type-dependent, even though the eventual type of the
5537e4b17023SJohn Marino 	 expression doesn't dependent on IFEXP.  */
5538e4b17023SJohn Marino       if (type_dependent_expression_p (ifexp)
5539e4b17023SJohn Marino 	  /* As a GNU extension, the middle operand may be omitted.  */
5540e4b17023SJohn Marino 	  || (op1 && type_dependent_expression_p (op1))
5541e4b17023SJohn Marino 	  || type_dependent_expression_p (op2))
5542e4b17023SJohn Marino 	return build_min_nt (COND_EXPR, ifexp, op1, op2);
5543e4b17023SJohn Marino       ifexp = build_non_dependent_expr (ifexp);
5544e4b17023SJohn Marino       if (op1)
5545e4b17023SJohn Marino 	op1 = build_non_dependent_expr (op1);
5546e4b17023SJohn Marino       op2 = build_non_dependent_expr (op2);
5547e4b17023SJohn Marino     }
5548e4b17023SJohn Marino 
5549e4b17023SJohn Marino   expr = build_conditional_expr (ifexp, op1, op2, complain);
5550e4b17023SJohn Marino   if (processing_template_decl && expr != error_mark_node)
5551e4b17023SJohn Marino     {
5552e4b17023SJohn Marino       tree min = build_min_non_dep (COND_EXPR, expr,
5553e4b17023SJohn Marino 				    orig_ifexp, orig_op1, orig_op2);
5554e4b17023SJohn Marino       /* In C++11, remember that the result is an lvalue or xvalue.
5555e4b17023SJohn Marino          In C++98, lvalue_kind can just assume lvalue in a template.  */
5556e4b17023SJohn Marino       if (cxx_dialect >= cxx0x
5557e4b17023SJohn Marino 	  && lvalue_or_rvalue_with_address_p (expr)
5558e4b17023SJohn Marino 	  && !lvalue_or_rvalue_with_address_p (min))
5559e4b17023SJohn Marino 	TREE_TYPE (min) = cp_build_reference_type (TREE_TYPE (min),
5560e4b17023SJohn Marino 						   !real_lvalue_p (expr));
5561e4b17023SJohn Marino       expr = convert_from_reference (min);
5562e4b17023SJohn Marino     }
5563e4b17023SJohn Marino   return expr;
5564e4b17023SJohn Marino }
5565e4b17023SJohn Marino 
5566e4b17023SJohn Marino /* Given a list of expressions, return a compound expression
5567e4b17023SJohn Marino    that performs them all and returns the value of the last of them.  */
5568e4b17023SJohn Marino 
5569e4b17023SJohn Marino tree
build_x_compound_expr_from_list(tree list,expr_list_kind exp,tsubst_flags_t complain)5570e4b17023SJohn Marino build_x_compound_expr_from_list (tree list, expr_list_kind exp,
5571e4b17023SJohn Marino 				 tsubst_flags_t complain)
5572e4b17023SJohn Marino {
5573e4b17023SJohn Marino   tree expr = TREE_VALUE (list);
5574e4b17023SJohn Marino 
5575e4b17023SJohn Marino   if (BRACE_ENCLOSED_INITIALIZER_P (expr)
5576e4b17023SJohn Marino       && !CONSTRUCTOR_IS_DIRECT_INIT (expr))
5577e4b17023SJohn Marino     {
5578e4b17023SJohn Marino       if (complain & tf_error)
5579e4b17023SJohn Marino 	pedwarn (EXPR_LOC_OR_HERE (expr), 0, "list-initializer for "
5580e4b17023SJohn Marino 		 "non-class type must not be parenthesized");
5581e4b17023SJohn Marino       else
5582e4b17023SJohn Marino 	return error_mark_node;
5583e4b17023SJohn Marino     }
5584e4b17023SJohn Marino 
5585e4b17023SJohn Marino   if (TREE_CHAIN (list))
5586e4b17023SJohn Marino     {
5587e4b17023SJohn Marino       if (complain & tf_error)
5588e4b17023SJohn Marino 	switch (exp)
5589e4b17023SJohn Marino 	  {
5590e4b17023SJohn Marino 	  case ELK_INIT:
5591e4b17023SJohn Marino 	    permerror (input_location, "expression list treated as compound "
5592e4b17023SJohn Marino 				       "expression in initializer");
5593e4b17023SJohn Marino 	    break;
5594e4b17023SJohn Marino 	  case ELK_MEM_INIT:
5595e4b17023SJohn Marino 	    permerror (input_location, "expression list treated as compound "
5596e4b17023SJohn Marino 				       "expression in mem-initializer");
5597e4b17023SJohn Marino 	    break;
5598e4b17023SJohn Marino 	  case ELK_FUNC_CAST:
5599e4b17023SJohn Marino 	    permerror (input_location, "expression list treated as compound "
5600e4b17023SJohn Marino 				       "expression in functional cast");
5601e4b17023SJohn Marino 	    break;
5602e4b17023SJohn Marino 	  default:
5603e4b17023SJohn Marino 	    gcc_unreachable ();
5604e4b17023SJohn Marino 	  }
5605e4b17023SJohn Marino       else
5606e4b17023SJohn Marino 	return error_mark_node;
5607e4b17023SJohn Marino 
5608e4b17023SJohn Marino       for (list = TREE_CHAIN (list); list; list = TREE_CHAIN (list))
5609e4b17023SJohn Marino 	expr = build_x_compound_expr (expr, TREE_VALUE (list),
5610e4b17023SJohn Marino                                       complain);
5611e4b17023SJohn Marino     }
5612e4b17023SJohn Marino 
5613e4b17023SJohn Marino   return expr;
5614e4b17023SJohn Marino }
5615e4b17023SJohn Marino 
5616e4b17023SJohn Marino /* Like build_x_compound_expr_from_list, but using a VEC.  */
5617e4b17023SJohn Marino 
5618e4b17023SJohn Marino tree
build_x_compound_expr_from_vec(VEC (tree,gc)* vec,const char * msg)5619e4b17023SJohn Marino build_x_compound_expr_from_vec (VEC(tree,gc) *vec, const char *msg)
5620e4b17023SJohn Marino {
5621e4b17023SJohn Marino   if (VEC_empty (tree, vec))
5622e4b17023SJohn Marino     return NULL_TREE;
5623e4b17023SJohn Marino   else if (VEC_length (tree, vec) == 1)
5624e4b17023SJohn Marino     return VEC_index (tree, vec, 0);
5625e4b17023SJohn Marino   else
5626e4b17023SJohn Marino     {
5627e4b17023SJohn Marino       tree expr;
5628e4b17023SJohn Marino       unsigned int ix;
5629e4b17023SJohn Marino       tree t;
5630e4b17023SJohn Marino 
5631e4b17023SJohn Marino       if (msg != NULL)
5632e4b17023SJohn Marino 	permerror (input_location,
5633e4b17023SJohn Marino 		   "%s expression list treated as compound expression",
5634e4b17023SJohn Marino 		   msg);
5635e4b17023SJohn Marino 
5636e4b17023SJohn Marino       expr = VEC_index (tree, vec, 0);
5637e4b17023SJohn Marino       for (ix = 1; VEC_iterate (tree, vec, ix, t); ++ix)
5638e4b17023SJohn Marino 	expr = build_x_compound_expr (expr, t, tf_warning_or_error);
5639e4b17023SJohn Marino 
5640e4b17023SJohn Marino       return expr;
5641e4b17023SJohn Marino     }
5642e4b17023SJohn Marino }
5643e4b17023SJohn Marino 
5644e4b17023SJohn Marino /* Handle overloading of the ',' operator when needed.  */
5645e4b17023SJohn Marino 
5646e4b17023SJohn Marino tree
build_x_compound_expr(tree op1,tree op2,tsubst_flags_t complain)5647e4b17023SJohn Marino build_x_compound_expr (tree op1, tree op2, tsubst_flags_t complain)
5648e4b17023SJohn Marino {
5649e4b17023SJohn Marino   tree result;
5650e4b17023SJohn Marino   tree orig_op1 = op1;
5651e4b17023SJohn Marino   tree orig_op2 = op2;
5652e4b17023SJohn Marino 
5653e4b17023SJohn Marino   if (processing_template_decl)
5654e4b17023SJohn Marino     {
5655e4b17023SJohn Marino       if (type_dependent_expression_p (op1)
5656e4b17023SJohn Marino 	  || type_dependent_expression_p (op2))
5657e4b17023SJohn Marino 	return build_min_nt (COMPOUND_EXPR, op1, op2);
5658e4b17023SJohn Marino       op1 = build_non_dependent_expr (op1);
5659e4b17023SJohn Marino       op2 = build_non_dependent_expr (op2);
5660e4b17023SJohn Marino     }
5661e4b17023SJohn Marino 
5662e4b17023SJohn Marino   result = build_new_op (COMPOUND_EXPR, LOOKUP_NORMAL, op1, op2, NULL_TREE,
5663e4b17023SJohn Marino 			 /*overload=*/NULL, complain);
5664e4b17023SJohn Marino   if (!result)
5665e4b17023SJohn Marino     result = cp_build_compound_expr (op1, op2, complain);
5666e4b17023SJohn Marino 
5667e4b17023SJohn Marino   if (processing_template_decl && result != error_mark_node)
5668e4b17023SJohn Marino     return build_min_non_dep (COMPOUND_EXPR, result, orig_op1, orig_op2);
5669e4b17023SJohn Marino 
5670e4b17023SJohn Marino   return result;
5671e4b17023SJohn Marino }
5672e4b17023SJohn Marino 
5673e4b17023SJohn Marino /* Like cp_build_compound_expr, but for the c-common bits.  */
5674e4b17023SJohn Marino 
5675e4b17023SJohn Marino tree
build_compound_expr(location_t loc ATTRIBUTE_UNUSED,tree lhs,tree rhs)5676e4b17023SJohn Marino build_compound_expr (location_t loc ATTRIBUTE_UNUSED, tree lhs, tree rhs)
5677e4b17023SJohn Marino {
5678e4b17023SJohn Marino   return cp_build_compound_expr (lhs, rhs, tf_warning_or_error);
5679e4b17023SJohn Marino }
5680e4b17023SJohn Marino 
5681e4b17023SJohn Marino /* Build a compound expression.  */
5682e4b17023SJohn Marino 
5683e4b17023SJohn Marino tree
cp_build_compound_expr(tree lhs,tree rhs,tsubst_flags_t complain)5684e4b17023SJohn Marino cp_build_compound_expr (tree lhs, tree rhs, tsubst_flags_t complain)
5685e4b17023SJohn Marino {
5686e4b17023SJohn Marino   lhs = convert_to_void (lhs, ICV_LEFT_OF_COMMA, complain);
5687e4b17023SJohn Marino 
5688e4b17023SJohn Marino   if (lhs == error_mark_node || rhs == error_mark_node)
5689e4b17023SJohn Marino     return error_mark_node;
5690e4b17023SJohn Marino 
5691e4b17023SJohn Marino   if (TREE_CODE (rhs) == TARGET_EXPR)
5692e4b17023SJohn Marino     {
5693e4b17023SJohn Marino       /* If the rhs is a TARGET_EXPR, then build the compound
5694e4b17023SJohn Marino 	 expression inside the target_expr's initializer. This
5695e4b17023SJohn Marino 	 helps the compiler to eliminate unnecessary temporaries.  */
5696e4b17023SJohn Marino       tree init = TREE_OPERAND (rhs, 1);
5697e4b17023SJohn Marino 
5698e4b17023SJohn Marino       init = build2 (COMPOUND_EXPR, TREE_TYPE (init), lhs, init);
5699e4b17023SJohn Marino       TREE_OPERAND (rhs, 1) = init;
5700e4b17023SJohn Marino 
5701e4b17023SJohn Marino       return rhs;
5702e4b17023SJohn Marino     }
5703e4b17023SJohn Marino 
5704e4b17023SJohn Marino   if (type_unknown_p (rhs))
5705e4b17023SJohn Marino     {
5706e4b17023SJohn Marino       error ("no context to resolve type of %qE", rhs);
5707e4b17023SJohn Marino       return error_mark_node;
5708e4b17023SJohn Marino     }
5709e4b17023SJohn Marino 
5710e4b17023SJohn Marino   return build2 (COMPOUND_EXPR, TREE_TYPE (rhs), lhs, rhs);
5711e4b17023SJohn Marino }
5712e4b17023SJohn Marino 
5713e4b17023SJohn Marino /* Issue a diagnostic message if casting from SRC_TYPE to DEST_TYPE
5714e4b17023SJohn Marino    casts away constness.  CAST gives the type of cast.  Returns true
5715e4b17023SJohn Marino    if the cast is ill-formed, false if it is well-formed.
5716e4b17023SJohn Marino 
5717e4b17023SJohn Marino    ??? This function warns for casting away any qualifier not just
5718e4b17023SJohn Marino    const.  We would like to specify exactly what qualifiers are casted
5719e4b17023SJohn Marino    away.
5720e4b17023SJohn Marino */
5721e4b17023SJohn Marino 
5722e4b17023SJohn Marino static bool
check_for_casting_away_constness(tree src_type,tree dest_type,enum tree_code cast,tsubst_flags_t complain)5723e4b17023SJohn Marino check_for_casting_away_constness (tree src_type, tree dest_type,
5724e4b17023SJohn Marino 				  enum tree_code cast, tsubst_flags_t complain)
5725e4b17023SJohn Marino {
5726e4b17023SJohn Marino   /* C-style casts are allowed to cast away constness.  With
5727e4b17023SJohn Marino      WARN_CAST_QUAL, we still want to issue a warning.  */
5728e4b17023SJohn Marino   if (cast == CAST_EXPR && !warn_cast_qual)
5729e4b17023SJohn Marino     return false;
5730e4b17023SJohn Marino 
5731e4b17023SJohn Marino   if (!casts_away_constness (src_type, dest_type))
5732e4b17023SJohn Marino     return false;
5733e4b17023SJohn Marino 
5734e4b17023SJohn Marino   switch (cast)
5735e4b17023SJohn Marino     {
5736e4b17023SJohn Marino     case CAST_EXPR:
5737e4b17023SJohn Marino       if (complain & tf_warning)
5738e4b17023SJohn Marino 	warning (OPT_Wcast_qual,
5739e4b17023SJohn Marino 		 "cast from type %qT to type %qT casts away qualifiers",
5740e4b17023SJohn Marino 		 src_type, dest_type);
5741e4b17023SJohn Marino       return false;
5742e4b17023SJohn Marino 
5743e4b17023SJohn Marino     case STATIC_CAST_EXPR:
5744e4b17023SJohn Marino       if (complain & tf_error)
5745e4b17023SJohn Marino 	error ("static_cast from type %qT to type %qT casts away qualifiers",
5746e4b17023SJohn Marino 	       src_type, dest_type);
5747e4b17023SJohn Marino       return true;
5748e4b17023SJohn Marino 
5749e4b17023SJohn Marino     case REINTERPRET_CAST_EXPR:
5750e4b17023SJohn Marino       if (complain & tf_error)
5751e4b17023SJohn Marino 	error ("reinterpret_cast from type %qT to type %qT casts away qualifiers",
5752e4b17023SJohn Marino 	       src_type, dest_type);
5753e4b17023SJohn Marino       return true;
5754e4b17023SJohn Marino 
5755e4b17023SJohn Marino     default:
5756e4b17023SJohn Marino       gcc_unreachable();
5757e4b17023SJohn Marino     }
5758e4b17023SJohn Marino }
5759e4b17023SJohn Marino 
5760e4b17023SJohn Marino /* Convert EXPR (an expression with pointer-to-member type) to TYPE
5761e4b17023SJohn Marino    (another pointer-to-member type in the same hierarchy) and return
5762e4b17023SJohn Marino    the converted expression.  If ALLOW_INVERSE_P is permitted, a
5763e4b17023SJohn Marino    pointer-to-derived may be converted to pointer-to-base; otherwise,
5764e4b17023SJohn Marino    only the other direction is permitted.  If C_CAST_P is true, this
5765e4b17023SJohn Marino    conversion is taking place as part of a C-style cast.  */
5766e4b17023SJohn Marino 
5767e4b17023SJohn Marino tree
convert_ptrmem(tree type,tree expr,bool allow_inverse_p,bool c_cast_p,tsubst_flags_t complain)5768e4b17023SJohn Marino convert_ptrmem (tree type, tree expr, bool allow_inverse_p,
5769e4b17023SJohn Marino 		bool c_cast_p, tsubst_flags_t complain)
5770e4b17023SJohn Marino {
5771e4b17023SJohn Marino   if (TYPE_PTRMEM_P (type))
5772e4b17023SJohn Marino     {
5773e4b17023SJohn Marino       tree delta;
5774e4b17023SJohn Marino 
5775e4b17023SJohn Marino       if (TREE_CODE (expr) == PTRMEM_CST)
5776e4b17023SJohn Marino 	expr = cplus_expand_constant (expr);
5777e4b17023SJohn Marino       delta = get_delta_difference (TYPE_PTRMEM_CLASS_TYPE (TREE_TYPE (expr)),
5778e4b17023SJohn Marino 				    TYPE_PTRMEM_CLASS_TYPE (type),
5779e4b17023SJohn Marino 				    allow_inverse_p,
5780e4b17023SJohn Marino 				    c_cast_p, complain);
5781e4b17023SJohn Marino       if (delta == error_mark_node)
5782e4b17023SJohn Marino 	return error_mark_node;
5783e4b17023SJohn Marino 
5784e4b17023SJohn Marino       if (!integer_zerop (delta))
5785e4b17023SJohn Marino 	{
5786e4b17023SJohn Marino 	  tree cond, op1, op2;
5787e4b17023SJohn Marino 
5788e4b17023SJohn Marino 	  cond = cp_build_binary_op (input_location,
5789e4b17023SJohn Marino 				     EQ_EXPR,
5790e4b17023SJohn Marino 				     expr,
5791e4b17023SJohn Marino 				     build_int_cst (TREE_TYPE (expr), -1),
5792e4b17023SJohn Marino 				     tf_warning_or_error);
5793e4b17023SJohn Marino 	  op1 = build_nop (ptrdiff_type_node, expr);
5794e4b17023SJohn Marino 	  op2 = cp_build_binary_op (input_location,
5795e4b17023SJohn Marino 				    PLUS_EXPR, op1, delta,
5796e4b17023SJohn Marino 				    tf_warning_or_error);
5797e4b17023SJohn Marino 
5798e4b17023SJohn Marino 	  expr = fold_build3_loc (input_location,
5799e4b17023SJohn Marino 			      COND_EXPR, ptrdiff_type_node, cond, op1, op2);
5800e4b17023SJohn Marino 
5801e4b17023SJohn Marino 	}
5802e4b17023SJohn Marino 
5803e4b17023SJohn Marino       return build_nop (type, expr);
5804e4b17023SJohn Marino     }
5805e4b17023SJohn Marino   else
5806e4b17023SJohn Marino     return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr,
5807e4b17023SJohn Marino 			     allow_inverse_p, c_cast_p, complain);
5808e4b17023SJohn Marino }
5809e4b17023SJohn Marino 
5810e4b17023SJohn Marino /* Perform a static_cast from EXPR to TYPE.  When C_CAST_P is true,
5811e4b17023SJohn Marino    this static_cast is being attempted as one of the possible casts
5812e4b17023SJohn Marino    allowed by a C-style cast.  (In that case, accessibility of base
5813e4b17023SJohn Marino    classes is not considered, and it is OK to cast away
5814e4b17023SJohn Marino    constness.)  Return the result of the cast.  *VALID_P is set to
5815e4b17023SJohn Marino    indicate whether or not the cast was valid.  */
5816e4b17023SJohn Marino 
5817e4b17023SJohn Marino static tree
build_static_cast_1(tree type,tree expr,bool c_cast_p,bool * valid_p,tsubst_flags_t complain)5818e4b17023SJohn Marino build_static_cast_1 (tree type, tree expr, bool c_cast_p,
5819e4b17023SJohn Marino 		     bool *valid_p, tsubst_flags_t complain)
5820e4b17023SJohn Marino {
5821e4b17023SJohn Marino   tree intype;
5822e4b17023SJohn Marino   tree result;
5823e4b17023SJohn Marino   cp_lvalue_kind clk;
5824e4b17023SJohn Marino 
5825e4b17023SJohn Marino   /* Assume the cast is valid.  */
5826e4b17023SJohn Marino   *valid_p = true;
5827e4b17023SJohn Marino 
5828e4b17023SJohn Marino   intype = unlowered_expr_type (expr);
5829e4b17023SJohn Marino 
5830e4b17023SJohn Marino   /* Save casted types in the function's used types hash table.  */
5831e4b17023SJohn Marino   used_types_insert (type);
5832e4b17023SJohn Marino 
5833e4b17023SJohn Marino   /* [expr.static.cast]
5834e4b17023SJohn Marino 
5835e4b17023SJohn Marino      An lvalue of type "cv1 B", where B is a class type, can be cast
5836e4b17023SJohn Marino      to type "reference to cv2 D", where D is a class derived (clause
5837e4b17023SJohn Marino      _class.derived_) from B, if a valid standard conversion from
5838e4b17023SJohn Marino      "pointer to D" to "pointer to B" exists (_conv.ptr_), cv2 is the
5839e4b17023SJohn Marino      same cv-qualification as, or greater cv-qualification than, cv1,
5840e4b17023SJohn Marino      and B is not a virtual base class of D.  */
5841e4b17023SJohn Marino   /* We check this case before checking the validity of "TYPE t =
5842e4b17023SJohn Marino      EXPR;" below because for this case:
5843e4b17023SJohn Marino 
5844e4b17023SJohn Marino        struct B {};
5845e4b17023SJohn Marino        struct D : public B { D(const B&); };
5846e4b17023SJohn Marino        extern B& b;
5847e4b17023SJohn Marino        void f() { static_cast<const D&>(b); }
5848e4b17023SJohn Marino 
5849e4b17023SJohn Marino      we want to avoid constructing a new D.  The standard is not
5850e4b17023SJohn Marino      completely clear about this issue, but our interpretation is
5851e4b17023SJohn Marino      consistent with other compilers.  */
5852e4b17023SJohn Marino   if (TREE_CODE (type) == REFERENCE_TYPE
5853e4b17023SJohn Marino       && CLASS_TYPE_P (TREE_TYPE (type))
5854e4b17023SJohn Marino       && CLASS_TYPE_P (intype)
5855e4b17023SJohn Marino       && (TYPE_REF_IS_RVALUE (type) || real_lvalue_p (expr))
5856e4b17023SJohn Marino       && DERIVED_FROM_P (intype, TREE_TYPE (type))
5857e4b17023SJohn Marino       && can_convert (build_pointer_type (TYPE_MAIN_VARIANT (intype)),
5858e4b17023SJohn Marino 		      build_pointer_type (TYPE_MAIN_VARIANT
5859e4b17023SJohn Marino 					  (TREE_TYPE (type))))
5860e4b17023SJohn Marino       && (c_cast_p
5861e4b17023SJohn Marino 	  || at_least_as_qualified_p (TREE_TYPE (type), intype)))
5862e4b17023SJohn Marino     {
5863e4b17023SJohn Marino       tree base;
5864e4b17023SJohn Marino 
5865e4b17023SJohn Marino       /* There is a standard conversion from "D*" to "B*" even if "B"
5866e4b17023SJohn Marino 	 is ambiguous or inaccessible.  If this is really a
5867e4b17023SJohn Marino 	 static_cast, then we check both for inaccessibility and
5868e4b17023SJohn Marino 	 ambiguity.  However, if this is a static_cast being performed
5869e4b17023SJohn Marino 	 because the user wrote a C-style cast, then accessibility is
5870e4b17023SJohn Marino 	 not considered.  */
5871e4b17023SJohn Marino       base = lookup_base (TREE_TYPE (type), intype,
5872e4b17023SJohn Marino 			  c_cast_p ? ba_unique : ba_check,
5873e4b17023SJohn Marino 			  NULL);
5874e4b17023SJohn Marino 
5875e4b17023SJohn Marino       /* Convert from "B*" to "D*".  This function will check that "B"
5876e4b17023SJohn Marino 	 is not a virtual base of "D".  */
5877e4b17023SJohn Marino       expr = build_base_path (MINUS_EXPR, build_address (expr),
5878e4b17023SJohn Marino 			      base, /*nonnull=*/false, complain);
5879e4b17023SJohn Marino       /* Convert the pointer to a reference -- but then remember that
5880e4b17023SJohn Marino 	 there are no expressions with reference type in C++.
5881e4b17023SJohn Marino 
5882e4b17023SJohn Marino          We call rvalue so that there's an actual tree code
5883e4b17023SJohn Marino          (NON_LVALUE_EXPR) for the static_cast; otherwise, if the operand
5884e4b17023SJohn Marino          is a variable with the same type, the conversion would get folded
5885e4b17023SJohn Marino          away, leaving just the variable and causing lvalue_kind to give
5886e4b17023SJohn Marino          the wrong answer.  */
5887e4b17023SJohn Marino       return convert_from_reference (rvalue (cp_fold_convert (type, expr)));
5888e4b17023SJohn Marino     }
5889e4b17023SJohn Marino 
5890e4b17023SJohn Marino   /* "A glvalue of type cv1 T1 can be cast to type rvalue reference to
5891e4b17023SJohn Marino      cv2 T2 if cv2 T2 is reference-compatible with cv1 T1 (8.5.3)."  */
5892e4b17023SJohn Marino   if (TREE_CODE (type) == REFERENCE_TYPE
5893e4b17023SJohn Marino       && TYPE_REF_IS_RVALUE (type)
5894e4b17023SJohn Marino       && (clk = real_lvalue_p (expr))
5895e4b17023SJohn Marino       && reference_related_p (TREE_TYPE (type), intype)
5896e4b17023SJohn Marino       && (c_cast_p || at_least_as_qualified_p (TREE_TYPE (type), intype)))
5897e4b17023SJohn Marino     {
5898e4b17023SJohn Marino       if (clk == clk_ordinary)
5899e4b17023SJohn Marino 	{
5900e4b17023SJohn Marino 	  /* Handle the (non-bit-field) lvalue case here by casting to
5901e4b17023SJohn Marino 	     lvalue reference and then changing it to an rvalue reference.
5902e4b17023SJohn Marino 	     Casting an xvalue to rvalue reference will be handled by the
5903e4b17023SJohn Marino 	     main code path.  */
5904e4b17023SJohn Marino 	  tree lref = cp_build_reference_type (TREE_TYPE (type), false);
5905e4b17023SJohn Marino 	  result = (perform_direct_initialization_if_possible
5906e4b17023SJohn Marino 		    (lref, expr, c_cast_p, complain));
5907e4b17023SJohn Marino 	  result = cp_fold_convert (type, result);
5908e4b17023SJohn Marino 	  /* Make sure we don't fold back down to a named rvalue reference,
5909e4b17023SJohn Marino 	     because that would be an lvalue.  */
5910e4b17023SJohn Marino 	  if (DECL_P (result))
5911e4b17023SJohn Marino 	    result = build1 (NON_LVALUE_EXPR, type, result);
5912e4b17023SJohn Marino 	  return convert_from_reference (result);
5913e4b17023SJohn Marino 	}
5914e4b17023SJohn Marino       else
5915e4b17023SJohn Marino 	/* For a bit-field or packed field, bind to a temporary.  */
5916e4b17023SJohn Marino 	expr = rvalue (expr);
5917e4b17023SJohn Marino     }
5918e4b17023SJohn Marino 
5919e4b17023SJohn Marino   /* Resolve overloaded address here rather than once in
5920e4b17023SJohn Marino      implicit_conversion and again in the inverse code below.  */
5921e4b17023SJohn Marino   if (TYPE_PTRMEMFUNC_P (type) && type_unknown_p (expr))
5922e4b17023SJohn Marino     {
5923e4b17023SJohn Marino       expr = instantiate_type (type, expr, complain);
5924e4b17023SJohn Marino       intype = TREE_TYPE (expr);
5925e4b17023SJohn Marino     }
5926e4b17023SJohn Marino 
5927e4b17023SJohn Marino   /* [expr.static.cast]
5928e4b17023SJohn Marino 
5929e4b17023SJohn Marino      An expression e can be explicitly converted to a type T using a
5930e4b17023SJohn Marino      static_cast of the form static_cast<T>(e) if the declaration T
5931e4b17023SJohn Marino      t(e);" is well-formed, for some invented temporary variable
5932e4b17023SJohn Marino      t.  */
5933e4b17023SJohn Marino   result = perform_direct_initialization_if_possible (type, expr,
5934e4b17023SJohn Marino 						      c_cast_p, complain);
5935e4b17023SJohn Marino   if (result)
5936e4b17023SJohn Marino     {
5937e4b17023SJohn Marino       result = convert_from_reference (result);
5938e4b17023SJohn Marino 
5939e4b17023SJohn Marino       /* [expr.static.cast]
5940e4b17023SJohn Marino 
5941e4b17023SJohn Marino 	 If T is a reference type, the result is an lvalue; otherwise,
5942e4b17023SJohn Marino 	 the result is an rvalue.  */
5943e4b17023SJohn Marino       if (TREE_CODE (type) != REFERENCE_TYPE)
5944e4b17023SJohn Marino 	result = rvalue (result);
5945e4b17023SJohn Marino       return result;
5946e4b17023SJohn Marino     }
5947e4b17023SJohn Marino 
5948e4b17023SJohn Marino   /* [expr.static.cast]
5949e4b17023SJohn Marino 
5950e4b17023SJohn Marino      Any expression can be explicitly converted to type cv void.  */
5951e4b17023SJohn Marino   if (TREE_CODE (type) == VOID_TYPE)
5952e4b17023SJohn Marino     return convert_to_void (expr, ICV_CAST, complain);
5953e4b17023SJohn Marino 
5954e4b17023SJohn Marino   /* [expr.static.cast]
5955e4b17023SJohn Marino 
5956e4b17023SJohn Marino      The inverse of any standard conversion sequence (clause _conv_),
5957e4b17023SJohn Marino      other than the lvalue-to-rvalue (_conv.lval_), array-to-pointer
5958e4b17023SJohn Marino      (_conv.array_), function-to-pointer (_conv.func_), and boolean
5959e4b17023SJohn Marino      (_conv.bool_) conversions, can be performed explicitly using
5960e4b17023SJohn Marino      static_cast subject to the restriction that the explicit
5961e4b17023SJohn Marino      conversion does not cast away constness (_expr.const.cast_), and
5962e4b17023SJohn Marino      the following additional rules for specific cases:  */
5963e4b17023SJohn Marino   /* For reference, the conversions not excluded are: integral
5964e4b17023SJohn Marino      promotions, floating point promotion, integral conversions,
5965e4b17023SJohn Marino      floating point conversions, floating-integral conversions,
5966e4b17023SJohn Marino      pointer conversions, and pointer to member conversions.  */
5967e4b17023SJohn Marino   /* DR 128
5968e4b17023SJohn Marino 
5969e4b17023SJohn Marino      A value of integral _or enumeration_ type can be explicitly
5970e4b17023SJohn Marino      converted to an enumeration type.  */
5971e4b17023SJohn Marino   /* The effect of all that is that any conversion between any two
5972e4b17023SJohn Marino      types which are integral, floating, or enumeration types can be
5973e4b17023SJohn Marino      performed.  */
5974e4b17023SJohn Marino   if ((INTEGRAL_OR_ENUMERATION_TYPE_P (type)
5975e4b17023SJohn Marino        || SCALAR_FLOAT_TYPE_P (type))
5976e4b17023SJohn Marino       && (INTEGRAL_OR_ENUMERATION_TYPE_P (intype)
5977e4b17023SJohn Marino 	  || SCALAR_FLOAT_TYPE_P (intype)))
5978e4b17023SJohn Marino     return ocp_convert (type, expr, CONV_C_CAST, LOOKUP_NORMAL);
5979e4b17023SJohn Marino 
5980e4b17023SJohn Marino   if (TYPE_PTR_P (type) && TYPE_PTR_P (intype)
5981e4b17023SJohn Marino       && CLASS_TYPE_P (TREE_TYPE (type))
5982e4b17023SJohn Marino       && CLASS_TYPE_P (TREE_TYPE (intype))
5983e4b17023SJohn Marino       && can_convert (build_pointer_type (TYPE_MAIN_VARIANT
5984e4b17023SJohn Marino 					  (TREE_TYPE (intype))),
5985e4b17023SJohn Marino 		      build_pointer_type (TYPE_MAIN_VARIANT
5986e4b17023SJohn Marino 					  (TREE_TYPE (type)))))
5987e4b17023SJohn Marino     {
5988e4b17023SJohn Marino       tree base;
5989e4b17023SJohn Marino 
5990e4b17023SJohn Marino       if (!c_cast_p
5991e4b17023SJohn Marino 	  && check_for_casting_away_constness (intype, type, STATIC_CAST_EXPR,
5992e4b17023SJohn Marino 					       complain))
5993e4b17023SJohn Marino 	return error_mark_node;
5994e4b17023SJohn Marino       base = lookup_base (TREE_TYPE (type), TREE_TYPE (intype),
5995e4b17023SJohn Marino 			  c_cast_p ? ba_unique : ba_check,
5996e4b17023SJohn Marino 			  NULL);
5997e4b17023SJohn Marino       expr = build_base_path (MINUS_EXPR, expr, base, /*nonnull=*/false,
5998e4b17023SJohn Marino 			      complain);
5999e4b17023SJohn Marino       return cp_fold_convert(type, expr);
6000e4b17023SJohn Marino     }
6001e4b17023SJohn Marino 
6002e4b17023SJohn Marino   if ((TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype))
6003e4b17023SJohn Marino       || (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype)))
6004e4b17023SJohn Marino     {
6005e4b17023SJohn Marino       tree c1;
6006e4b17023SJohn Marino       tree c2;
6007e4b17023SJohn Marino       tree t1;
6008e4b17023SJohn Marino       tree t2;
6009e4b17023SJohn Marino 
6010e4b17023SJohn Marino       c1 = TYPE_PTRMEM_CLASS_TYPE (intype);
6011e4b17023SJohn Marino       c2 = TYPE_PTRMEM_CLASS_TYPE (type);
6012e4b17023SJohn Marino 
6013e4b17023SJohn Marino       if (TYPE_PTRMEM_P (type))
6014e4b17023SJohn Marino 	{
6015e4b17023SJohn Marino 	  t1 = (build_ptrmem_type
6016e4b17023SJohn Marino 		(c1,
6017e4b17023SJohn Marino 		 TYPE_MAIN_VARIANT (TYPE_PTRMEM_POINTED_TO_TYPE (intype))));
6018e4b17023SJohn Marino 	  t2 = (build_ptrmem_type
6019e4b17023SJohn Marino 		(c2,
6020e4b17023SJohn Marino 		 TYPE_MAIN_VARIANT (TYPE_PTRMEM_POINTED_TO_TYPE (type))));
6021e4b17023SJohn Marino 	}
6022e4b17023SJohn Marino       else
6023e4b17023SJohn Marino 	{
6024e4b17023SJohn Marino 	  t1 = intype;
6025e4b17023SJohn Marino 	  t2 = type;
6026e4b17023SJohn Marino 	}
6027e4b17023SJohn Marino       if (can_convert (t1, t2) || can_convert (t2, t1))
6028e4b17023SJohn Marino 	{
6029e4b17023SJohn Marino 	  if (!c_cast_p
6030e4b17023SJohn Marino 	      && check_for_casting_away_constness (intype, type,
6031e4b17023SJohn Marino 						   STATIC_CAST_EXPR,
6032e4b17023SJohn Marino 						   complain))
6033e4b17023SJohn Marino 	    return error_mark_node;
6034e4b17023SJohn Marino 	  return convert_ptrmem (type, expr, /*allow_inverse_p=*/1,
6035e4b17023SJohn Marino 				 c_cast_p, complain);
6036e4b17023SJohn Marino 	}
6037e4b17023SJohn Marino     }
6038e4b17023SJohn Marino 
6039e4b17023SJohn Marino   /* [expr.static.cast]
6040e4b17023SJohn Marino 
6041e4b17023SJohn Marino      An rvalue of type "pointer to cv void" can be explicitly
6042e4b17023SJohn Marino      converted to a pointer to object type.  A value of type pointer
6043e4b17023SJohn Marino      to object converted to "pointer to cv void" and back to the
6044e4b17023SJohn Marino      original pointer type will have its original value.  */
6045e4b17023SJohn Marino   if (TREE_CODE (intype) == POINTER_TYPE
6046e4b17023SJohn Marino       && VOID_TYPE_P (TREE_TYPE (intype))
6047e4b17023SJohn Marino       && TYPE_PTROB_P (type))
6048e4b17023SJohn Marino     {
6049e4b17023SJohn Marino       if (!c_cast_p
6050e4b17023SJohn Marino 	  && check_for_casting_away_constness (intype, type, STATIC_CAST_EXPR,
6051e4b17023SJohn Marino 					       complain))
6052e4b17023SJohn Marino 	return error_mark_node;
6053e4b17023SJohn Marino       return build_nop (type, expr);
6054e4b17023SJohn Marino     }
6055e4b17023SJohn Marino 
6056e4b17023SJohn Marino   *valid_p = false;
6057e4b17023SJohn Marino   return error_mark_node;
6058e4b17023SJohn Marino }
6059e4b17023SJohn Marino 
6060e4b17023SJohn Marino /* Return an expression representing static_cast<TYPE>(EXPR).  */
6061e4b17023SJohn Marino 
6062e4b17023SJohn Marino tree
build_static_cast(tree type,tree expr,tsubst_flags_t complain)6063e4b17023SJohn Marino build_static_cast (tree type, tree expr, tsubst_flags_t complain)
6064e4b17023SJohn Marino {
6065e4b17023SJohn Marino   tree result;
6066e4b17023SJohn Marino   bool valid_p;
6067e4b17023SJohn Marino 
6068e4b17023SJohn Marino   if (type == error_mark_node || expr == error_mark_node)
6069e4b17023SJohn Marino     return error_mark_node;
6070e4b17023SJohn Marino 
6071e4b17023SJohn Marino   if (processing_template_decl)
6072e4b17023SJohn Marino     {
6073e4b17023SJohn Marino       expr = build_min (STATIC_CAST_EXPR, type, expr);
6074e4b17023SJohn Marino       /* We don't know if it will or will not have side effects.  */
6075e4b17023SJohn Marino       TREE_SIDE_EFFECTS (expr) = 1;
6076e4b17023SJohn Marino       return convert_from_reference (expr);
6077e4b17023SJohn Marino     }
6078e4b17023SJohn Marino 
6079e4b17023SJohn Marino   /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
6080e4b17023SJohn Marino      Strip such NOP_EXPRs if VALUE is being used in non-lvalue context.  */
6081e4b17023SJohn Marino   if (TREE_CODE (type) != REFERENCE_TYPE
6082e4b17023SJohn Marino       && TREE_CODE (expr) == NOP_EXPR
6083e4b17023SJohn Marino       && TREE_TYPE (expr) == TREE_TYPE (TREE_OPERAND (expr, 0)))
6084e4b17023SJohn Marino     expr = TREE_OPERAND (expr, 0);
6085e4b17023SJohn Marino 
6086e4b17023SJohn Marino   result = build_static_cast_1 (type, expr, /*c_cast_p=*/false, &valid_p,
6087e4b17023SJohn Marino                                 complain);
6088e4b17023SJohn Marino   if (valid_p)
6089e4b17023SJohn Marino     return result;
6090e4b17023SJohn Marino 
6091e4b17023SJohn Marino   if (complain & tf_error)
6092e4b17023SJohn Marino     error ("invalid static_cast from type %qT to type %qT",
6093e4b17023SJohn Marino            TREE_TYPE (expr), type);
6094e4b17023SJohn Marino   return error_mark_node;
6095e4b17023SJohn Marino }
6096e4b17023SJohn Marino 
6097e4b17023SJohn Marino /* EXPR is an expression with member function or pointer-to-member
6098e4b17023SJohn Marino    function type.  TYPE is a pointer type.  Converting EXPR to TYPE is
6099e4b17023SJohn Marino    not permitted by ISO C++, but we accept it in some modes.  If we
6100e4b17023SJohn Marino    are not in one of those modes, issue a diagnostic.  Return the
6101e4b17023SJohn Marino    converted expression.  */
6102e4b17023SJohn Marino 
6103e4b17023SJohn Marino tree
convert_member_func_to_ptr(tree type,tree expr)6104e4b17023SJohn Marino convert_member_func_to_ptr (tree type, tree expr)
6105e4b17023SJohn Marino {
6106e4b17023SJohn Marino   tree intype;
6107e4b17023SJohn Marino   tree decl;
6108e4b17023SJohn Marino 
6109e4b17023SJohn Marino   intype = TREE_TYPE (expr);
6110e4b17023SJohn Marino   gcc_assert (TYPE_PTRMEMFUNC_P (intype)
6111e4b17023SJohn Marino 	      || TREE_CODE (intype) == METHOD_TYPE);
6112e4b17023SJohn Marino 
6113e4b17023SJohn Marino   if (pedantic || warn_pmf2ptr)
6114e4b17023SJohn Marino     pedwarn (input_location, pedantic ? OPT_pedantic : OPT_Wpmf_conversions,
6115e4b17023SJohn Marino 	     "converting from %qT to %qT", intype, type);
6116e4b17023SJohn Marino 
6117e4b17023SJohn Marino   if (TREE_CODE (intype) == METHOD_TYPE)
6118e4b17023SJohn Marino     expr = build_addr_func (expr);
6119e4b17023SJohn Marino   else if (TREE_CODE (expr) == PTRMEM_CST)
6120e4b17023SJohn Marino     expr = build_address (PTRMEM_CST_MEMBER (expr));
6121e4b17023SJohn Marino   else
6122e4b17023SJohn Marino     {
6123e4b17023SJohn Marino       decl = maybe_dummy_object (TYPE_PTRMEM_CLASS_TYPE (intype), 0);
6124e4b17023SJohn Marino       decl = build_address (decl);
6125e4b17023SJohn Marino       expr = get_member_function_from_ptrfunc (&decl, expr);
6126e4b17023SJohn Marino     }
6127e4b17023SJohn Marino 
6128e4b17023SJohn Marino   return build_nop (type, expr);
6129e4b17023SJohn Marino }
6130e4b17023SJohn Marino 
6131e4b17023SJohn Marino /* Return a representation for a reinterpret_cast from EXPR to TYPE.
6132e4b17023SJohn Marino    If C_CAST_P is true, this reinterpret cast is being done as part of
6133e4b17023SJohn Marino    a C-style cast.  If VALID_P is non-NULL, *VALID_P is set to
6134e4b17023SJohn Marino    indicate whether or not reinterpret_cast was valid.  */
6135e4b17023SJohn Marino 
6136e4b17023SJohn Marino static tree
build_reinterpret_cast_1(tree type,tree expr,bool c_cast_p,bool * valid_p,tsubst_flags_t complain)6137e4b17023SJohn Marino build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p,
6138e4b17023SJohn Marino 			  bool *valid_p, tsubst_flags_t complain)
6139e4b17023SJohn Marino {
6140e4b17023SJohn Marino   tree intype;
6141e4b17023SJohn Marino 
6142e4b17023SJohn Marino   /* Assume the cast is invalid.  */
6143e4b17023SJohn Marino   if (valid_p)
6144e4b17023SJohn Marino     *valid_p = true;
6145e4b17023SJohn Marino 
6146e4b17023SJohn Marino   if (type == error_mark_node || error_operand_p (expr))
6147e4b17023SJohn Marino     return error_mark_node;
6148e4b17023SJohn Marino 
6149e4b17023SJohn Marino   intype = TREE_TYPE (expr);
6150e4b17023SJohn Marino 
6151e4b17023SJohn Marino   /* Save casted types in the function's used types hash table.  */
6152e4b17023SJohn Marino   used_types_insert (type);
6153e4b17023SJohn Marino 
6154e4b17023SJohn Marino   /* [expr.reinterpret.cast]
6155e4b17023SJohn Marino      An lvalue expression of type T1 can be cast to the type
6156e4b17023SJohn Marino      "reference to T2" if an expression of type "pointer to T1" can be
6157e4b17023SJohn Marino      explicitly converted to the type "pointer to T2" using a
6158e4b17023SJohn Marino      reinterpret_cast.  */
6159e4b17023SJohn Marino   if (TREE_CODE (type) == REFERENCE_TYPE)
6160e4b17023SJohn Marino     {
6161e4b17023SJohn Marino       if (! real_lvalue_p (expr))
6162e4b17023SJohn Marino 	{
6163e4b17023SJohn Marino           if (complain & tf_error)
6164e4b17023SJohn Marino             error ("invalid cast of an rvalue expression of type "
6165e4b17023SJohn Marino                    "%qT to type %qT",
6166e4b17023SJohn Marino                    intype, type);
6167e4b17023SJohn Marino 	  return error_mark_node;
6168e4b17023SJohn Marino 	}
6169e4b17023SJohn Marino 
6170e4b17023SJohn Marino       /* Warn about a reinterpret_cast from "A*" to "B&" if "A" and
6171e4b17023SJohn Marino 	 "B" are related class types; the reinterpret_cast does not
6172e4b17023SJohn Marino 	 adjust the pointer.  */
6173e4b17023SJohn Marino       if (TYPE_PTR_P (intype)
6174e4b17023SJohn Marino           && (complain & tf_warning)
6175e4b17023SJohn Marino 	  && (comptypes (TREE_TYPE (intype), TREE_TYPE (type),
6176e4b17023SJohn Marino 			 COMPARE_BASE | COMPARE_DERIVED)))
6177e4b17023SJohn Marino 	warning (0, "casting %qT to %qT does not dereference pointer",
6178e4b17023SJohn Marino 		 intype, type);
6179e4b17023SJohn Marino 
6180e4b17023SJohn Marino       expr = cp_build_addr_expr (expr, complain);
6181e4b17023SJohn Marino 
6182e4b17023SJohn Marino       if (warn_strict_aliasing > 2)
6183e4b17023SJohn Marino 	strict_aliasing_warning (TREE_TYPE (expr), type, expr);
6184e4b17023SJohn Marino 
6185e4b17023SJohn Marino       if (expr != error_mark_node)
6186e4b17023SJohn Marino 	expr = build_reinterpret_cast_1
6187e4b17023SJohn Marino 	  (build_pointer_type (TREE_TYPE (type)), expr, c_cast_p,
6188e4b17023SJohn Marino 	   valid_p, complain);
6189e4b17023SJohn Marino       if (expr != error_mark_node)
6190e4b17023SJohn Marino 	/* cp_build_indirect_ref isn't right for rvalue refs.  */
6191e4b17023SJohn Marino 	expr = convert_from_reference (fold_convert (type, expr));
6192e4b17023SJohn Marino       return expr;
6193e4b17023SJohn Marino     }
6194e4b17023SJohn Marino 
6195e4b17023SJohn Marino   /* As a G++ extension, we consider conversions from member
6196e4b17023SJohn Marino      functions, and pointers to member functions to
6197e4b17023SJohn Marino      pointer-to-function and pointer-to-void types.  If
6198e4b17023SJohn Marino      -Wno-pmf-conversions has not been specified,
6199e4b17023SJohn Marino      convert_member_func_to_ptr will issue an error message.  */
6200e4b17023SJohn Marino   if ((TYPE_PTRMEMFUNC_P (intype)
6201e4b17023SJohn Marino        || TREE_CODE (intype) == METHOD_TYPE)
6202e4b17023SJohn Marino       && TYPE_PTR_P (type)
6203e4b17023SJohn Marino       && (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE
6204e4b17023SJohn Marino 	  || VOID_TYPE_P (TREE_TYPE (type))))
6205e4b17023SJohn Marino     return convert_member_func_to_ptr (type, expr);
6206e4b17023SJohn Marino 
6207e4b17023SJohn Marino   /* If the cast is not to a reference type, the lvalue-to-rvalue,
6208e4b17023SJohn Marino      array-to-pointer, and function-to-pointer conversions are
6209e4b17023SJohn Marino      performed.  */
6210e4b17023SJohn Marino   expr = decay_conversion (expr);
6211e4b17023SJohn Marino 
6212e4b17023SJohn Marino   /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
6213e4b17023SJohn Marino      Strip such NOP_EXPRs if VALUE is being used in non-lvalue context.  */
6214e4b17023SJohn Marino   if (TREE_CODE (expr) == NOP_EXPR
6215e4b17023SJohn Marino       && TREE_TYPE (expr) == TREE_TYPE (TREE_OPERAND (expr, 0)))
6216e4b17023SJohn Marino     expr = TREE_OPERAND (expr, 0);
6217e4b17023SJohn Marino 
6218e4b17023SJohn Marino   if (error_operand_p (expr))
6219e4b17023SJohn Marino     return error_mark_node;
6220e4b17023SJohn Marino 
6221e4b17023SJohn Marino   intype = TREE_TYPE (expr);
6222e4b17023SJohn Marino 
6223e4b17023SJohn Marino   /* [expr.reinterpret.cast]
6224e4b17023SJohn Marino      A pointer can be converted to any integral type large enough to
6225e4b17023SJohn Marino      hold it. ... A value of type std::nullptr_t can be converted to
6226e4b17023SJohn Marino      an integral type; the conversion has the same meaning and
6227e4b17023SJohn Marino      validity as a conversion of (void*)0 to the integral type.  */
6228e4b17023SJohn Marino   if (CP_INTEGRAL_TYPE_P (type)
6229e4b17023SJohn Marino       && (TYPE_PTR_P (intype) || NULLPTR_TYPE_P (intype)))
6230e4b17023SJohn Marino     {
6231e4b17023SJohn Marino       if (TYPE_PRECISION (type) < TYPE_PRECISION (intype))
6232e4b17023SJohn Marino         {
6233e4b17023SJohn Marino           if (complain & tf_error)
6234e4b17023SJohn Marino             permerror (input_location, "cast from %qT to %qT loses precision",
6235e4b17023SJohn Marino                        intype, type);
6236e4b17023SJohn Marino           else
6237e4b17023SJohn Marino             return error_mark_node;
6238e4b17023SJohn Marino         }
6239e4b17023SJohn Marino       if (NULLPTR_TYPE_P (intype))
6240e4b17023SJohn Marino         return build_int_cst (type, 0);
6241e4b17023SJohn Marino     }
6242e4b17023SJohn Marino   /* [expr.reinterpret.cast]
6243e4b17023SJohn Marino      A value of integral or enumeration type can be explicitly
6244e4b17023SJohn Marino      converted to a pointer.  */
6245e4b17023SJohn Marino   else if (TYPE_PTR_P (type) && INTEGRAL_OR_ENUMERATION_TYPE_P (intype))
6246e4b17023SJohn Marino     /* OK */
6247e4b17023SJohn Marino     ;
6248e4b17023SJohn Marino   else if ((INTEGRAL_OR_ENUMERATION_TYPE_P (type)
6249e4b17023SJohn Marino 	    || TYPE_PTR_P (type) || TYPE_PTR_TO_MEMBER_P (type))
6250e4b17023SJohn Marino 	   && same_type_p (type, intype))
6251e4b17023SJohn Marino     /* DR 799 */
6252e4b17023SJohn Marino     return fold_if_not_in_template (build_nop (type, expr));
6253e4b17023SJohn Marino   else if ((TYPE_PTRFN_P (type) && TYPE_PTRFN_P (intype))
6254e4b17023SJohn Marino 	   || (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype)))
6255e4b17023SJohn Marino     return fold_if_not_in_template (build_nop (type, expr));
6256e4b17023SJohn Marino   else if ((TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype))
6257e4b17023SJohn Marino 	   || (TYPE_PTROBV_P (type) && TYPE_PTROBV_P (intype)))
6258e4b17023SJohn Marino     {
6259e4b17023SJohn Marino       tree sexpr = expr;
6260e4b17023SJohn Marino 
6261e4b17023SJohn Marino       if (!c_cast_p
6262e4b17023SJohn Marino 	  && check_for_casting_away_constness (intype, type,
6263e4b17023SJohn Marino 					       REINTERPRET_CAST_EXPR,
6264e4b17023SJohn Marino 					       complain))
6265e4b17023SJohn Marino 	return error_mark_node;
6266e4b17023SJohn Marino       /* Warn about possible alignment problems.  */
6267e4b17023SJohn Marino       if (STRICT_ALIGNMENT && warn_cast_align
6268e4b17023SJohn Marino           && (complain & tf_warning)
6269e4b17023SJohn Marino 	  && !VOID_TYPE_P (type)
6270e4b17023SJohn Marino 	  && TREE_CODE (TREE_TYPE (intype)) != FUNCTION_TYPE
6271e4b17023SJohn Marino 	  && COMPLETE_TYPE_P (TREE_TYPE (type))
6272e4b17023SJohn Marino 	  && COMPLETE_TYPE_P (TREE_TYPE (intype))
6273e4b17023SJohn Marino 	  && TYPE_ALIGN (TREE_TYPE (type)) > TYPE_ALIGN (TREE_TYPE (intype)))
6274e4b17023SJohn Marino 	warning (OPT_Wcast_align, "cast from %qT to %qT "
6275e4b17023SJohn Marino                  "increases required alignment of target type", intype, type);
6276e4b17023SJohn Marino 
6277e4b17023SJohn Marino       /* We need to strip nops here, because the front end likes to
6278e4b17023SJohn Marino 	 create (int *)&a for array-to-pointer decay, instead of &a[0].  */
6279e4b17023SJohn Marino       STRIP_NOPS (sexpr);
6280e4b17023SJohn Marino       if (warn_strict_aliasing <= 2)
6281e4b17023SJohn Marino 	strict_aliasing_warning (intype, type, sexpr);
6282e4b17023SJohn Marino 
6283e4b17023SJohn Marino       return fold_if_not_in_template (build_nop (type, expr));
6284e4b17023SJohn Marino     }
6285e4b17023SJohn Marino   else if ((TYPE_PTRFN_P (type) && TYPE_PTROBV_P (intype))
6286e4b17023SJohn Marino 	   || (TYPE_PTRFN_P (intype) && TYPE_PTROBV_P (type)))
6287e4b17023SJohn Marino     {
6288e4b17023SJohn Marino       if (pedantic && (complain & tf_warning))
6289e4b17023SJohn Marino 	/* Only issue a warning, as we have always supported this
6290e4b17023SJohn Marino 	   where possible, and it is necessary in some cases.  DR 195
6291e4b17023SJohn Marino 	   addresses this issue, but as of 2004/10/26 is still in
6292e4b17023SJohn Marino 	   drafting.  */
6293e4b17023SJohn Marino 	warning (0, "ISO C++ forbids casting between pointer-to-function and pointer-to-object");
6294e4b17023SJohn Marino       return fold_if_not_in_template (build_nop (type, expr));
6295e4b17023SJohn Marino     }
6296e4b17023SJohn Marino   else if (TREE_CODE (type) == VECTOR_TYPE)
6297e4b17023SJohn Marino     return fold_if_not_in_template (convert_to_vector (type, expr));
6298e4b17023SJohn Marino   else if (TREE_CODE (intype) == VECTOR_TYPE
6299e4b17023SJohn Marino 	   && INTEGRAL_OR_ENUMERATION_TYPE_P (type))
6300e4b17023SJohn Marino     return fold_if_not_in_template (convert_to_integer (type, expr));
6301e4b17023SJohn Marino   else
6302e4b17023SJohn Marino     {
6303e4b17023SJohn Marino       if (valid_p)
6304e4b17023SJohn Marino 	*valid_p = false;
6305e4b17023SJohn Marino       if (complain & tf_error)
6306e4b17023SJohn Marino         error ("invalid cast from type %qT to type %qT", intype, type);
6307e4b17023SJohn Marino       return error_mark_node;
6308e4b17023SJohn Marino     }
6309e4b17023SJohn Marino 
6310e4b17023SJohn Marino   return cp_convert (type, expr);
6311e4b17023SJohn Marino }
6312e4b17023SJohn Marino 
6313e4b17023SJohn Marino tree
build_reinterpret_cast(tree type,tree expr,tsubst_flags_t complain)6314e4b17023SJohn Marino build_reinterpret_cast (tree type, tree expr, tsubst_flags_t complain)
6315e4b17023SJohn Marino {
6316e4b17023SJohn Marino   if (type == error_mark_node || expr == error_mark_node)
6317e4b17023SJohn Marino     return error_mark_node;
6318e4b17023SJohn Marino 
6319e4b17023SJohn Marino   if (processing_template_decl)
6320e4b17023SJohn Marino     {
6321e4b17023SJohn Marino       tree t = build_min (REINTERPRET_CAST_EXPR, type, expr);
6322e4b17023SJohn Marino 
6323e4b17023SJohn Marino       if (!TREE_SIDE_EFFECTS (t)
6324e4b17023SJohn Marino 	  && type_dependent_expression_p (expr))
6325e4b17023SJohn Marino 	/* There might turn out to be side effects inside expr.  */
6326e4b17023SJohn Marino 	TREE_SIDE_EFFECTS (t) = 1;
6327e4b17023SJohn Marino       return convert_from_reference (t);
6328e4b17023SJohn Marino     }
6329e4b17023SJohn Marino 
6330e4b17023SJohn Marino   return build_reinterpret_cast_1 (type, expr, /*c_cast_p=*/false,
6331e4b17023SJohn Marino 				   /*valid_p=*/NULL, complain);
6332e4b17023SJohn Marino }
6333e4b17023SJohn Marino 
6334e4b17023SJohn Marino /* Perform a const_cast from EXPR to TYPE.  If the cast is valid,
6335e4b17023SJohn Marino    return an appropriate expression.  Otherwise, return
6336e4b17023SJohn Marino    error_mark_node.  If the cast is not valid, and COMPLAIN is true,
6337e4b17023SJohn Marino    then a diagnostic will be issued.  If VALID_P is non-NULL, we are
6338e4b17023SJohn Marino    performing a C-style cast, its value upon return will indicate
6339e4b17023SJohn Marino    whether or not the conversion succeeded.  */
6340e4b17023SJohn Marino 
6341e4b17023SJohn Marino static tree
build_const_cast_1(tree dst_type,tree expr,tsubst_flags_t complain,bool * valid_p)6342e4b17023SJohn Marino build_const_cast_1 (tree dst_type, tree expr, tsubst_flags_t complain,
6343e4b17023SJohn Marino 		    bool *valid_p)
6344e4b17023SJohn Marino {
6345e4b17023SJohn Marino   tree src_type;
6346e4b17023SJohn Marino   tree reference_type;
6347e4b17023SJohn Marino 
6348e4b17023SJohn Marino   /* Callers are responsible for handling error_mark_node as a
6349e4b17023SJohn Marino      destination type.  */
6350e4b17023SJohn Marino   gcc_assert (dst_type != error_mark_node);
6351e4b17023SJohn Marino   /* In a template, callers should be building syntactic
6352e4b17023SJohn Marino      representations of casts, not using this machinery.  */
6353e4b17023SJohn Marino   gcc_assert (!processing_template_decl);
6354e4b17023SJohn Marino 
6355e4b17023SJohn Marino   /* Assume the conversion is invalid.  */
6356e4b17023SJohn Marino   if (valid_p)
6357e4b17023SJohn Marino     *valid_p = false;
6358e4b17023SJohn Marino 
6359e4b17023SJohn Marino   if (!POINTER_TYPE_P (dst_type) && !TYPE_PTRMEM_P (dst_type))
6360e4b17023SJohn Marino     {
6361e4b17023SJohn Marino       if (complain & tf_error)
6362e4b17023SJohn Marino 	error ("invalid use of const_cast with type %qT, "
6363e4b17023SJohn Marino 	       "which is not a pointer, "
6364e4b17023SJohn Marino 	       "reference, nor a pointer-to-data-member type", dst_type);
6365e4b17023SJohn Marino       return error_mark_node;
6366e4b17023SJohn Marino     }
6367e4b17023SJohn Marino 
6368e4b17023SJohn Marino   if (TREE_CODE (TREE_TYPE (dst_type)) == FUNCTION_TYPE)
6369e4b17023SJohn Marino     {
6370e4b17023SJohn Marino       if (complain & tf_error)
6371e4b17023SJohn Marino 	error ("invalid use of const_cast with type %qT, which is a pointer "
6372e4b17023SJohn Marino 	       "or reference to a function type", dst_type);
6373e4b17023SJohn Marino       return error_mark_node;
6374e4b17023SJohn Marino     }
6375e4b17023SJohn Marino 
6376e4b17023SJohn Marino   /* Save casted types in the function's used types hash table.  */
6377e4b17023SJohn Marino   used_types_insert (dst_type);
6378e4b17023SJohn Marino 
6379e4b17023SJohn Marino   src_type = TREE_TYPE (expr);
6380e4b17023SJohn Marino   /* Expressions do not really have reference types.  */
6381e4b17023SJohn Marino   if (TREE_CODE (src_type) == REFERENCE_TYPE)
6382e4b17023SJohn Marino     src_type = TREE_TYPE (src_type);
6383e4b17023SJohn Marino 
6384e4b17023SJohn Marino   /* [expr.const.cast]
6385e4b17023SJohn Marino 
6386e4b17023SJohn Marino      For two object types T1 and T2, if a pointer to T1 can be explicitly
6387e4b17023SJohn Marino      converted to the type "pointer to T2" using a const_cast, then the
6388e4b17023SJohn Marino      following conversions can also be made:
6389e4b17023SJohn Marino 
6390e4b17023SJohn Marino      -- an lvalue of type T1 can be explicitly converted to an lvalue of
6391e4b17023SJohn Marino      type T2 using the cast const_cast<T2&>;
6392e4b17023SJohn Marino 
6393e4b17023SJohn Marino      -- a glvalue of type T1 can be explicitly converted to an xvalue of
6394e4b17023SJohn Marino      type T2 using the cast const_cast<T2&&>; and
6395e4b17023SJohn Marino 
6396e4b17023SJohn Marino      -- if T1 is a class type, a prvalue of type T1 can be explicitly
6397e4b17023SJohn Marino      converted to an xvalue of type T2 using the cast const_cast<T2&&>.  */
6398e4b17023SJohn Marino 
6399e4b17023SJohn Marino   if (TREE_CODE (dst_type) == REFERENCE_TYPE)
6400e4b17023SJohn Marino     {
6401e4b17023SJohn Marino       reference_type = dst_type;
6402e4b17023SJohn Marino       if (!TYPE_REF_IS_RVALUE (dst_type)
6403e4b17023SJohn Marino 	  ? real_lvalue_p (expr)
6404e4b17023SJohn Marino 	  : (CLASS_TYPE_P (TREE_TYPE (dst_type))
6405e4b17023SJohn Marino 	     ? lvalue_p (expr)
6406e4b17023SJohn Marino 	     : lvalue_or_rvalue_with_address_p (expr)))
6407e4b17023SJohn Marino 	/* OK.  */;
6408e4b17023SJohn Marino       else
6409e4b17023SJohn Marino 	{
6410e4b17023SJohn Marino 	  if (complain & tf_error)
6411e4b17023SJohn Marino 	    error ("invalid const_cast of an rvalue of type %qT to type %qT",
6412e4b17023SJohn Marino 		   src_type, dst_type);
6413e4b17023SJohn Marino 	  return error_mark_node;
6414e4b17023SJohn Marino 	}
6415e4b17023SJohn Marino       dst_type = build_pointer_type (TREE_TYPE (dst_type));
6416e4b17023SJohn Marino       src_type = build_pointer_type (src_type);
6417e4b17023SJohn Marino     }
6418e4b17023SJohn Marino   else
6419e4b17023SJohn Marino     {
6420e4b17023SJohn Marino       reference_type = NULL_TREE;
6421e4b17023SJohn Marino       /* If the destination type is not a reference type, the
6422e4b17023SJohn Marino 	 lvalue-to-rvalue, array-to-pointer, and function-to-pointer
6423e4b17023SJohn Marino 	 conversions are performed.  */
6424e4b17023SJohn Marino       src_type = type_decays_to (src_type);
6425e4b17023SJohn Marino       if (src_type == error_mark_node)
6426e4b17023SJohn Marino 	return error_mark_node;
6427e4b17023SJohn Marino     }
6428e4b17023SJohn Marino 
6429e4b17023SJohn Marino   if (TYPE_PTR_P (src_type) || TYPE_PTRMEM_P (src_type))
6430e4b17023SJohn Marino     {
6431e4b17023SJohn Marino       if (comp_ptr_ttypes_const (dst_type, src_type))
6432e4b17023SJohn Marino 	{
6433e4b17023SJohn Marino 	  if (valid_p)
6434e4b17023SJohn Marino 	    {
6435e4b17023SJohn Marino 	      *valid_p = true;
6436e4b17023SJohn Marino 	      /* This cast is actually a C-style cast.  Issue a warning if
6437e4b17023SJohn Marino 		 the user is making a potentially unsafe cast.  */
6438e4b17023SJohn Marino 	      check_for_casting_away_constness (src_type, dst_type,
6439e4b17023SJohn Marino 						CAST_EXPR, complain);
6440e4b17023SJohn Marino 	    }
6441e4b17023SJohn Marino 	  if (reference_type)
6442e4b17023SJohn Marino 	    {
6443e4b17023SJohn Marino 	      expr = cp_build_addr_expr (expr, complain);
6444e4b17023SJohn Marino 	      expr = build_nop (reference_type, expr);
6445e4b17023SJohn Marino 	      return convert_from_reference (expr);
6446e4b17023SJohn Marino 	    }
6447e4b17023SJohn Marino 	  else
6448e4b17023SJohn Marino 	    {
6449e4b17023SJohn Marino 	      expr = decay_conversion (expr);
6450e4b17023SJohn Marino 	      /* build_c_cast puts on a NOP_EXPR to make the result not an
6451e4b17023SJohn Marino 		 lvalue.  Strip such NOP_EXPRs if VALUE is being used in
6452e4b17023SJohn Marino 		 non-lvalue context.  */
6453e4b17023SJohn Marino 	      if (TREE_CODE (expr) == NOP_EXPR
6454e4b17023SJohn Marino 		  && TREE_TYPE (expr) == TREE_TYPE (TREE_OPERAND (expr, 0)))
6455e4b17023SJohn Marino 		expr = TREE_OPERAND (expr, 0);
6456e4b17023SJohn Marino 	      return build_nop (dst_type, expr);
6457e4b17023SJohn Marino 	    }
6458e4b17023SJohn Marino 	}
6459e4b17023SJohn Marino       else if (valid_p
6460e4b17023SJohn Marino 	       && !at_least_as_qualified_p (TREE_TYPE (dst_type),
6461e4b17023SJohn Marino 					    TREE_TYPE (src_type)))
6462e4b17023SJohn Marino 	check_for_casting_away_constness (src_type, dst_type, CAST_EXPR,
6463e4b17023SJohn Marino 					  complain);
6464e4b17023SJohn Marino     }
6465e4b17023SJohn Marino 
6466e4b17023SJohn Marino   if (complain & tf_error)
6467e4b17023SJohn Marino     error ("invalid const_cast from type %qT to type %qT",
6468e4b17023SJohn Marino 	   src_type, dst_type);
6469e4b17023SJohn Marino   return error_mark_node;
6470e4b17023SJohn Marino }
6471e4b17023SJohn Marino 
6472e4b17023SJohn Marino tree
build_const_cast(tree type,tree expr,tsubst_flags_t complain)6473e4b17023SJohn Marino build_const_cast (tree type, tree expr, tsubst_flags_t complain)
6474e4b17023SJohn Marino {
6475e4b17023SJohn Marino   if (type == error_mark_node || error_operand_p (expr))
6476e4b17023SJohn Marino     return error_mark_node;
6477e4b17023SJohn Marino 
6478e4b17023SJohn Marino   if (processing_template_decl)
6479e4b17023SJohn Marino     {
6480e4b17023SJohn Marino       tree t = build_min (CONST_CAST_EXPR, type, expr);
6481e4b17023SJohn Marino 
6482e4b17023SJohn Marino       if (!TREE_SIDE_EFFECTS (t)
6483e4b17023SJohn Marino 	  && type_dependent_expression_p (expr))
6484e4b17023SJohn Marino 	/* There might turn out to be side effects inside expr.  */
6485e4b17023SJohn Marino 	TREE_SIDE_EFFECTS (t) = 1;
6486e4b17023SJohn Marino       return convert_from_reference (t);
6487e4b17023SJohn Marino     }
6488e4b17023SJohn Marino 
6489e4b17023SJohn Marino   return build_const_cast_1 (type, expr, complain,
6490e4b17023SJohn Marino 			     /*valid_p=*/NULL);
6491e4b17023SJohn Marino }
6492e4b17023SJohn Marino 
6493e4b17023SJohn Marino /* Like cp_build_c_cast, but for the c-common bits.  */
6494e4b17023SJohn Marino 
6495e4b17023SJohn Marino tree
build_c_cast(location_t loc ATTRIBUTE_UNUSED,tree type,tree expr)6496e4b17023SJohn Marino build_c_cast (location_t loc ATTRIBUTE_UNUSED, tree type, tree expr)
6497e4b17023SJohn Marino {
6498e4b17023SJohn Marino   return cp_build_c_cast (type, expr, tf_warning_or_error);
6499e4b17023SJohn Marino }
6500e4b17023SJohn Marino 
6501e4b17023SJohn Marino /* Build an expression representing an explicit C-style cast to type
6502e4b17023SJohn Marino    TYPE of expression EXPR.  */
6503e4b17023SJohn Marino 
6504e4b17023SJohn Marino tree
cp_build_c_cast(tree type,tree expr,tsubst_flags_t complain)6505e4b17023SJohn Marino cp_build_c_cast (tree type, tree expr, tsubst_flags_t complain)
6506e4b17023SJohn Marino {
6507e4b17023SJohn Marino   tree value = expr;
6508e4b17023SJohn Marino   tree result;
6509e4b17023SJohn Marino   bool valid_p;
6510e4b17023SJohn Marino 
6511e4b17023SJohn Marino   if (type == error_mark_node || error_operand_p (expr))
6512e4b17023SJohn Marino     return error_mark_node;
6513e4b17023SJohn Marino 
6514e4b17023SJohn Marino   if (processing_template_decl)
6515e4b17023SJohn Marino     {
6516e4b17023SJohn Marino       tree t = build_min (CAST_EXPR, type,
6517e4b17023SJohn Marino 			  tree_cons (NULL_TREE, value, NULL_TREE));
6518e4b17023SJohn Marino       /* We don't know if it will or will not have side effects.  */
6519e4b17023SJohn Marino       TREE_SIDE_EFFECTS (t) = 1;
6520e4b17023SJohn Marino       return convert_from_reference (t);
6521e4b17023SJohn Marino     }
6522e4b17023SJohn Marino 
6523e4b17023SJohn Marino   /* Casts to a (pointer to a) specific ObjC class (or 'id' or
6524e4b17023SJohn Marino      'Class') should always be retained, because this information aids
6525e4b17023SJohn Marino      in method lookup.  */
6526e4b17023SJohn Marino   if (objc_is_object_ptr (type)
6527e4b17023SJohn Marino       && objc_is_object_ptr (TREE_TYPE (expr)))
6528e4b17023SJohn Marino     return build_nop (type, expr);
6529e4b17023SJohn Marino 
6530e4b17023SJohn Marino   /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
6531e4b17023SJohn Marino      Strip such NOP_EXPRs if VALUE is being used in non-lvalue context.  */
6532e4b17023SJohn Marino   if (TREE_CODE (type) != REFERENCE_TYPE
6533e4b17023SJohn Marino       && TREE_CODE (value) == NOP_EXPR
6534e4b17023SJohn Marino       && TREE_TYPE (value) == TREE_TYPE (TREE_OPERAND (value, 0)))
6535e4b17023SJohn Marino     value = TREE_OPERAND (value, 0);
6536e4b17023SJohn Marino 
6537e4b17023SJohn Marino   if (TREE_CODE (type) == ARRAY_TYPE)
6538e4b17023SJohn Marino     {
6539e4b17023SJohn Marino       /* Allow casting from T1* to T2[] because Cfront allows it.
6540e4b17023SJohn Marino 	 NIHCL uses it. It is not valid ISO C++ however.  */
6541e4b17023SJohn Marino       if (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE)
6542e4b17023SJohn Marino 	{
6543e4b17023SJohn Marino           if (complain & tf_error)
6544e4b17023SJohn Marino             permerror (input_location, "ISO C++ forbids casting to an array type %qT", type);
6545e4b17023SJohn Marino           else
6546e4b17023SJohn Marino             return error_mark_node;
6547e4b17023SJohn Marino 	  type = build_pointer_type (TREE_TYPE (type));
6548e4b17023SJohn Marino 	}
6549e4b17023SJohn Marino       else
6550e4b17023SJohn Marino 	{
6551e4b17023SJohn Marino           if (complain & tf_error)
6552e4b17023SJohn Marino             error ("ISO C++ forbids casting to an array type %qT", type);
6553e4b17023SJohn Marino 	  return error_mark_node;
6554e4b17023SJohn Marino 	}
6555e4b17023SJohn Marino     }
6556e4b17023SJohn Marino 
6557e4b17023SJohn Marino   if (TREE_CODE (type) == FUNCTION_TYPE
6558e4b17023SJohn Marino       || TREE_CODE (type) == METHOD_TYPE)
6559e4b17023SJohn Marino     {
6560e4b17023SJohn Marino       if (complain & tf_error)
6561e4b17023SJohn Marino         error ("invalid cast to function type %qT", type);
6562e4b17023SJohn Marino       return error_mark_node;
6563e4b17023SJohn Marino     }
6564e4b17023SJohn Marino 
6565e4b17023SJohn Marino   if (TREE_CODE (type) == POINTER_TYPE
6566e4b17023SJohn Marino       && TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE
6567e4b17023SJohn Marino       /* Casting to an integer of smaller size is an error detected elsewhere.  */
6568e4b17023SJohn Marino       && TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (value))
6569e4b17023SJohn Marino       /* Don't warn about converting any constant.  */
6570e4b17023SJohn Marino       && !TREE_CONSTANT (value))
6571e4b17023SJohn Marino     warning_at (input_location, OPT_Wint_to_pointer_cast,
6572e4b17023SJohn Marino 		"cast to pointer from integer of different size");
6573e4b17023SJohn Marino 
6574e4b17023SJohn Marino   /* A C-style cast can be a const_cast.  */
6575e4b17023SJohn Marino   result = build_const_cast_1 (type, value, complain & tf_warning,
6576e4b17023SJohn Marino 			       &valid_p);
6577e4b17023SJohn Marino   if (valid_p)
6578e4b17023SJohn Marino     return result;
6579e4b17023SJohn Marino 
6580e4b17023SJohn Marino   /* Or a static cast.  */
6581e4b17023SJohn Marino   result = build_static_cast_1 (type, value, /*c_cast_p=*/true,
6582e4b17023SJohn Marino 				&valid_p, complain);
6583e4b17023SJohn Marino   /* Or a reinterpret_cast.  */
6584e4b17023SJohn Marino   if (!valid_p)
6585e4b17023SJohn Marino     result = build_reinterpret_cast_1 (type, value, /*c_cast_p=*/true,
6586e4b17023SJohn Marino 				       &valid_p, complain);
6587e4b17023SJohn Marino   /* The static_cast or reinterpret_cast may be followed by a
6588e4b17023SJohn Marino      const_cast.  */
6589e4b17023SJohn Marino   if (valid_p
6590e4b17023SJohn Marino       /* A valid cast may result in errors if, for example, a
6591e4b17023SJohn Marino 	 conversion to am ambiguous base class is required.  */
6592e4b17023SJohn Marino       && !error_operand_p (result))
6593e4b17023SJohn Marino     {
6594e4b17023SJohn Marino       tree result_type;
6595e4b17023SJohn Marino 
6596e4b17023SJohn Marino       /* Non-class rvalues always have cv-unqualified type.  */
6597e4b17023SJohn Marino       if (!CLASS_TYPE_P (type))
6598e4b17023SJohn Marino 	type = TYPE_MAIN_VARIANT (type);
6599e4b17023SJohn Marino       result_type = TREE_TYPE (result);
6600e4b17023SJohn Marino       if (!CLASS_TYPE_P (result_type) && TREE_CODE (type) != REFERENCE_TYPE)
6601e4b17023SJohn Marino 	result_type = TYPE_MAIN_VARIANT (result_type);
6602e4b17023SJohn Marino       /* If the type of RESULT does not match TYPE, perform a
6603e4b17023SJohn Marino 	 const_cast to make it match.  If the static_cast or
6604e4b17023SJohn Marino 	 reinterpret_cast succeeded, we will differ by at most
6605e4b17023SJohn Marino 	 cv-qualification, so the follow-on const_cast is guaranteed
6606e4b17023SJohn Marino 	 to succeed.  */
6607e4b17023SJohn Marino       if (!same_type_p (non_reference (type), non_reference (result_type)))
6608e4b17023SJohn Marino 	{
6609e4b17023SJohn Marino 	  result = build_const_cast_1 (type, result, false, &valid_p);
6610e4b17023SJohn Marino 	  gcc_assert (valid_p);
6611e4b17023SJohn Marino 	}
6612e4b17023SJohn Marino       return result;
6613e4b17023SJohn Marino     }
6614e4b17023SJohn Marino 
6615e4b17023SJohn Marino   return error_mark_node;
6616e4b17023SJohn Marino }
6617e4b17023SJohn Marino 
6618e4b17023SJohn Marino /* For use from the C common bits.  */
6619e4b17023SJohn Marino tree
build_modify_expr(location_t location ATTRIBUTE_UNUSED,tree lhs,tree lhs_origtype ATTRIBUTE_UNUSED,enum tree_code modifycode,location_t rhs_location ATTRIBUTE_UNUSED,tree rhs,tree rhs_origtype ATTRIBUTE_UNUSED)6620e4b17023SJohn Marino build_modify_expr (location_t location ATTRIBUTE_UNUSED,
6621e4b17023SJohn Marino 		   tree lhs, tree lhs_origtype ATTRIBUTE_UNUSED,
6622e4b17023SJohn Marino 		   enum tree_code modifycode,
6623e4b17023SJohn Marino 		   location_t rhs_location ATTRIBUTE_UNUSED, tree rhs,
6624e4b17023SJohn Marino 		   tree rhs_origtype ATTRIBUTE_UNUSED)
6625e4b17023SJohn Marino {
6626e4b17023SJohn Marino   return cp_build_modify_expr (lhs, modifycode, rhs, tf_warning_or_error);
6627e4b17023SJohn Marino }
6628e4b17023SJohn Marino 
6629e4b17023SJohn Marino /* Build an assignment expression of lvalue LHS from value RHS.
6630e4b17023SJohn Marino    MODIFYCODE is the code for a binary operator that we use
6631e4b17023SJohn Marino    to combine the old value of LHS with RHS to get the new value.
6632e4b17023SJohn Marino    Or else MODIFYCODE is NOP_EXPR meaning do a simple assignment.
6633e4b17023SJohn Marino 
6634e4b17023SJohn Marino    C++: If MODIFYCODE is INIT_EXPR, then leave references unbashed.  */
6635e4b17023SJohn Marino 
6636e4b17023SJohn Marino tree
cp_build_modify_expr(tree lhs,enum tree_code modifycode,tree rhs,tsubst_flags_t complain)6637e4b17023SJohn Marino cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
6638e4b17023SJohn Marino 		      tsubst_flags_t complain)
6639e4b17023SJohn Marino {
6640e4b17023SJohn Marino   tree result;
6641e4b17023SJohn Marino   tree newrhs = rhs;
6642e4b17023SJohn Marino   tree lhstype = TREE_TYPE (lhs);
6643e4b17023SJohn Marino   tree olhstype = lhstype;
6644e4b17023SJohn Marino   bool plain_assign = (modifycode == NOP_EXPR);
6645e4b17023SJohn Marino 
6646e4b17023SJohn Marino   /* Avoid duplicate error messages from operands that had errors.  */
6647e4b17023SJohn Marino   if (error_operand_p (lhs) || error_operand_p (rhs))
6648e4b17023SJohn Marino     return error_mark_node;
6649e4b17023SJohn Marino 
6650e4b17023SJohn Marino   /* Handle control structure constructs used as "lvalues".  */
6651e4b17023SJohn Marino   switch (TREE_CODE (lhs))
6652e4b17023SJohn Marino     {
6653e4b17023SJohn Marino       /* Handle --foo = 5; as these are valid constructs in C++.  */
6654e4b17023SJohn Marino     case PREDECREMENT_EXPR:
6655e4b17023SJohn Marino     case PREINCREMENT_EXPR:
6656e4b17023SJohn Marino       if (TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0)))
6657e4b17023SJohn Marino 	lhs = build2 (TREE_CODE (lhs), TREE_TYPE (lhs),
6658e4b17023SJohn Marino 		      stabilize_reference (TREE_OPERAND (lhs, 0)),
6659e4b17023SJohn Marino 		      TREE_OPERAND (lhs, 1));
6660e4b17023SJohn Marino       newrhs = cp_build_modify_expr (TREE_OPERAND (lhs, 0),
6661e4b17023SJohn Marino 				     modifycode, rhs, complain);
6662e4b17023SJohn Marino       if (newrhs == error_mark_node)
6663e4b17023SJohn Marino 	return error_mark_node;
6664e4b17023SJohn Marino       return build2 (COMPOUND_EXPR, lhstype, lhs, newrhs);
6665e4b17023SJohn Marino 
6666e4b17023SJohn Marino       /* Handle (a, b) used as an "lvalue".  */
6667e4b17023SJohn Marino     case COMPOUND_EXPR:
6668e4b17023SJohn Marino       newrhs = cp_build_modify_expr (TREE_OPERAND (lhs, 1),
6669e4b17023SJohn Marino 				     modifycode, rhs, complain);
6670e4b17023SJohn Marino       if (newrhs == error_mark_node)
6671e4b17023SJohn Marino 	return error_mark_node;
6672e4b17023SJohn Marino       return build2 (COMPOUND_EXPR, lhstype,
6673e4b17023SJohn Marino 		     TREE_OPERAND (lhs, 0), newrhs);
6674e4b17023SJohn Marino 
6675e4b17023SJohn Marino     case MODIFY_EXPR:
6676e4b17023SJohn Marino       if (TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0)))
6677e4b17023SJohn Marino 	lhs = build2 (TREE_CODE (lhs), TREE_TYPE (lhs),
6678e4b17023SJohn Marino 		      stabilize_reference (TREE_OPERAND (lhs, 0)),
6679e4b17023SJohn Marino 		      TREE_OPERAND (lhs, 1));
6680e4b17023SJohn Marino       newrhs = cp_build_modify_expr (TREE_OPERAND (lhs, 0), modifycode, rhs,
6681e4b17023SJohn Marino 				     complain);
6682e4b17023SJohn Marino       if (newrhs == error_mark_node)
6683e4b17023SJohn Marino 	return error_mark_node;
6684e4b17023SJohn Marino       return build2 (COMPOUND_EXPR, lhstype, lhs, newrhs);
6685e4b17023SJohn Marino 
6686e4b17023SJohn Marino     case MIN_EXPR:
6687e4b17023SJohn Marino     case MAX_EXPR:
6688e4b17023SJohn Marino       /* MIN_EXPR and MAX_EXPR are currently only permitted as lvalues,
6689e4b17023SJohn Marino 	 when neither operand has side-effects.  */
6690e4b17023SJohn Marino       if (!lvalue_or_else (lhs, lv_assign, complain))
6691e4b17023SJohn Marino 	return error_mark_node;
6692e4b17023SJohn Marino 
6693e4b17023SJohn Marino       gcc_assert (!TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0))
6694e4b17023SJohn Marino 		  && !TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 1)));
6695e4b17023SJohn Marino 
6696e4b17023SJohn Marino       lhs = build3 (COND_EXPR, TREE_TYPE (lhs),
6697e4b17023SJohn Marino 		    build2 (TREE_CODE (lhs) == MIN_EXPR ? LE_EXPR : GE_EXPR,
6698e4b17023SJohn Marino 			    boolean_type_node,
6699e4b17023SJohn Marino 			    TREE_OPERAND (lhs, 0),
6700e4b17023SJohn Marino 			    TREE_OPERAND (lhs, 1)),
6701e4b17023SJohn Marino 		    TREE_OPERAND (lhs, 0),
6702e4b17023SJohn Marino 		    TREE_OPERAND (lhs, 1));
6703e4b17023SJohn Marino       /* Fall through.  */
6704e4b17023SJohn Marino 
6705e4b17023SJohn Marino       /* Handle (a ? b : c) used as an "lvalue".  */
6706e4b17023SJohn Marino     case COND_EXPR:
6707e4b17023SJohn Marino       {
6708e4b17023SJohn Marino 	/* Produce (a ? (b = rhs) : (c = rhs))
6709e4b17023SJohn Marino 	   except that the RHS goes through a save-expr
6710e4b17023SJohn Marino 	   so the code to compute it is only emitted once.  */
6711e4b17023SJohn Marino 	tree cond;
6712e4b17023SJohn Marino 	tree preeval = NULL_TREE;
6713e4b17023SJohn Marino 
6714e4b17023SJohn Marino 	if (VOID_TYPE_P (TREE_TYPE (rhs)))
6715e4b17023SJohn Marino 	  {
6716e4b17023SJohn Marino 	    if (complain & tf_error)
6717e4b17023SJohn Marino 	      error ("void value not ignored as it ought to be");
6718e4b17023SJohn Marino 	    return error_mark_node;
6719e4b17023SJohn Marino 	  }
6720e4b17023SJohn Marino 
6721e4b17023SJohn Marino 	rhs = stabilize_expr (rhs, &preeval);
6722e4b17023SJohn Marino 
6723e4b17023SJohn Marino 	/* Check this here to avoid odd errors when trying to convert
6724e4b17023SJohn Marino 	   a throw to the type of the COND_EXPR.  */
6725e4b17023SJohn Marino 	if (!lvalue_or_else (lhs, lv_assign, complain))
6726e4b17023SJohn Marino 	  return error_mark_node;
6727e4b17023SJohn Marino 
6728e4b17023SJohn Marino 	cond = build_conditional_expr
6729e4b17023SJohn Marino 	  (TREE_OPERAND (lhs, 0),
6730e4b17023SJohn Marino 	   cp_build_modify_expr (TREE_OPERAND (lhs, 1),
6731e4b17023SJohn Marino 				 modifycode, rhs, complain),
6732e4b17023SJohn Marino 	   cp_build_modify_expr (TREE_OPERAND (lhs, 2),
6733e4b17023SJohn Marino 				 modifycode, rhs, complain),
6734e4b17023SJohn Marino            complain);
6735e4b17023SJohn Marino 
6736e4b17023SJohn Marino 	if (cond == error_mark_node)
6737e4b17023SJohn Marino 	  return cond;
6738e4b17023SJohn Marino 	/* Make sure the code to compute the rhs comes out
6739e4b17023SJohn Marino 	   before the split.  */
6740e4b17023SJohn Marino 	if (preeval)
6741e4b17023SJohn Marino 	  cond = build2 (COMPOUND_EXPR, TREE_TYPE (lhs), preeval, cond);
6742e4b17023SJohn Marino 	return cond;
6743e4b17023SJohn Marino       }
6744e4b17023SJohn Marino 
6745e4b17023SJohn Marino     default:
6746e4b17023SJohn Marino       break;
6747e4b17023SJohn Marino     }
6748e4b17023SJohn Marino 
6749e4b17023SJohn Marino   if (modifycode == INIT_EXPR)
6750e4b17023SJohn Marino     {
6751e4b17023SJohn Marino       if (BRACE_ENCLOSED_INITIALIZER_P (rhs))
6752e4b17023SJohn Marino 	/* Do the default thing.  */;
6753e4b17023SJohn Marino       else if (TREE_CODE (rhs) == CONSTRUCTOR)
6754e4b17023SJohn Marino 	{
6755e4b17023SJohn Marino 	  /* Compound literal.  */
6756e4b17023SJohn Marino 	  if (! same_type_p (TREE_TYPE (rhs), lhstype))
6757e4b17023SJohn Marino 	    /* Call convert to generate an error; see PR 11063.  */
6758e4b17023SJohn Marino 	    rhs = convert (lhstype, rhs);
6759e4b17023SJohn Marino 	  result = build2 (INIT_EXPR, lhstype, lhs, rhs);
6760e4b17023SJohn Marino 	  TREE_SIDE_EFFECTS (result) = 1;
6761e4b17023SJohn Marino 	  return result;
6762e4b17023SJohn Marino 	}
6763e4b17023SJohn Marino       else if (! MAYBE_CLASS_TYPE_P (lhstype))
6764e4b17023SJohn Marino 	/* Do the default thing.  */;
6765e4b17023SJohn Marino       else
6766e4b17023SJohn Marino 	{
6767e4b17023SJohn Marino 	  VEC(tree,gc) *rhs_vec = make_tree_vector_single (rhs);
6768e4b17023SJohn Marino 	  result = build_special_member_call (lhs, complete_ctor_identifier,
6769e4b17023SJohn Marino 					      &rhs_vec, lhstype, LOOKUP_NORMAL,
6770e4b17023SJohn Marino                                               complain);
6771e4b17023SJohn Marino 	  release_tree_vector (rhs_vec);
6772e4b17023SJohn Marino 	  if (result == NULL_TREE)
6773e4b17023SJohn Marino 	    return error_mark_node;
6774e4b17023SJohn Marino 	  return result;
6775e4b17023SJohn Marino 	}
6776e4b17023SJohn Marino     }
6777e4b17023SJohn Marino   else
6778e4b17023SJohn Marino     {
6779e4b17023SJohn Marino       lhs = require_complete_type_sfinae (lhs, complain);
6780e4b17023SJohn Marino       if (lhs == error_mark_node)
6781e4b17023SJohn Marino 	return error_mark_node;
6782e4b17023SJohn Marino 
6783e4b17023SJohn Marino       if (modifycode == NOP_EXPR)
6784e4b17023SJohn Marino 	{
6785e4b17023SJohn Marino 	  if (c_dialect_objc ())
6786e4b17023SJohn Marino 	    {
6787e4b17023SJohn Marino 	      result = objc_maybe_build_modify_expr (lhs, rhs);
6788e4b17023SJohn Marino 	      if (result)
6789e4b17023SJohn Marino 		return result;
6790e4b17023SJohn Marino 	    }
6791e4b17023SJohn Marino 
6792e4b17023SJohn Marino 	  /* `operator=' is not an inheritable operator.  */
6793e4b17023SJohn Marino 	  if (! MAYBE_CLASS_TYPE_P (lhstype))
6794e4b17023SJohn Marino 	    /* Do the default thing.  */;
6795e4b17023SJohn Marino 	  else
6796e4b17023SJohn Marino 	    {
6797e4b17023SJohn Marino 	      result = build_new_op (MODIFY_EXPR, LOOKUP_NORMAL,
6798e4b17023SJohn Marino 				     lhs, rhs, make_node (NOP_EXPR),
6799e4b17023SJohn Marino 				     /*overload=*/NULL,
6800e4b17023SJohn Marino 				     complain);
6801e4b17023SJohn Marino 	      if (result == NULL_TREE)
6802e4b17023SJohn Marino 		return error_mark_node;
6803e4b17023SJohn Marino 	      return result;
6804e4b17023SJohn Marino 	    }
6805e4b17023SJohn Marino 	  lhstype = olhstype;
6806e4b17023SJohn Marino 	}
6807e4b17023SJohn Marino       else
6808e4b17023SJohn Marino 	{
6809e4b17023SJohn Marino 	  tree init = NULL_TREE;
6810e4b17023SJohn Marino 
6811e4b17023SJohn Marino 	  /* A binary op has been requested.  Combine the old LHS
6812e4b17023SJohn Marino 	     value with the RHS producing the value we should actually
6813e4b17023SJohn Marino 	     store into the LHS.  */
6814e4b17023SJohn Marino 	  gcc_assert (!((TREE_CODE (lhstype) == REFERENCE_TYPE
6815e4b17023SJohn Marino 			 && MAYBE_CLASS_TYPE_P (TREE_TYPE (lhstype)))
6816e4b17023SJohn Marino 			|| MAYBE_CLASS_TYPE_P (lhstype)));
6817e4b17023SJohn Marino 
6818e4b17023SJohn Marino 	  /* Preevaluate the RHS to make sure its evaluation is complete
6819e4b17023SJohn Marino 	     before the lvalue-to-rvalue conversion of the LHS:
6820e4b17023SJohn Marino 
6821e4b17023SJohn Marino 	     [expr.ass] With respect to an indeterminately-sequenced
6822e4b17023SJohn Marino 	     function call, the operation of a compound assignment is a
6823e4b17023SJohn Marino 	     single evaluation. [ Note: Therefore, a function call shall
6824e4b17023SJohn Marino 	     not intervene between the lvalue-to-rvalue conversion and the
6825e4b17023SJohn Marino 	     side effect associated with any single compound assignment
6826e4b17023SJohn Marino 	     operator. -- end note ]  */
6827e4b17023SJohn Marino 	  lhs = stabilize_reference (lhs);
6828e4b17023SJohn Marino 	  if (TREE_SIDE_EFFECTS (rhs))
6829e4b17023SJohn Marino 	    rhs = mark_rvalue_use (rhs);
6830e4b17023SJohn Marino 	  rhs = stabilize_expr (rhs, &init);
6831e4b17023SJohn Marino 	  newrhs = cp_build_binary_op (input_location,
6832e4b17023SJohn Marino 				       modifycode, lhs, rhs,
6833e4b17023SJohn Marino 				       complain);
6834e4b17023SJohn Marino 	  if (newrhs == error_mark_node)
6835e4b17023SJohn Marino 	    {
6836e4b17023SJohn Marino 	      if (complain & tf_error)
6837e4b17023SJohn Marino 		error ("  in evaluation of %<%Q(%#T, %#T)%>", modifycode,
6838e4b17023SJohn Marino 		       TREE_TYPE (lhs), TREE_TYPE (rhs));
6839e4b17023SJohn Marino 	      return error_mark_node;
6840e4b17023SJohn Marino 	    }
6841e4b17023SJohn Marino 
6842e4b17023SJohn Marino 	  if (init)
6843e4b17023SJohn Marino 	    newrhs = build2 (COMPOUND_EXPR, TREE_TYPE (newrhs), init, newrhs);
6844e4b17023SJohn Marino 
6845e4b17023SJohn Marino 	  /* Now it looks like a plain assignment.  */
6846e4b17023SJohn Marino 	  modifycode = NOP_EXPR;
6847e4b17023SJohn Marino 	  if (c_dialect_objc ())
6848e4b17023SJohn Marino 	    {
6849e4b17023SJohn Marino 	      result = objc_maybe_build_modify_expr (lhs, newrhs);
6850e4b17023SJohn Marino 	      if (result)
6851e4b17023SJohn Marino 		return result;
6852e4b17023SJohn Marino 	    }
6853e4b17023SJohn Marino 	}
6854e4b17023SJohn Marino       gcc_assert (TREE_CODE (lhstype) != REFERENCE_TYPE);
6855e4b17023SJohn Marino       gcc_assert (TREE_CODE (TREE_TYPE (newrhs)) != REFERENCE_TYPE);
6856e4b17023SJohn Marino     }
6857e4b17023SJohn Marino 
6858e4b17023SJohn Marino   /* The left-hand side must be an lvalue.  */
6859e4b17023SJohn Marino   if (!lvalue_or_else (lhs, lv_assign, complain))
6860e4b17023SJohn Marino     return error_mark_node;
6861e4b17023SJohn Marino 
6862e4b17023SJohn Marino   /* Warn about modifying something that is `const'.  Don't warn if
6863e4b17023SJohn Marino      this is initialization.  */
6864e4b17023SJohn Marino   if (modifycode != INIT_EXPR
6865e4b17023SJohn Marino       && (TREE_READONLY (lhs) || CP_TYPE_CONST_P (lhstype)
6866e4b17023SJohn Marino 	  /* Functions are not modifiable, even though they are
6867e4b17023SJohn Marino 	     lvalues.  */
6868e4b17023SJohn Marino 	  || TREE_CODE (TREE_TYPE (lhs)) == FUNCTION_TYPE
6869e4b17023SJohn Marino 	  || TREE_CODE (TREE_TYPE (lhs)) == METHOD_TYPE
6870e4b17023SJohn Marino 	  /* If it's an aggregate and any field is const, then it is
6871e4b17023SJohn Marino 	     effectively const.  */
6872e4b17023SJohn Marino 	  || (CLASS_TYPE_P (lhstype)
6873e4b17023SJohn Marino 	      && C_TYPE_FIELDS_READONLY (lhstype))))
6874e4b17023SJohn Marino     {
6875e4b17023SJohn Marino       if (complain & tf_error)
6876e4b17023SJohn Marino 	cxx_readonly_error (lhs, lv_assign);
6877e4b17023SJohn Marino       else
6878e4b17023SJohn Marino 	return error_mark_node;
6879e4b17023SJohn Marino     }
6880e4b17023SJohn Marino 
6881e4b17023SJohn Marino   /* If storing into a structure or union member, it may have been given a
6882e4b17023SJohn Marino      lowered bitfield type.  We need to convert to the declared type first,
6883e4b17023SJohn Marino      so retrieve it now.  */
6884e4b17023SJohn Marino 
6885e4b17023SJohn Marino   olhstype = unlowered_expr_type (lhs);
6886e4b17023SJohn Marino 
6887e4b17023SJohn Marino   /* Convert new value to destination type.  */
6888e4b17023SJohn Marino 
6889e4b17023SJohn Marino   if (TREE_CODE (lhstype) == ARRAY_TYPE)
6890e4b17023SJohn Marino     {
6891e4b17023SJohn Marino       int from_array;
6892e4b17023SJohn Marino 
6893e4b17023SJohn Marino       if (BRACE_ENCLOSED_INITIALIZER_P (newrhs))
6894e4b17023SJohn Marino 	{
6895e4b17023SJohn Marino 	  if (modifycode != INIT_EXPR)
6896e4b17023SJohn Marino 	    {
6897e4b17023SJohn Marino 	      if (complain & tf_error)
6898e4b17023SJohn Marino 		error ("assigning to an array from an initializer list");
6899e4b17023SJohn Marino 	      return error_mark_node;
6900e4b17023SJohn Marino 	    }
6901e4b17023SJohn Marino 	  if (check_array_initializer (lhs, lhstype, newrhs))
6902e4b17023SJohn Marino 	    return error_mark_node;
6903e4b17023SJohn Marino 	  newrhs = digest_init (lhstype, newrhs, complain);
6904e4b17023SJohn Marino 	  if (newrhs == error_mark_node)
6905e4b17023SJohn Marino 	    return error_mark_node;
6906e4b17023SJohn Marino 	}
6907e4b17023SJohn Marino 
6908e4b17023SJohn Marino       else if (!same_or_base_type_p (TYPE_MAIN_VARIANT (lhstype),
6909e4b17023SJohn Marino 				     TYPE_MAIN_VARIANT (TREE_TYPE (newrhs))))
6910e4b17023SJohn Marino 	{
6911e4b17023SJohn Marino 	  if (complain & tf_error)
6912e4b17023SJohn Marino 	    error ("incompatible types in assignment of %qT to %qT",
6913e4b17023SJohn Marino 		   TREE_TYPE (rhs), lhstype);
6914e4b17023SJohn Marino 	  return error_mark_node;
6915e4b17023SJohn Marino 	}
6916e4b17023SJohn Marino 
6917e4b17023SJohn Marino       /* Allow array assignment in compiler-generated code.  */
6918e4b17023SJohn Marino       else if (!current_function_decl
6919e4b17023SJohn Marino 	       || !DECL_DEFAULTED_FN (current_function_decl))
6920e4b17023SJohn Marino 	{
6921e4b17023SJohn Marino           /* This routine is used for both initialization and assignment.
6922e4b17023SJohn Marino              Make sure the diagnostic message differentiates the context.  */
6923e4b17023SJohn Marino 	  if (complain & tf_error)
6924e4b17023SJohn Marino 	    {
6925e4b17023SJohn Marino 	      if (modifycode == INIT_EXPR)
6926e4b17023SJohn Marino 		error ("array used as initializer");
6927e4b17023SJohn Marino 	      else
6928e4b17023SJohn Marino 		error ("invalid array assignment");
6929e4b17023SJohn Marino 	    }
6930e4b17023SJohn Marino 	  return error_mark_node;
6931e4b17023SJohn Marino 	}
6932e4b17023SJohn Marino 
6933e4b17023SJohn Marino       from_array = TREE_CODE (TREE_TYPE (newrhs)) == ARRAY_TYPE
6934e4b17023SJohn Marino 		   ? 1 + (modifycode != INIT_EXPR): 0;
6935e4b17023SJohn Marino       return build_vec_init (lhs, NULL_TREE, newrhs,
6936e4b17023SJohn Marino 			     /*explicit_value_init_p=*/false,
6937e4b17023SJohn Marino 			     from_array, complain);
6938e4b17023SJohn Marino     }
6939e4b17023SJohn Marino 
6940e4b17023SJohn Marino   if (modifycode == INIT_EXPR)
6941e4b17023SJohn Marino     /* Calls with INIT_EXPR are all direct-initialization, so don't set
6942e4b17023SJohn Marino        LOOKUP_ONLYCONVERTING.  */
6943e4b17023SJohn Marino     newrhs = convert_for_initialization (lhs, olhstype, newrhs, LOOKUP_NORMAL,
6944e4b17023SJohn Marino 					 ICR_INIT, NULL_TREE, 0,
6945e4b17023SJohn Marino                                          complain);
6946e4b17023SJohn Marino   else
6947e4b17023SJohn Marino     newrhs = convert_for_assignment (olhstype, newrhs, ICR_ASSIGN,
6948e4b17023SJohn Marino 				     NULL_TREE, 0, complain, LOOKUP_IMPLICIT);
6949e4b17023SJohn Marino 
6950e4b17023SJohn Marino   if (!same_type_p (lhstype, olhstype))
6951e4b17023SJohn Marino     newrhs = cp_convert_and_check (lhstype, newrhs);
6952e4b17023SJohn Marino 
6953e4b17023SJohn Marino   if (modifycode != INIT_EXPR)
6954e4b17023SJohn Marino     {
6955e4b17023SJohn Marino       if (TREE_CODE (newrhs) == CALL_EXPR
6956e4b17023SJohn Marino 	  && TYPE_NEEDS_CONSTRUCTING (lhstype))
6957e4b17023SJohn Marino 	newrhs = build_cplus_new (lhstype, newrhs, complain);
6958e4b17023SJohn Marino 
6959e4b17023SJohn Marino       /* Can't initialize directly from a TARGET_EXPR, since that would
6960e4b17023SJohn Marino 	 cause the lhs to be constructed twice, and possibly result in
6961e4b17023SJohn Marino 	 accidental self-initialization.  So we force the TARGET_EXPR to be
6962e4b17023SJohn Marino 	 expanded without a target.  */
6963e4b17023SJohn Marino       if (TREE_CODE (newrhs) == TARGET_EXPR)
6964e4b17023SJohn Marino 	newrhs = build2 (COMPOUND_EXPR, TREE_TYPE (newrhs), newrhs,
6965e4b17023SJohn Marino 			 TREE_OPERAND (newrhs, 0));
6966e4b17023SJohn Marino     }
6967e4b17023SJohn Marino 
6968e4b17023SJohn Marino   if (newrhs == error_mark_node)
6969e4b17023SJohn Marino     return error_mark_node;
6970e4b17023SJohn Marino 
6971e4b17023SJohn Marino   if (c_dialect_objc () && flag_objc_gc)
6972e4b17023SJohn Marino     {
6973e4b17023SJohn Marino       result = objc_generate_write_barrier (lhs, modifycode, newrhs);
6974e4b17023SJohn Marino 
6975e4b17023SJohn Marino       if (result)
6976e4b17023SJohn Marino 	return result;
6977e4b17023SJohn Marino     }
6978e4b17023SJohn Marino 
6979e4b17023SJohn Marino   result = build2 (modifycode == NOP_EXPR ? MODIFY_EXPR : INIT_EXPR,
6980e4b17023SJohn Marino 		   lhstype, lhs, newrhs);
6981e4b17023SJohn Marino 
6982e4b17023SJohn Marino   TREE_SIDE_EFFECTS (result) = 1;
6983e4b17023SJohn Marino   if (!plain_assign)
6984e4b17023SJohn Marino     TREE_NO_WARNING (result) = 1;
6985e4b17023SJohn Marino 
6986e4b17023SJohn Marino   return result;
6987e4b17023SJohn Marino }
6988e4b17023SJohn Marino 
6989e4b17023SJohn Marino tree
build_x_modify_expr(tree lhs,enum tree_code modifycode,tree rhs,tsubst_flags_t complain)6990e4b17023SJohn Marino build_x_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
6991e4b17023SJohn Marino 		     tsubst_flags_t complain)
6992e4b17023SJohn Marino {
6993e4b17023SJohn Marino   if (processing_template_decl)
6994e4b17023SJohn Marino     return build_min_nt (MODOP_EXPR, lhs,
6995e4b17023SJohn Marino 			 build_min_nt (modifycode, NULL_TREE, NULL_TREE), rhs);
6996e4b17023SJohn Marino 
6997e4b17023SJohn Marino   if (modifycode != NOP_EXPR)
6998e4b17023SJohn Marino     {
6999e4b17023SJohn Marino       tree rval = build_new_op (MODIFY_EXPR, LOOKUP_NORMAL, lhs, rhs,
7000e4b17023SJohn Marino 				make_node (modifycode),
7001e4b17023SJohn Marino 				/*overload=*/NULL,
7002e4b17023SJohn Marino 				complain);
7003e4b17023SJohn Marino       if (rval)
7004e4b17023SJohn Marino 	{
7005e4b17023SJohn Marino 	  TREE_NO_WARNING (rval) = 1;
7006e4b17023SJohn Marino 	  return rval;
7007e4b17023SJohn Marino 	}
7008e4b17023SJohn Marino     }
7009e4b17023SJohn Marino   return cp_build_modify_expr (lhs, modifycode, rhs, complain);
7010e4b17023SJohn Marino }
7011e4b17023SJohn Marino 
7012e4b17023SJohn Marino /* Helper function for get_delta_difference which assumes FROM is a base
7013e4b17023SJohn Marino    class of TO.  Returns a delta for the conversion of pointer-to-member
7014e4b17023SJohn Marino    of FROM to pointer-to-member of TO.  If the conversion is invalid and
7015e4b17023SJohn Marino    tf_error is not set in COMPLAIN returns error_mark_node, otherwise
7016e4b17023SJohn Marino    returns zero.  If FROM is not a base class of TO, returns NULL_TREE.
7017e4b17023SJohn Marino    If C_CAST_P is true, this conversion is taking place as part of a
7018e4b17023SJohn Marino    C-style cast.  */
7019e4b17023SJohn Marino 
7020e4b17023SJohn Marino static tree
get_delta_difference_1(tree from,tree to,bool c_cast_p,tsubst_flags_t complain)7021e4b17023SJohn Marino get_delta_difference_1 (tree from, tree to, bool c_cast_p,
7022e4b17023SJohn Marino 			tsubst_flags_t complain)
7023e4b17023SJohn Marino {
7024e4b17023SJohn Marino   tree binfo;
7025e4b17023SJohn Marino   base_kind kind;
7026e4b17023SJohn Marino   base_access access = c_cast_p ? ba_unique : ba_check;
7027e4b17023SJohn Marino 
7028e4b17023SJohn Marino   /* Note: ba_quiet does not distinguish between access control and
7029e4b17023SJohn Marino      ambiguity.  */
7030e4b17023SJohn Marino   if (!(complain & tf_error))
7031e4b17023SJohn Marino     access |= ba_quiet;
7032e4b17023SJohn Marino 
7033e4b17023SJohn Marino   binfo = lookup_base (to, from, access, &kind);
7034e4b17023SJohn Marino 
7035e4b17023SJohn Marino   if (kind == bk_inaccessible || kind == bk_ambig)
7036e4b17023SJohn Marino     {
7037e4b17023SJohn Marino       if (!(complain & tf_error))
7038e4b17023SJohn Marino 	return error_mark_node;
7039e4b17023SJohn Marino 
7040e4b17023SJohn Marino       error ("   in pointer to member function conversion");
7041e4b17023SJohn Marino       return size_zero_node;
7042e4b17023SJohn Marino     }
7043e4b17023SJohn Marino   else if (binfo)
7044e4b17023SJohn Marino     {
7045e4b17023SJohn Marino       if (kind != bk_via_virtual)
7046e4b17023SJohn Marino 	return BINFO_OFFSET (binfo);
7047e4b17023SJohn Marino       else
7048e4b17023SJohn Marino 	/* FROM is a virtual base class of TO.  Issue an error or warning
7049e4b17023SJohn Marino 	   depending on whether or not this is a reinterpret cast.  */
7050e4b17023SJohn Marino 	{
7051e4b17023SJohn Marino 	  if (!(complain & tf_error))
7052e4b17023SJohn Marino 	    return error_mark_node;
7053e4b17023SJohn Marino 
7054e4b17023SJohn Marino 	  error ("pointer to member conversion via virtual base %qT",
7055e4b17023SJohn Marino 		 BINFO_TYPE (binfo_from_vbase (binfo)));
7056e4b17023SJohn Marino 
7057e4b17023SJohn Marino 	  return size_zero_node;
7058e4b17023SJohn Marino 	}
7059e4b17023SJohn Marino       }
7060e4b17023SJohn Marino   else
7061e4b17023SJohn Marino     return NULL_TREE;
7062e4b17023SJohn Marino }
7063e4b17023SJohn Marino 
7064e4b17023SJohn Marino /* Get difference in deltas for different pointer to member function
7065e4b17023SJohn Marino    types.  If the conversion is invalid and tf_error is not set in
7066e4b17023SJohn Marino    COMPLAIN, returns error_mark_node, otherwise returns an integer
7067e4b17023SJohn Marino    constant of type PTRDIFF_TYPE_NODE and its value is zero if the
7068e4b17023SJohn Marino    conversion is invalid.  If ALLOW_INVERSE_P is true, then allow reverse
7069e4b17023SJohn Marino    conversions as well.  If C_CAST_P is true this conversion is taking
7070e4b17023SJohn Marino    place as part of a C-style cast.
7071e4b17023SJohn Marino 
7072e4b17023SJohn Marino    Note that the naming of FROM and TO is kind of backwards; the return
7073e4b17023SJohn Marino    value is what we add to a TO in order to get a FROM.  They are named
7074e4b17023SJohn Marino    this way because we call this function to find out how to convert from
7075e4b17023SJohn Marino    a pointer to member of FROM to a pointer to member of TO.  */
7076e4b17023SJohn Marino 
7077e4b17023SJohn Marino static tree
get_delta_difference(tree from,tree to,bool allow_inverse_p,bool c_cast_p,tsubst_flags_t complain)7078e4b17023SJohn Marino get_delta_difference (tree from, tree to,
7079e4b17023SJohn Marino 		      bool allow_inverse_p,
7080e4b17023SJohn Marino 		      bool c_cast_p, tsubst_flags_t complain)
7081e4b17023SJohn Marino {
7082e4b17023SJohn Marino   tree result;
7083e4b17023SJohn Marino 
7084e4b17023SJohn Marino   if (same_type_ignoring_top_level_qualifiers_p (from, to))
7085e4b17023SJohn Marino     /* Pointer to member of incomplete class is permitted*/
7086e4b17023SJohn Marino     result = size_zero_node;
7087e4b17023SJohn Marino   else
7088e4b17023SJohn Marino     result = get_delta_difference_1 (from, to, c_cast_p, complain);
7089e4b17023SJohn Marino 
7090e4b17023SJohn Marino   if (result == error_mark_node)
7091e4b17023SJohn Marino     return error_mark_node;
7092e4b17023SJohn Marino 
7093e4b17023SJohn Marino   if (!result)
7094e4b17023SJohn Marino   {
7095e4b17023SJohn Marino     if (!allow_inverse_p)
7096e4b17023SJohn Marino       {
7097e4b17023SJohn Marino 	if (!(complain & tf_error))
7098e4b17023SJohn Marino 	  return error_mark_node;
7099e4b17023SJohn Marino 
7100e4b17023SJohn Marino 	error_not_base_type (from, to);
7101e4b17023SJohn Marino 	error ("   in pointer to member conversion");
7102e4b17023SJohn Marino       	result = size_zero_node;
7103e4b17023SJohn Marino       }
7104e4b17023SJohn Marino     else
7105e4b17023SJohn Marino       {
7106e4b17023SJohn Marino 	result = get_delta_difference_1 (to, from, c_cast_p, complain);
7107e4b17023SJohn Marino 
7108e4b17023SJohn Marino 	if (result == error_mark_node)
7109e4b17023SJohn Marino 	  return error_mark_node;
7110e4b17023SJohn Marino 
7111e4b17023SJohn Marino 	if (result)
7112e4b17023SJohn Marino 	  result = size_diffop_loc (input_location,
7113e4b17023SJohn Marino 				    size_zero_node, result);
7114e4b17023SJohn Marino 	else
7115e4b17023SJohn Marino 	  {
7116e4b17023SJohn Marino 	    if (!(complain & tf_error))
7117e4b17023SJohn Marino 	      return error_mark_node;
7118e4b17023SJohn Marino 
7119e4b17023SJohn Marino 	    error_not_base_type (from, to);
7120e4b17023SJohn Marino 	    error ("   in pointer to member conversion");
7121e4b17023SJohn Marino 	    result = size_zero_node;
7122e4b17023SJohn Marino 	  }
7123e4b17023SJohn Marino       }
7124e4b17023SJohn Marino   }
7125e4b17023SJohn Marino 
7126e4b17023SJohn Marino   return fold_if_not_in_template (convert_to_integer (ptrdiff_type_node,
7127e4b17023SJohn Marino 						      result));
7128e4b17023SJohn Marino }
7129e4b17023SJohn Marino 
7130e4b17023SJohn Marino /* Return a constructor for the pointer-to-member-function TYPE using
7131e4b17023SJohn Marino    the other components as specified.  */
7132e4b17023SJohn Marino 
7133e4b17023SJohn Marino tree
build_ptrmemfunc1(tree type,tree delta,tree pfn)7134e4b17023SJohn Marino build_ptrmemfunc1 (tree type, tree delta, tree pfn)
7135e4b17023SJohn Marino {
7136e4b17023SJohn Marino   tree u = NULL_TREE;
7137e4b17023SJohn Marino   tree delta_field;
7138e4b17023SJohn Marino   tree pfn_field;
7139e4b17023SJohn Marino   VEC(constructor_elt, gc) *v;
7140e4b17023SJohn Marino 
7141e4b17023SJohn Marino   /* Pull the FIELD_DECLs out of the type.  */
7142e4b17023SJohn Marino   pfn_field = TYPE_FIELDS (type);
7143e4b17023SJohn Marino   delta_field = DECL_CHAIN (pfn_field);
7144e4b17023SJohn Marino 
7145e4b17023SJohn Marino   /* Make sure DELTA has the type we want.  */
7146e4b17023SJohn Marino   delta = convert_and_check (delta_type_node, delta);
7147e4b17023SJohn Marino 
7148e4b17023SJohn Marino   /* Convert to the correct target type if necessary.  */
7149e4b17023SJohn Marino   pfn = fold_convert (TREE_TYPE (pfn_field), pfn);
7150e4b17023SJohn Marino 
7151e4b17023SJohn Marino   /* Finish creating the initializer.  */
7152e4b17023SJohn Marino   v = VEC_alloc(constructor_elt, gc, 2);
7153e4b17023SJohn Marino   CONSTRUCTOR_APPEND_ELT(v, pfn_field, pfn);
7154e4b17023SJohn Marino   CONSTRUCTOR_APPEND_ELT(v, delta_field, delta);
7155e4b17023SJohn Marino   u = build_constructor (type, v);
7156e4b17023SJohn Marino   TREE_CONSTANT (u) = TREE_CONSTANT (pfn) & TREE_CONSTANT (delta);
7157e4b17023SJohn Marino   TREE_STATIC (u) = (TREE_CONSTANT (u)
7158e4b17023SJohn Marino 		     && (initializer_constant_valid_p (pfn, TREE_TYPE (pfn))
7159e4b17023SJohn Marino 			 != NULL_TREE)
7160e4b17023SJohn Marino 		     && (initializer_constant_valid_p (delta, TREE_TYPE (delta))
7161e4b17023SJohn Marino 			 != NULL_TREE));
7162e4b17023SJohn Marino   return u;
7163e4b17023SJohn Marino }
7164e4b17023SJohn Marino 
7165e4b17023SJohn Marino /* Build a constructor for a pointer to member function.  It can be
7166e4b17023SJohn Marino    used to initialize global variables, local variable, or used
7167e4b17023SJohn Marino    as a value in expressions.  TYPE is the POINTER to METHOD_TYPE we
7168e4b17023SJohn Marino    want to be.
7169e4b17023SJohn Marino 
7170e4b17023SJohn Marino    If FORCE is nonzero, then force this conversion, even if
7171e4b17023SJohn Marino    we would rather not do it.  Usually set when using an explicit
7172e4b17023SJohn Marino    cast.  A C-style cast is being processed iff C_CAST_P is true.
7173e4b17023SJohn Marino 
7174e4b17023SJohn Marino    Return error_mark_node, if something goes wrong.  */
7175e4b17023SJohn Marino 
7176e4b17023SJohn Marino tree
build_ptrmemfunc(tree type,tree pfn,int force,bool c_cast_p,tsubst_flags_t complain)7177e4b17023SJohn Marino build_ptrmemfunc (tree type, tree pfn, int force, bool c_cast_p,
7178e4b17023SJohn Marino 		  tsubst_flags_t complain)
7179e4b17023SJohn Marino {
7180e4b17023SJohn Marino   tree fn;
7181e4b17023SJohn Marino   tree pfn_type;
7182e4b17023SJohn Marino   tree to_type;
7183e4b17023SJohn Marino 
7184e4b17023SJohn Marino   if (error_operand_p (pfn))
7185e4b17023SJohn Marino     return error_mark_node;
7186e4b17023SJohn Marino 
7187e4b17023SJohn Marino   pfn_type = TREE_TYPE (pfn);
7188e4b17023SJohn Marino   to_type = build_ptrmemfunc_type (type);
7189e4b17023SJohn Marino 
7190e4b17023SJohn Marino   /* Handle multiple conversions of pointer to member functions.  */
7191e4b17023SJohn Marino   if (TYPE_PTRMEMFUNC_P (pfn_type))
7192e4b17023SJohn Marino     {
7193e4b17023SJohn Marino       tree delta = NULL_TREE;
7194e4b17023SJohn Marino       tree npfn = NULL_TREE;
7195e4b17023SJohn Marino       tree n;
7196e4b17023SJohn Marino 
7197e4b17023SJohn Marino       if (!force
7198e4b17023SJohn Marino 	  && !can_convert_arg (to_type, TREE_TYPE (pfn), pfn, LOOKUP_NORMAL))
7199e4b17023SJohn Marino 	error ("invalid conversion to type %qT from type %qT",
7200e4b17023SJohn Marino 	       to_type, pfn_type);
7201e4b17023SJohn Marino 
7202e4b17023SJohn Marino       n = get_delta_difference (TYPE_PTRMEMFUNC_OBJECT_TYPE (pfn_type),
7203e4b17023SJohn Marino 				TYPE_PTRMEMFUNC_OBJECT_TYPE (to_type),
7204e4b17023SJohn Marino 				force,
7205e4b17023SJohn Marino 				c_cast_p, complain);
7206e4b17023SJohn Marino       if (n == error_mark_node)
7207e4b17023SJohn Marino 	return error_mark_node;
7208e4b17023SJohn Marino 
7209e4b17023SJohn Marino       /* We don't have to do any conversion to convert a
7210e4b17023SJohn Marino 	 pointer-to-member to its own type.  But, we don't want to
7211e4b17023SJohn Marino 	 just return a PTRMEM_CST if there's an explicit cast; that
7212e4b17023SJohn Marino 	 cast should make the expression an invalid template argument.  */
7213e4b17023SJohn Marino       if (TREE_CODE (pfn) != PTRMEM_CST)
7214e4b17023SJohn Marino 	{
7215e4b17023SJohn Marino 	  if (same_type_p (to_type, pfn_type))
7216e4b17023SJohn Marino 	    return pfn;
7217e4b17023SJohn Marino 	  else if (integer_zerop (n))
7218e4b17023SJohn Marino 	    return build_reinterpret_cast (to_type, pfn,
7219e4b17023SJohn Marino                                            tf_warning_or_error);
7220e4b17023SJohn Marino 	}
7221e4b17023SJohn Marino 
7222e4b17023SJohn Marino       if (TREE_SIDE_EFFECTS (pfn))
7223e4b17023SJohn Marino 	pfn = save_expr (pfn);
7224e4b17023SJohn Marino 
7225e4b17023SJohn Marino       /* Obtain the function pointer and the current DELTA.  */
7226e4b17023SJohn Marino       if (TREE_CODE (pfn) == PTRMEM_CST)
7227e4b17023SJohn Marino 	expand_ptrmemfunc_cst (pfn, &delta, &npfn);
7228e4b17023SJohn Marino       else
7229e4b17023SJohn Marino 	{
7230e4b17023SJohn Marino 	  npfn = build_ptrmemfunc_access_expr (pfn, pfn_identifier);
7231e4b17023SJohn Marino 	  delta = build_ptrmemfunc_access_expr (pfn, delta_identifier);
7232e4b17023SJohn Marino 	}
7233e4b17023SJohn Marino 
7234e4b17023SJohn Marino       /* Just adjust the DELTA field.  */
7235e4b17023SJohn Marino       gcc_assert  (same_type_ignoring_top_level_qualifiers_p
7236e4b17023SJohn Marino 		   (TREE_TYPE (delta), ptrdiff_type_node));
7237e4b17023SJohn Marino       if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_delta)
7238e4b17023SJohn Marino 	n = cp_build_binary_op (input_location,
7239e4b17023SJohn Marino 				LSHIFT_EXPR, n, integer_one_node,
7240e4b17023SJohn Marino 				tf_warning_or_error);
7241e4b17023SJohn Marino       delta = cp_build_binary_op (input_location,
7242e4b17023SJohn Marino 				  PLUS_EXPR, delta, n, tf_warning_or_error);
7243e4b17023SJohn Marino       return build_ptrmemfunc1 (to_type, delta, npfn);
7244e4b17023SJohn Marino     }
7245e4b17023SJohn Marino 
7246e4b17023SJohn Marino   /* Handle null pointer to member function conversions.  */
7247e4b17023SJohn Marino   if (null_ptr_cst_p (pfn))
7248e4b17023SJohn Marino     {
7249*95d28233SJohn Marino       pfn = build_c_cast (input_location, type, pfn);
7250e4b17023SJohn Marino       return build_ptrmemfunc1 (to_type,
7251e4b17023SJohn Marino 				integer_zero_node,
7252e4b17023SJohn Marino 				pfn);
7253e4b17023SJohn Marino     }
7254e4b17023SJohn Marino 
7255e4b17023SJohn Marino   if (type_unknown_p (pfn))
7256e4b17023SJohn Marino     return instantiate_type (type, pfn, tf_warning_or_error);
7257e4b17023SJohn Marino 
7258e4b17023SJohn Marino   fn = TREE_OPERAND (pfn, 0);
7259e4b17023SJohn Marino   gcc_assert (TREE_CODE (fn) == FUNCTION_DECL
7260e4b17023SJohn Marino 	      /* In a template, we will have preserved the
7261e4b17023SJohn Marino 		 OFFSET_REF.  */
7262e4b17023SJohn Marino 	      || (processing_template_decl && TREE_CODE (fn) == OFFSET_REF));
7263e4b17023SJohn Marino   return make_ptrmem_cst (to_type, fn);
7264e4b17023SJohn Marino }
7265e4b17023SJohn Marino 
7266e4b17023SJohn Marino /* Return the DELTA, IDX, PFN, and DELTA2 values for the PTRMEM_CST
7267e4b17023SJohn Marino    given by CST.
7268e4b17023SJohn Marino 
7269e4b17023SJohn Marino    ??? There is no consistency as to the types returned for the above
7270e4b17023SJohn Marino    values.  Some code acts as if it were a sizetype and some as if it were
7271e4b17023SJohn Marino    integer_type_node.  */
7272e4b17023SJohn Marino 
7273e4b17023SJohn Marino void
expand_ptrmemfunc_cst(tree cst,tree * delta,tree * pfn)7274e4b17023SJohn Marino expand_ptrmemfunc_cst (tree cst, tree *delta, tree *pfn)
7275e4b17023SJohn Marino {
7276e4b17023SJohn Marino   tree type = TREE_TYPE (cst);
7277e4b17023SJohn Marino   tree fn = PTRMEM_CST_MEMBER (cst);
7278e4b17023SJohn Marino   tree ptr_class, fn_class;
7279e4b17023SJohn Marino 
7280e4b17023SJohn Marino   gcc_assert (TREE_CODE (fn) == FUNCTION_DECL);
7281e4b17023SJohn Marino 
7282e4b17023SJohn Marino   /* The class that the function belongs to.  */
7283e4b17023SJohn Marino   fn_class = DECL_CONTEXT (fn);
7284e4b17023SJohn Marino 
7285e4b17023SJohn Marino   /* The class that we're creating a pointer to member of.  */
7286e4b17023SJohn Marino   ptr_class = TYPE_PTRMEMFUNC_OBJECT_TYPE (type);
7287e4b17023SJohn Marino 
7288e4b17023SJohn Marino   /* First, calculate the adjustment to the function's class.  */
7289e4b17023SJohn Marino   *delta = get_delta_difference (fn_class, ptr_class, /*force=*/0,
7290e4b17023SJohn Marino 				 /*c_cast_p=*/0, tf_warning_or_error);
7291e4b17023SJohn Marino 
7292e4b17023SJohn Marino   if (!DECL_VIRTUAL_P (fn))
7293e4b17023SJohn Marino     *pfn = convert (TYPE_PTRMEMFUNC_FN_TYPE (type), build_addr_func (fn));
7294e4b17023SJohn Marino   else
7295e4b17023SJohn Marino     {
7296e4b17023SJohn Marino       /* If we're dealing with a virtual function, we have to adjust 'this'
7297e4b17023SJohn Marino 	 again, to point to the base which provides the vtable entry for
7298e4b17023SJohn Marino 	 fn; the call will do the opposite adjustment.  */
7299e4b17023SJohn Marino       tree orig_class = DECL_CONTEXT (fn);
7300e4b17023SJohn Marino       tree binfo = binfo_or_else (orig_class, fn_class);
7301e4b17023SJohn Marino       *delta = build2 (PLUS_EXPR, TREE_TYPE (*delta),
7302e4b17023SJohn Marino 		       *delta, BINFO_OFFSET (binfo));
7303e4b17023SJohn Marino       *delta = fold_if_not_in_template (*delta);
7304e4b17023SJohn Marino 
7305e4b17023SJohn Marino       /* We set PFN to the vtable offset at which the function can be
7306e4b17023SJohn Marino 	 found, plus one (unless ptrmemfunc_vbit_in_delta, in which
7307e4b17023SJohn Marino 	 case delta is shifted left, and then incremented).  */
7308e4b17023SJohn Marino       *pfn = DECL_VINDEX (fn);
7309e4b17023SJohn Marino       *pfn = build2 (MULT_EXPR, integer_type_node, *pfn,
7310e4b17023SJohn Marino 		     TYPE_SIZE_UNIT (vtable_entry_type));
7311e4b17023SJohn Marino       *pfn = fold_if_not_in_template (*pfn);
7312e4b17023SJohn Marino 
7313e4b17023SJohn Marino       switch (TARGET_PTRMEMFUNC_VBIT_LOCATION)
7314e4b17023SJohn Marino 	{
7315e4b17023SJohn Marino 	case ptrmemfunc_vbit_in_pfn:
7316e4b17023SJohn Marino 	  *pfn = build2 (PLUS_EXPR, integer_type_node, *pfn,
7317e4b17023SJohn Marino 			 integer_one_node);
7318e4b17023SJohn Marino 	  *pfn = fold_if_not_in_template (*pfn);
7319e4b17023SJohn Marino 	  break;
7320e4b17023SJohn Marino 
7321e4b17023SJohn Marino 	case ptrmemfunc_vbit_in_delta:
7322e4b17023SJohn Marino 	  *delta = build2 (LSHIFT_EXPR, TREE_TYPE (*delta),
7323e4b17023SJohn Marino 			   *delta, integer_one_node);
7324e4b17023SJohn Marino 	  *delta = fold_if_not_in_template (*delta);
7325e4b17023SJohn Marino 	  *delta = build2 (PLUS_EXPR, TREE_TYPE (*delta),
7326e4b17023SJohn Marino 			   *delta, integer_one_node);
7327e4b17023SJohn Marino 	  *delta = fold_if_not_in_template (*delta);
7328e4b17023SJohn Marino 	  break;
7329e4b17023SJohn Marino 
7330e4b17023SJohn Marino 	default:
7331e4b17023SJohn Marino 	  gcc_unreachable ();
7332e4b17023SJohn Marino 	}
7333e4b17023SJohn Marino 
7334e4b17023SJohn Marino       *pfn = build_nop (TYPE_PTRMEMFUNC_FN_TYPE (type), *pfn);
7335e4b17023SJohn Marino       *pfn = fold_if_not_in_template (*pfn);
7336e4b17023SJohn Marino     }
7337e4b17023SJohn Marino }
7338e4b17023SJohn Marino 
7339e4b17023SJohn Marino /* Return an expression for PFN from the pointer-to-member function
7340e4b17023SJohn Marino    given by T.  */
7341e4b17023SJohn Marino 
7342e4b17023SJohn Marino static tree
pfn_from_ptrmemfunc(tree t)7343e4b17023SJohn Marino pfn_from_ptrmemfunc (tree t)
7344e4b17023SJohn Marino {
7345e4b17023SJohn Marino   if (TREE_CODE (t) == PTRMEM_CST)
7346e4b17023SJohn Marino     {
7347e4b17023SJohn Marino       tree delta;
7348e4b17023SJohn Marino       tree pfn;
7349e4b17023SJohn Marino 
7350e4b17023SJohn Marino       expand_ptrmemfunc_cst (t, &delta, &pfn);
7351e4b17023SJohn Marino       if (pfn)
7352e4b17023SJohn Marino 	return pfn;
7353e4b17023SJohn Marino     }
7354e4b17023SJohn Marino 
7355e4b17023SJohn Marino   return build_ptrmemfunc_access_expr (t, pfn_identifier);
7356e4b17023SJohn Marino }
7357e4b17023SJohn Marino 
7358e4b17023SJohn Marino /* Return an expression for DELTA from the pointer-to-member function
7359e4b17023SJohn Marino    given by T.  */
7360e4b17023SJohn Marino 
7361e4b17023SJohn Marino static tree
delta_from_ptrmemfunc(tree t)7362e4b17023SJohn Marino delta_from_ptrmemfunc (tree t)
7363e4b17023SJohn Marino {
7364e4b17023SJohn Marino   if (TREE_CODE (t) == PTRMEM_CST)
7365e4b17023SJohn Marino     {
7366e4b17023SJohn Marino       tree delta;
7367e4b17023SJohn Marino       tree pfn;
7368e4b17023SJohn Marino 
7369e4b17023SJohn Marino       expand_ptrmemfunc_cst (t, &delta, &pfn);
7370e4b17023SJohn Marino       if (delta)
7371e4b17023SJohn Marino 	return delta;
7372e4b17023SJohn Marino     }
7373e4b17023SJohn Marino 
7374e4b17023SJohn Marino   return build_ptrmemfunc_access_expr (t, delta_identifier);
7375e4b17023SJohn Marino }
7376e4b17023SJohn Marino 
7377e4b17023SJohn Marino /* Convert value RHS to type TYPE as preparation for an assignment to
7378e4b17023SJohn Marino    an lvalue of type TYPE.  ERRTYPE indicates what kind of error the
7379e4b17023SJohn Marino    implicit conversion is.  If FNDECL is non-NULL, we are doing the
7380e4b17023SJohn Marino    conversion in order to pass the PARMNUMth argument of FNDECL.
7381e4b17023SJohn Marino    If FNDECL is NULL, we are doing the conversion in function pointer
7382e4b17023SJohn Marino    argument passing, conversion in initialization, etc. */
7383e4b17023SJohn Marino 
7384e4b17023SJohn Marino static tree
convert_for_assignment(tree type,tree rhs,impl_conv_rhs errtype,tree fndecl,int parmnum,tsubst_flags_t complain,int flags)7385e4b17023SJohn Marino convert_for_assignment (tree type, tree rhs,
7386e4b17023SJohn Marino 			impl_conv_rhs errtype, tree fndecl, int parmnum,
7387e4b17023SJohn Marino 			tsubst_flags_t complain, int flags)
7388e4b17023SJohn Marino {
7389e4b17023SJohn Marino   tree rhstype;
7390e4b17023SJohn Marino   enum tree_code coder;
7391e4b17023SJohn Marino 
7392e4b17023SJohn Marino   /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
7393e4b17023SJohn Marino   if (TREE_CODE (rhs) == NON_LVALUE_EXPR)
7394e4b17023SJohn Marino     rhs = TREE_OPERAND (rhs, 0);
7395e4b17023SJohn Marino 
7396e4b17023SJohn Marino   rhstype = TREE_TYPE (rhs);
7397e4b17023SJohn Marino   coder = TREE_CODE (rhstype);
7398e4b17023SJohn Marino 
7399e4b17023SJohn Marino   if (TREE_CODE (type) == VECTOR_TYPE && coder == VECTOR_TYPE
7400e4b17023SJohn Marino       && vector_types_convertible_p (type, rhstype, true))
7401e4b17023SJohn Marino     {
7402e4b17023SJohn Marino       rhs = mark_rvalue_use (rhs);
7403e4b17023SJohn Marino       return convert (type, rhs);
7404e4b17023SJohn Marino     }
7405e4b17023SJohn Marino 
7406e4b17023SJohn Marino   if (rhs == error_mark_node || rhstype == error_mark_node)
7407e4b17023SJohn Marino     return error_mark_node;
7408e4b17023SJohn Marino   if (TREE_CODE (rhs) == TREE_LIST && TREE_VALUE (rhs) == error_mark_node)
7409e4b17023SJohn Marino     return error_mark_node;
7410e4b17023SJohn Marino 
7411e4b17023SJohn Marino   /* The RHS of an assignment cannot have void type.  */
7412e4b17023SJohn Marino   if (coder == VOID_TYPE)
7413e4b17023SJohn Marino     {
7414e4b17023SJohn Marino       if (complain & tf_error)
7415e4b17023SJohn Marino 	error ("void value not ignored as it ought to be");
7416e4b17023SJohn Marino       return error_mark_node;
7417e4b17023SJohn Marino     }
7418e4b17023SJohn Marino 
7419e4b17023SJohn Marino   /* Simplify the RHS if possible.  */
7420e4b17023SJohn Marino   if (TREE_CODE (rhs) == CONST_DECL)
7421e4b17023SJohn Marino     rhs = DECL_INITIAL (rhs);
7422e4b17023SJohn Marino 
7423e4b17023SJohn Marino   if (c_dialect_objc ())
7424e4b17023SJohn Marino     {
7425e4b17023SJohn Marino       int parmno;
7426e4b17023SJohn Marino       tree selector;
7427e4b17023SJohn Marino       tree rname = fndecl;
7428e4b17023SJohn Marino 
7429e4b17023SJohn Marino       switch (errtype)
7430e4b17023SJohn Marino         {
7431e4b17023SJohn Marino 	  case ICR_ASSIGN:
7432e4b17023SJohn Marino 	    parmno = -1;
7433e4b17023SJohn Marino 	    break;
7434e4b17023SJohn Marino 	  case ICR_INIT:
7435e4b17023SJohn Marino 	    parmno = -2;
7436e4b17023SJohn Marino 	    break;
7437e4b17023SJohn Marino 	  default:
7438e4b17023SJohn Marino 	    selector = objc_message_selector ();
7439e4b17023SJohn Marino 	    parmno = parmnum;
7440e4b17023SJohn Marino 	    if (selector && parmno > 1)
7441e4b17023SJohn Marino 	      {
7442e4b17023SJohn Marino 		rname = selector;
7443e4b17023SJohn Marino 		parmno -= 1;
7444e4b17023SJohn Marino 	      }
7445e4b17023SJohn Marino 	}
7446e4b17023SJohn Marino 
7447e4b17023SJohn Marino       if (objc_compare_types (type, rhstype, parmno, rname))
7448e4b17023SJohn Marino 	{
7449e4b17023SJohn Marino 	  rhs = mark_rvalue_use (rhs);
7450e4b17023SJohn Marino 	  return convert (type, rhs);
7451e4b17023SJohn Marino 	}
7452e4b17023SJohn Marino     }
7453e4b17023SJohn Marino 
7454e4b17023SJohn Marino   /* [expr.ass]
7455e4b17023SJohn Marino 
7456e4b17023SJohn Marino      The expression is implicitly converted (clause _conv_) to the
7457e4b17023SJohn Marino      cv-unqualified type of the left operand.
7458e4b17023SJohn Marino 
7459e4b17023SJohn Marino      We allow bad conversions here because by the time we get to this point
7460e4b17023SJohn Marino      we are committed to doing the conversion.  If we end up doing a bad
7461e4b17023SJohn Marino      conversion, convert_like will complain.  */
7462e4b17023SJohn Marino   if (!can_convert_arg_bad (type, rhstype, rhs, flags))
7463e4b17023SJohn Marino     {
7464e4b17023SJohn Marino       /* When -Wno-pmf-conversions is use, we just silently allow
7465e4b17023SJohn Marino 	 conversions from pointers-to-members to plain pointers.  If
7466e4b17023SJohn Marino 	 the conversion doesn't work, cp_convert will complain.  */
7467e4b17023SJohn Marino       if (!warn_pmf2ptr
7468e4b17023SJohn Marino 	  && TYPE_PTR_P (type)
7469e4b17023SJohn Marino 	  && TYPE_PTRMEMFUNC_P (rhstype))
7470e4b17023SJohn Marino 	rhs = cp_convert (strip_top_quals (type), rhs);
7471e4b17023SJohn Marino       else
7472e4b17023SJohn Marino 	{
7473e4b17023SJohn Marino 	  if (complain & tf_error)
7474e4b17023SJohn Marino 	    {
7475e4b17023SJohn Marino 	      /* If the right-hand side has unknown type, then it is an
7476e4b17023SJohn Marino 		 overloaded function.  Call instantiate_type to get error
7477e4b17023SJohn Marino 		 messages.  */
7478e4b17023SJohn Marino 	      if (rhstype == unknown_type_node)
7479e4b17023SJohn Marino 		instantiate_type (type, rhs, tf_warning_or_error);
7480e4b17023SJohn Marino 	      else if (fndecl)
7481e4b17023SJohn Marino 		error ("cannot convert %qT to %qT for argument %qP to %qD",
7482e4b17023SJohn Marino 		       rhstype, type, parmnum, fndecl);
7483e4b17023SJohn Marino 	      else
7484e4b17023SJohn Marino 		switch (errtype)
7485e4b17023SJohn Marino 		  {
7486e4b17023SJohn Marino 		    case ICR_DEFAULT_ARGUMENT:
7487e4b17023SJohn Marino 		      error ("cannot convert %qT to %qT in default argument",
7488e4b17023SJohn Marino 			     rhstype, type);
7489e4b17023SJohn Marino 		      break;
7490e4b17023SJohn Marino 		    case ICR_ARGPASS:
7491e4b17023SJohn Marino 		      error ("cannot convert %qT to %qT in argument passing",
7492e4b17023SJohn Marino 			     rhstype, type);
7493e4b17023SJohn Marino 		      break;
7494e4b17023SJohn Marino 		    case ICR_CONVERTING:
7495e4b17023SJohn Marino 		      error ("cannot convert %qT to %qT",
7496e4b17023SJohn Marino 			     rhstype, type);
7497e4b17023SJohn Marino 		      break;
7498e4b17023SJohn Marino 		    case ICR_INIT:
7499e4b17023SJohn Marino 		      error ("cannot convert %qT to %qT in initialization",
7500e4b17023SJohn Marino 			     rhstype, type);
7501e4b17023SJohn Marino 		      break;
7502e4b17023SJohn Marino 		    case ICR_RETURN:
7503e4b17023SJohn Marino 		      error ("cannot convert %qT to %qT in return",
7504e4b17023SJohn Marino 			     rhstype, type);
7505e4b17023SJohn Marino 		      break;
7506e4b17023SJohn Marino 		    case ICR_ASSIGN:
7507e4b17023SJohn Marino 		      error ("cannot convert %qT to %qT in assignment",
7508e4b17023SJohn Marino 			     rhstype, type);
7509e4b17023SJohn Marino 		      break;
7510e4b17023SJohn Marino 		    default:
7511e4b17023SJohn Marino 		      gcc_unreachable();
7512e4b17023SJohn Marino 		  }
7513e4b17023SJohn Marino 	    }
7514e4b17023SJohn Marino 	  return error_mark_node;
7515e4b17023SJohn Marino 	}
7516e4b17023SJohn Marino     }
7517e4b17023SJohn Marino   if (warn_missing_format_attribute)
7518e4b17023SJohn Marino     {
7519e4b17023SJohn Marino       const enum tree_code codel = TREE_CODE (type);
7520e4b17023SJohn Marino       if ((codel == POINTER_TYPE || codel == REFERENCE_TYPE)
7521e4b17023SJohn Marino 	  && coder == codel
7522e4b17023SJohn Marino 	  && check_missing_format_attribute (type, rhstype)
7523e4b17023SJohn Marino 	  && (complain & tf_warning))
7524e4b17023SJohn Marino 	switch (errtype)
7525e4b17023SJohn Marino 	  {
7526e4b17023SJohn Marino 	    case ICR_ARGPASS:
7527e4b17023SJohn Marino 	    case ICR_DEFAULT_ARGUMENT:
7528e4b17023SJohn Marino 	      if (fndecl)
7529e4b17023SJohn Marino 		warning (OPT_Wmissing_format_attribute,
7530e4b17023SJohn Marino 			 "parameter %qP of %qD might be a candidate "
7531e4b17023SJohn Marino 			 "for a format attribute", parmnum, fndecl);
7532e4b17023SJohn Marino 	      else
7533e4b17023SJohn Marino 		warning (OPT_Wmissing_format_attribute,
7534e4b17023SJohn Marino 			 "parameter might be a candidate "
7535e4b17023SJohn Marino 			 "for a format attribute");
7536e4b17023SJohn Marino 	      break;
7537e4b17023SJohn Marino 	    case ICR_CONVERTING:
7538e4b17023SJohn Marino 	      warning (OPT_Wmissing_format_attribute,
7539e4b17023SJohn Marino 		       "target of conversion might be a candidate "
7540e4b17023SJohn Marino 		       "for a format attribute");
7541e4b17023SJohn Marino 	      break;
7542e4b17023SJohn Marino 	    case ICR_INIT:
7543e4b17023SJohn Marino 	      warning (OPT_Wmissing_format_attribute,
7544e4b17023SJohn Marino 		       "target of initialization might be a candidate "
7545e4b17023SJohn Marino 		       "for a format attribute");
7546e4b17023SJohn Marino 	      break;
7547e4b17023SJohn Marino 	    case ICR_RETURN:
7548e4b17023SJohn Marino 	      warning (OPT_Wmissing_format_attribute,
7549e4b17023SJohn Marino 		       "return type might be a candidate "
7550e4b17023SJohn Marino 		       "for a format attribute");
7551e4b17023SJohn Marino 	      break;
7552e4b17023SJohn Marino 	    case ICR_ASSIGN:
7553e4b17023SJohn Marino 	      warning (OPT_Wmissing_format_attribute,
7554e4b17023SJohn Marino 		       "left-hand side of assignment might be a candidate "
7555e4b17023SJohn Marino 		       "for a format attribute");
7556e4b17023SJohn Marino 	      break;
7557e4b17023SJohn Marino 	    default:
7558e4b17023SJohn Marino 	      gcc_unreachable();
7559e4b17023SJohn Marino 	  }
7560e4b17023SJohn Marino     }
7561e4b17023SJohn Marino 
7562e4b17023SJohn Marino   /* If -Wparentheses, warn about a = b = c when a has type bool and b
7563e4b17023SJohn Marino      does not.  */
7564e4b17023SJohn Marino   if (warn_parentheses
7565e4b17023SJohn Marino       && TREE_CODE (type) == BOOLEAN_TYPE
7566e4b17023SJohn Marino       && TREE_CODE (rhs) == MODIFY_EXPR
7567e4b17023SJohn Marino       && !TREE_NO_WARNING (rhs)
7568e4b17023SJohn Marino       && TREE_CODE (TREE_TYPE (rhs)) != BOOLEAN_TYPE
7569e4b17023SJohn Marino       && (complain & tf_warning))
7570e4b17023SJohn Marino     {
7571e4b17023SJohn Marino       location_t loc = EXPR_LOC_OR_HERE (rhs);
7572e4b17023SJohn Marino 
7573e4b17023SJohn Marino       warning_at (loc, OPT_Wparentheses,
7574e4b17023SJohn Marino 		  "suggest parentheses around assignment used as truth value");
7575e4b17023SJohn Marino       TREE_NO_WARNING (rhs) = 1;
7576e4b17023SJohn Marino     }
7577e4b17023SJohn Marino 
7578e4b17023SJohn Marino   return perform_implicit_conversion_flags (strip_top_quals (type), rhs,
7579e4b17023SJohn Marino 					    complain, flags);
7580e4b17023SJohn Marino }
7581e4b17023SJohn Marino 
7582e4b17023SJohn Marino /* Convert RHS to be of type TYPE.
7583e4b17023SJohn Marino    If EXP is nonzero, it is the target of the initialization.
7584e4b17023SJohn Marino    ERRTYPE indicates what kind of error the implicit conversion is.
7585e4b17023SJohn Marino 
7586e4b17023SJohn Marino    Two major differences between the behavior of
7587e4b17023SJohn Marino    `convert_for_assignment' and `convert_for_initialization'
7588e4b17023SJohn Marino    are that references are bashed in the former, while
7589e4b17023SJohn Marino    copied in the latter, and aggregates are assigned in
7590e4b17023SJohn Marino    the former (operator=) while initialized in the
7591e4b17023SJohn Marino    latter (X(X&)).
7592e4b17023SJohn Marino 
7593e4b17023SJohn Marino    If using constructor make sure no conversion operator exists, if one does
7594e4b17023SJohn Marino    exist, an ambiguity exists.
7595e4b17023SJohn Marino 
7596e4b17023SJohn Marino    If flags doesn't include LOOKUP_COMPLAIN, don't complain about anything.  */
7597e4b17023SJohn Marino 
7598e4b17023SJohn Marino tree
convert_for_initialization(tree exp,tree type,tree rhs,int flags,impl_conv_rhs errtype,tree fndecl,int parmnum,tsubst_flags_t complain)7599e4b17023SJohn Marino convert_for_initialization (tree exp, tree type, tree rhs, int flags,
7600e4b17023SJohn Marino 			    impl_conv_rhs errtype, tree fndecl, int parmnum,
7601e4b17023SJohn Marino                             tsubst_flags_t complain)
7602e4b17023SJohn Marino {
7603e4b17023SJohn Marino   enum tree_code codel = TREE_CODE (type);
7604e4b17023SJohn Marino   tree rhstype;
7605e4b17023SJohn Marino   enum tree_code coder;
7606e4b17023SJohn Marino 
7607e4b17023SJohn Marino   /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
7608e4b17023SJohn Marino      Strip such NOP_EXPRs, since RHS is used in non-lvalue context.  */
7609e4b17023SJohn Marino   if (TREE_CODE (rhs) == NOP_EXPR
7610e4b17023SJohn Marino       && TREE_TYPE (rhs) == TREE_TYPE (TREE_OPERAND (rhs, 0))
7611e4b17023SJohn Marino       && codel != REFERENCE_TYPE)
7612e4b17023SJohn Marino     rhs = TREE_OPERAND (rhs, 0);
7613e4b17023SJohn Marino 
7614e4b17023SJohn Marino   if (type == error_mark_node
7615e4b17023SJohn Marino       || rhs == error_mark_node
7616e4b17023SJohn Marino       || (TREE_CODE (rhs) == TREE_LIST && TREE_VALUE (rhs) == error_mark_node))
7617e4b17023SJohn Marino     return error_mark_node;
7618e4b17023SJohn Marino 
7619e4b17023SJohn Marino   if ((TREE_CODE (TREE_TYPE (rhs)) == ARRAY_TYPE
7620e4b17023SJohn Marino        && TREE_CODE (type) != ARRAY_TYPE
7621e4b17023SJohn Marino        && (TREE_CODE (type) != REFERENCE_TYPE
7622e4b17023SJohn Marino 	   || TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE))
7623e4b17023SJohn Marino       || (TREE_CODE (TREE_TYPE (rhs)) == FUNCTION_TYPE
7624e4b17023SJohn Marino 	  && (TREE_CODE (type) != REFERENCE_TYPE
7625e4b17023SJohn Marino 	      || TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE))
7626e4b17023SJohn Marino       || TREE_CODE (TREE_TYPE (rhs)) == METHOD_TYPE)
7627e4b17023SJohn Marino     rhs = decay_conversion (rhs);
7628e4b17023SJohn Marino 
7629e4b17023SJohn Marino   rhstype = TREE_TYPE (rhs);
7630e4b17023SJohn Marino   coder = TREE_CODE (rhstype);
7631e4b17023SJohn Marino 
7632e4b17023SJohn Marino   if (coder == ERROR_MARK)
7633e4b17023SJohn Marino     return error_mark_node;
7634e4b17023SJohn Marino 
7635e4b17023SJohn Marino   /* We accept references to incomplete types, so we can
7636e4b17023SJohn Marino      return here before checking if RHS is of complete type.  */
7637e4b17023SJohn Marino 
7638e4b17023SJohn Marino   if (codel == REFERENCE_TYPE)
7639e4b17023SJohn Marino     {
7640e4b17023SJohn Marino       /* This should eventually happen in convert_arguments.  */
7641e4b17023SJohn Marino       int savew = 0, savee = 0;
7642e4b17023SJohn Marino 
7643e4b17023SJohn Marino       if (fndecl)
7644e4b17023SJohn Marino 	savew = warningcount, savee = errorcount;
7645e4b17023SJohn Marino       rhs = initialize_reference (type, rhs, flags, complain);
7646e4b17023SJohn Marino       if (fndecl)
7647e4b17023SJohn Marino 	{
7648e4b17023SJohn Marino 	  if (warningcount > savew)
7649e4b17023SJohn Marino 	    warning (0, "in passing argument %P of %q+D", parmnum, fndecl);
7650e4b17023SJohn Marino 	  else if (errorcount > savee)
7651e4b17023SJohn Marino 	    error ("in passing argument %P of %q+D", parmnum, fndecl);
7652e4b17023SJohn Marino 	}
7653e4b17023SJohn Marino       return rhs;
7654e4b17023SJohn Marino     }
7655e4b17023SJohn Marino 
7656e4b17023SJohn Marino   if (exp != 0)
7657e4b17023SJohn Marino     exp = require_complete_type_sfinae (exp, complain);
7658e4b17023SJohn Marino   if (exp == error_mark_node)
7659e4b17023SJohn Marino     return error_mark_node;
7660e4b17023SJohn Marino 
7661e4b17023SJohn Marino   rhstype = non_reference (rhstype);
7662e4b17023SJohn Marino 
7663e4b17023SJohn Marino   type = complete_type (type);
7664e4b17023SJohn Marino 
7665e4b17023SJohn Marino   if (DIRECT_INIT_EXPR_P (type, rhs))
7666e4b17023SJohn Marino     /* Don't try to do copy-initialization if we already have
7667e4b17023SJohn Marino        direct-initialization.  */
7668e4b17023SJohn Marino     return rhs;
7669e4b17023SJohn Marino 
7670e4b17023SJohn Marino   if (MAYBE_CLASS_TYPE_P (type))
7671e4b17023SJohn Marino     return perform_implicit_conversion_flags (type, rhs, complain, flags);
7672e4b17023SJohn Marino 
7673e4b17023SJohn Marino   return convert_for_assignment (type, rhs, errtype, fndecl, parmnum,
7674e4b17023SJohn Marino 				 complain, flags);
7675e4b17023SJohn Marino }
7676e4b17023SJohn Marino 
7677e4b17023SJohn Marino /* If RETVAL is the address of, or a reference to, a local variable or
7678e4b17023SJohn Marino    temporary give an appropriate warning.  */
7679e4b17023SJohn Marino 
7680e4b17023SJohn Marino static void
maybe_warn_about_returning_address_of_local(tree retval)7681e4b17023SJohn Marino maybe_warn_about_returning_address_of_local (tree retval)
7682e4b17023SJohn Marino {
7683e4b17023SJohn Marino   tree valtype = TREE_TYPE (DECL_RESULT (current_function_decl));
7684e4b17023SJohn Marino   tree whats_returned = retval;
7685e4b17023SJohn Marino 
7686e4b17023SJohn Marino   for (;;)
7687e4b17023SJohn Marino     {
7688e4b17023SJohn Marino       if (TREE_CODE (whats_returned) == COMPOUND_EXPR)
7689e4b17023SJohn Marino 	whats_returned = TREE_OPERAND (whats_returned, 1);
7690e4b17023SJohn Marino       else if (CONVERT_EXPR_P (whats_returned)
7691e4b17023SJohn Marino 	       || TREE_CODE (whats_returned) == NON_LVALUE_EXPR)
7692e4b17023SJohn Marino 	whats_returned = TREE_OPERAND (whats_returned, 0);
7693e4b17023SJohn Marino       else
7694e4b17023SJohn Marino 	break;
7695e4b17023SJohn Marino     }
7696e4b17023SJohn Marino 
7697e4b17023SJohn Marino   if (TREE_CODE (whats_returned) != ADDR_EXPR)
7698e4b17023SJohn Marino     return;
7699e4b17023SJohn Marino   whats_returned = TREE_OPERAND (whats_returned, 0);
7700e4b17023SJohn Marino 
7701e4b17023SJohn Marino   if (TREE_CODE (valtype) == REFERENCE_TYPE)
7702e4b17023SJohn Marino     {
7703e4b17023SJohn Marino       if (TREE_CODE (whats_returned) == AGGR_INIT_EXPR
7704e4b17023SJohn Marino 	  || TREE_CODE (whats_returned) == TARGET_EXPR)
7705e4b17023SJohn Marino 	{
7706e4b17023SJohn Marino 	  warning (0, "returning reference to temporary");
7707e4b17023SJohn Marino 	  return;
7708e4b17023SJohn Marino 	}
7709e4b17023SJohn Marino       if (TREE_CODE (whats_returned) == VAR_DECL
7710e4b17023SJohn Marino 	  && DECL_NAME (whats_returned)
7711e4b17023SJohn Marino 	  && TEMP_NAME_P (DECL_NAME (whats_returned)))
7712e4b17023SJohn Marino 	{
7713e4b17023SJohn Marino 	  warning (0, "reference to non-lvalue returned");
7714e4b17023SJohn Marino 	  return;
7715e4b17023SJohn Marino 	}
7716e4b17023SJohn Marino     }
7717e4b17023SJohn Marino 
7718e4b17023SJohn Marino   while (TREE_CODE (whats_returned) == COMPONENT_REF
7719e4b17023SJohn Marino 	 || TREE_CODE (whats_returned) == ARRAY_REF)
7720e4b17023SJohn Marino     whats_returned = TREE_OPERAND (whats_returned, 0);
7721e4b17023SJohn Marino 
7722e4b17023SJohn Marino   if (DECL_P (whats_returned)
7723e4b17023SJohn Marino       && DECL_NAME (whats_returned)
7724e4b17023SJohn Marino       && DECL_FUNCTION_SCOPE_P (whats_returned)
7725e4b17023SJohn Marino       && !(TREE_STATIC (whats_returned)
7726e4b17023SJohn Marino 	   || TREE_PUBLIC (whats_returned)))
7727e4b17023SJohn Marino     {
7728e4b17023SJohn Marino       if (TREE_CODE (valtype) == REFERENCE_TYPE)
7729e4b17023SJohn Marino 	warning (0, "reference to local variable %q+D returned",
7730e4b17023SJohn Marino 		 whats_returned);
7731e4b17023SJohn Marino       else
7732e4b17023SJohn Marino 	warning (0, "address of local variable %q+D returned",
7733e4b17023SJohn Marino 		 whats_returned);
7734e4b17023SJohn Marino       return;
7735e4b17023SJohn Marino     }
7736e4b17023SJohn Marino }
7737e4b17023SJohn Marino 
7738e4b17023SJohn Marino /* Check that returning RETVAL from the current function is valid.
7739e4b17023SJohn Marino    Return an expression explicitly showing all conversions required to
7740e4b17023SJohn Marino    change RETVAL into the function return type, and to assign it to
7741e4b17023SJohn Marino    the DECL_RESULT for the function.  Set *NO_WARNING to true if
7742e4b17023SJohn Marino    code reaches end of non-void function warning shouldn't be issued
7743e4b17023SJohn Marino    on this RETURN_EXPR.  */
7744e4b17023SJohn Marino 
7745e4b17023SJohn Marino tree
check_return_expr(tree retval,bool * no_warning)7746e4b17023SJohn Marino check_return_expr (tree retval, bool *no_warning)
7747e4b17023SJohn Marino {
7748e4b17023SJohn Marino   tree result;
7749e4b17023SJohn Marino   /* The type actually returned by the function, after any
7750e4b17023SJohn Marino      promotions.  */
7751e4b17023SJohn Marino   tree valtype;
7752e4b17023SJohn Marino   int fn_returns_value_p;
7753e4b17023SJohn Marino   bool named_return_value_okay_p;
7754e4b17023SJohn Marino 
7755e4b17023SJohn Marino   *no_warning = false;
7756e4b17023SJohn Marino 
7757e4b17023SJohn Marino   /* A `volatile' function is one that isn't supposed to return, ever.
7758e4b17023SJohn Marino      (This is a G++ extension, used to get better code for functions
7759e4b17023SJohn Marino      that call the `volatile' function.)  */
7760e4b17023SJohn Marino   if (TREE_THIS_VOLATILE (current_function_decl))
7761e4b17023SJohn Marino     warning (0, "function declared %<noreturn%> has a %<return%> statement");
7762e4b17023SJohn Marino 
7763e4b17023SJohn Marino   /* Check for various simple errors.  */
7764e4b17023SJohn Marino   if (DECL_DESTRUCTOR_P (current_function_decl))
7765e4b17023SJohn Marino     {
7766e4b17023SJohn Marino       if (retval)
7767e4b17023SJohn Marino 	error ("returning a value from a destructor");
7768e4b17023SJohn Marino       return NULL_TREE;
7769e4b17023SJohn Marino     }
7770e4b17023SJohn Marino   else if (DECL_CONSTRUCTOR_P (current_function_decl))
7771e4b17023SJohn Marino     {
7772e4b17023SJohn Marino       if (in_function_try_handler)
7773e4b17023SJohn Marino 	/* If a return statement appears in a handler of the
7774e4b17023SJohn Marino 	   function-try-block of a constructor, the program is ill-formed.  */
7775e4b17023SJohn Marino 	error ("cannot return from a handler of a function-try-block of a constructor");
7776e4b17023SJohn Marino       else if (retval)
7777e4b17023SJohn Marino 	/* You can't return a value from a constructor.  */
7778e4b17023SJohn Marino 	error ("returning a value from a constructor");
7779e4b17023SJohn Marino       return NULL_TREE;
7780e4b17023SJohn Marino     }
7781e4b17023SJohn Marino 
7782e4b17023SJohn Marino   /* As an extension, deduce lambda return type from a return statement
7783e4b17023SJohn Marino      anywhere in the body.  */
7784e4b17023SJohn Marino   if (retval && LAMBDA_FUNCTION_P (current_function_decl))
7785e4b17023SJohn Marino     {
7786e4b17023SJohn Marino       tree lambda = CLASSTYPE_LAMBDA_EXPR (current_class_type);
7787e4b17023SJohn Marino       if (LAMBDA_EXPR_DEDUCE_RETURN_TYPE_P (lambda))
7788e4b17023SJohn Marino 	{
7789e4b17023SJohn Marino 	  tree type = lambda_return_type (retval);
7790e4b17023SJohn Marino 	  tree oldtype = LAMBDA_EXPR_RETURN_TYPE (lambda);
7791e4b17023SJohn Marino 
7792e4b17023SJohn Marino 	  if (oldtype == NULL_TREE)
7793e4b17023SJohn Marino 	    apply_lambda_return_type (lambda, type);
7794e4b17023SJohn Marino 	  /* If one of the answers is type-dependent, we can't do any
7795e4b17023SJohn Marino 	     better until instantiation time.  */
7796e4b17023SJohn Marino 	  else if (oldtype == dependent_lambda_return_type_node)
7797e4b17023SJohn Marino 	    /* Leave it.  */;
7798e4b17023SJohn Marino 	  else if (type == dependent_lambda_return_type_node)
7799e4b17023SJohn Marino 	    apply_lambda_return_type (lambda, type);
7800e4b17023SJohn Marino 	  else if (!same_type_p (type, oldtype))
7801e4b17023SJohn Marino 	    error ("inconsistent types %qT and %qT deduced for "
7802e4b17023SJohn Marino 		   "lambda return type", type, oldtype);
7803e4b17023SJohn Marino 	}
7804e4b17023SJohn Marino     }
7805e4b17023SJohn Marino 
7806e4b17023SJohn Marino   if (processing_template_decl)
7807e4b17023SJohn Marino     {
7808e4b17023SJohn Marino       current_function_returns_value = 1;
7809e4b17023SJohn Marino       if (check_for_bare_parameter_packs (retval))
7810e4b17023SJohn Marino         retval = error_mark_node;
7811e4b17023SJohn Marino       return retval;
7812e4b17023SJohn Marino     }
7813e4b17023SJohn Marino 
7814e4b17023SJohn Marino   /* When no explicit return-value is given in a function with a named
7815e4b17023SJohn Marino      return value, the named return value is used.  */
7816e4b17023SJohn Marino   result = DECL_RESULT (current_function_decl);
7817e4b17023SJohn Marino   valtype = TREE_TYPE (result);
7818e4b17023SJohn Marino   gcc_assert (valtype != NULL_TREE);
7819e4b17023SJohn Marino   fn_returns_value_p = !VOID_TYPE_P (valtype);
7820e4b17023SJohn Marino   if (!retval && DECL_NAME (result) && fn_returns_value_p)
7821e4b17023SJohn Marino     retval = result;
7822e4b17023SJohn Marino 
7823e4b17023SJohn Marino   /* Check for a return statement with no return value in a function
7824e4b17023SJohn Marino      that's supposed to return a value.  */
7825e4b17023SJohn Marino   if (!retval && fn_returns_value_p)
7826e4b17023SJohn Marino     {
7827e4b17023SJohn Marino       permerror (input_location, "return-statement with no value, in function returning %qT",
7828e4b17023SJohn Marino 	         valtype);
7829e4b17023SJohn Marino       /* Clear this, so finish_function won't say that we reach the
7830e4b17023SJohn Marino 	 end of a non-void function (which we don't, we gave a
7831e4b17023SJohn Marino 	 return!).  */
7832e4b17023SJohn Marino       current_function_returns_null = 0;
7833e4b17023SJohn Marino       /* And signal caller that TREE_NO_WARNING should be set on the
7834e4b17023SJohn Marino 	 RETURN_EXPR to avoid control reaches end of non-void function
7835e4b17023SJohn Marino 	 warnings in tree-cfg.c.  */
7836e4b17023SJohn Marino       *no_warning = true;
7837e4b17023SJohn Marino     }
7838e4b17023SJohn Marino   /* Check for a return statement with a value in a function that
7839e4b17023SJohn Marino      isn't supposed to return a value.  */
7840e4b17023SJohn Marino   else if (retval && !fn_returns_value_p)
7841e4b17023SJohn Marino     {
7842e4b17023SJohn Marino       if (VOID_TYPE_P (TREE_TYPE (retval)))
7843e4b17023SJohn Marino 	/* You can return a `void' value from a function of `void'
7844e4b17023SJohn Marino 	   type.  In that case, we have to evaluate the expression for
7845e4b17023SJohn Marino 	   its side-effects.  */
7846e4b17023SJohn Marino 	  finish_expr_stmt (retval);
7847e4b17023SJohn Marino       else
7848e4b17023SJohn Marino 	permerror (input_location, "return-statement with a value, in function "
7849e4b17023SJohn Marino 		   "returning 'void'");
7850e4b17023SJohn Marino       current_function_returns_null = 1;
7851e4b17023SJohn Marino 
7852e4b17023SJohn Marino       /* There's really no value to return, after all.  */
7853e4b17023SJohn Marino       return NULL_TREE;
7854e4b17023SJohn Marino     }
7855e4b17023SJohn Marino   else if (!retval)
7856e4b17023SJohn Marino     /* Remember that this function can sometimes return without a
7857e4b17023SJohn Marino        value.  */
7858e4b17023SJohn Marino     current_function_returns_null = 1;
7859e4b17023SJohn Marino   else
7860e4b17023SJohn Marino     /* Remember that this function did return a value.  */
7861e4b17023SJohn Marino     current_function_returns_value = 1;
7862e4b17023SJohn Marino 
7863e4b17023SJohn Marino   /* Check for erroneous operands -- but after giving ourselves a
7864e4b17023SJohn Marino      chance to provide an error about returning a value from a void
7865e4b17023SJohn Marino      function.  */
7866e4b17023SJohn Marino   if (error_operand_p (retval))
7867e4b17023SJohn Marino     {
7868e4b17023SJohn Marino       current_function_return_value = error_mark_node;
7869e4b17023SJohn Marino       return error_mark_node;
7870e4b17023SJohn Marino     }
7871e4b17023SJohn Marino 
7872e4b17023SJohn Marino   /* Only operator new(...) throw(), can return NULL [expr.new/13].  */
7873e4b17023SJohn Marino   if ((DECL_OVERLOADED_OPERATOR_P (current_function_decl) == NEW_EXPR
7874e4b17023SJohn Marino        || DECL_OVERLOADED_OPERATOR_P (current_function_decl) == VEC_NEW_EXPR)
7875e4b17023SJohn Marino       && !TYPE_NOTHROW_P (TREE_TYPE (current_function_decl))
7876e4b17023SJohn Marino       && ! flag_check_new
7877e4b17023SJohn Marino       && retval && null_ptr_cst_p (retval))
7878e4b17023SJohn Marino     warning (0, "%<operator new%> must not return NULL unless it is "
7879e4b17023SJohn Marino 	     "declared %<throw()%> (or -fcheck-new is in effect)");
7880e4b17023SJohn Marino 
7881e4b17023SJohn Marino   /* Effective C++ rule 15.  See also start_function.  */
7882e4b17023SJohn Marino   if (warn_ecpp
7883e4b17023SJohn Marino       && DECL_NAME (current_function_decl) == ansi_assopname(NOP_EXPR))
7884e4b17023SJohn Marino     {
7885e4b17023SJohn Marino       bool warn = true;
7886e4b17023SJohn Marino 
7887e4b17023SJohn Marino       /* The function return type must be a reference to the current
7888e4b17023SJohn Marino 	class.  */
7889e4b17023SJohn Marino       if (TREE_CODE (valtype) == REFERENCE_TYPE
7890e4b17023SJohn Marino 	  && same_type_ignoring_top_level_qualifiers_p
7891e4b17023SJohn Marino 	      (TREE_TYPE (valtype), TREE_TYPE (current_class_ref)))
7892e4b17023SJohn Marino 	{
7893e4b17023SJohn Marino 	  /* Returning '*this' is obviously OK.  */
7894e4b17023SJohn Marino 	  if (retval == current_class_ref)
7895e4b17023SJohn Marino 	    warn = false;
7896e4b17023SJohn Marino 	  /* If we are calling a function whose return type is the same of
7897e4b17023SJohn Marino 	     the current class reference, it is ok.  */
7898e4b17023SJohn Marino 	  else if (TREE_CODE (retval) == INDIRECT_REF
7899e4b17023SJohn Marino 		   && TREE_CODE (TREE_OPERAND (retval, 0)) == CALL_EXPR)
7900e4b17023SJohn Marino 	    warn = false;
7901e4b17023SJohn Marino 	}
7902e4b17023SJohn Marino 
7903e4b17023SJohn Marino       if (warn)
7904e4b17023SJohn Marino 	warning (OPT_Weffc__, "%<operator=%> should return a reference to %<*this%>");
7905e4b17023SJohn Marino     }
7906e4b17023SJohn Marino 
7907e4b17023SJohn Marino   /* The fabled Named Return Value optimization, as per [class.copy]/15:
7908e4b17023SJohn Marino 
7909e4b17023SJohn Marino      [...]      For  a function with a class return type, if the expression
7910e4b17023SJohn Marino      in the return statement is the name of a local  object,  and  the  cv-
7911e4b17023SJohn Marino      unqualified  type  of  the  local  object  is the same as the function
7912e4b17023SJohn Marino      return type, an implementation is permitted to omit creating the  tem-
7913e4b17023SJohn Marino      porary  object  to  hold  the function return value [...]
7914e4b17023SJohn Marino 
7915e4b17023SJohn Marino      So, if this is a value-returning function that always returns the same
7916e4b17023SJohn Marino      local variable, remember it.
7917e4b17023SJohn Marino 
7918e4b17023SJohn Marino      It might be nice to be more flexible, and choose the first suitable
7919e4b17023SJohn Marino      variable even if the function sometimes returns something else, but
7920e4b17023SJohn Marino      then we run the risk of clobbering the variable we chose if the other
7921e4b17023SJohn Marino      returned expression uses the chosen variable somehow.  And people expect
7922e4b17023SJohn Marino      this restriction, anyway.  (jason 2000-11-19)
7923e4b17023SJohn Marino 
7924e4b17023SJohn Marino      See finish_function and finalize_nrv for the rest of this optimization.  */
7925e4b17023SJohn Marino 
7926e4b17023SJohn Marino   named_return_value_okay_p =
7927e4b17023SJohn Marino     (retval != NULL_TREE
7928e4b17023SJohn Marino      /* Must be a local, automatic variable.  */
7929e4b17023SJohn Marino      && TREE_CODE (retval) == VAR_DECL
7930e4b17023SJohn Marino      && DECL_CONTEXT (retval) == current_function_decl
7931e4b17023SJohn Marino      && ! TREE_STATIC (retval)
7932*95d28233SJohn Marino      /* And not a lambda or anonymous union proxy.  */
7933*95d28233SJohn Marino      && !DECL_HAS_VALUE_EXPR_P (retval)
7934e4b17023SJohn Marino      && (DECL_ALIGN (retval)
7935e4b17023SJohn Marino          >= DECL_ALIGN (DECL_RESULT (current_function_decl)))
7936e4b17023SJohn Marino      /* The cv-unqualified type of the returned value must be the
7937e4b17023SJohn Marino         same as the cv-unqualified return type of the
7938e4b17023SJohn Marino         function.  */
7939e4b17023SJohn Marino      && same_type_p ((TYPE_MAIN_VARIANT (TREE_TYPE (retval))),
7940e4b17023SJohn Marino                      (TYPE_MAIN_VARIANT
7941e4b17023SJohn Marino                       (TREE_TYPE (TREE_TYPE (current_function_decl)))))
7942e4b17023SJohn Marino      /* And the returned value must be non-volatile.  */
7943e4b17023SJohn Marino      && ! TYPE_VOLATILE (TREE_TYPE (retval)));
7944e4b17023SJohn Marino 
7945e4b17023SJohn Marino   if (fn_returns_value_p && flag_elide_constructors)
7946e4b17023SJohn Marino     {
7947e4b17023SJohn Marino       if (named_return_value_okay_p
7948e4b17023SJohn Marino           && (current_function_return_value == NULL_TREE
7949e4b17023SJohn Marino               || current_function_return_value == retval))
7950e4b17023SJohn Marino 	current_function_return_value = retval;
7951e4b17023SJohn Marino       else
7952e4b17023SJohn Marino 	current_function_return_value = error_mark_node;
7953e4b17023SJohn Marino     }
7954e4b17023SJohn Marino 
7955e4b17023SJohn Marino   /* We don't need to do any conversions when there's nothing being
7956e4b17023SJohn Marino      returned.  */
7957e4b17023SJohn Marino   if (!retval)
7958e4b17023SJohn Marino     return NULL_TREE;
7959e4b17023SJohn Marino 
7960e4b17023SJohn Marino   /* Do any required conversions.  */
7961e4b17023SJohn Marino   if (retval == result || DECL_CONSTRUCTOR_P (current_function_decl))
7962e4b17023SJohn Marino     /* No conversions are required.  */
7963e4b17023SJohn Marino     ;
7964e4b17023SJohn Marino   else
7965e4b17023SJohn Marino     {
7966e4b17023SJohn Marino       /* The type the function is declared to return.  */
7967e4b17023SJohn Marino       tree functype = TREE_TYPE (TREE_TYPE (current_function_decl));
7968e4b17023SJohn Marino       int flags = LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING;
7969e4b17023SJohn Marino 
7970e4b17023SJohn Marino       /* The functype's return type will have been set to void, if it
7971e4b17023SJohn Marino 	 was an incomplete type.  Just treat this as 'return;' */
7972e4b17023SJohn Marino       if (VOID_TYPE_P (functype))
7973e4b17023SJohn Marino 	return error_mark_node;
7974e4b17023SJohn Marino 
7975e4b17023SJohn Marino       /* Under C++0x [12.8/16 class.copy], a returned lvalue is sometimes
7976e4b17023SJohn Marino 	 treated as an rvalue for the purposes of overload resolution to
7977e4b17023SJohn Marino 	 favor move constructors over copy constructors.
7978e4b17023SJohn Marino 
7979e4b17023SJohn Marino          Note that these conditions are similar to, but not as strict as,
7980e4b17023SJohn Marino 	 the conditions for the named return value optimization.  */
7981e4b17023SJohn Marino       if ((cxx_dialect != cxx98)
7982*95d28233SJohn Marino           && ((TREE_CODE (retval) == VAR_DECL
7983*95d28233SJohn Marino 	       && !DECL_HAS_VALUE_EXPR_P (retval))
7984e4b17023SJohn Marino 	      || TREE_CODE (retval) == PARM_DECL)
7985e4b17023SJohn Marino 	  && DECL_CONTEXT (retval) == current_function_decl
7986e4b17023SJohn Marino 	  && !TREE_STATIC (retval)
7987e4b17023SJohn Marino 	  && same_type_p ((TYPE_MAIN_VARIANT (TREE_TYPE (retval))),
7988e4b17023SJohn Marino 			  (TYPE_MAIN_VARIANT
7989e4b17023SJohn Marino 			   (TREE_TYPE (TREE_TYPE (current_function_decl)))))
7990e4b17023SJohn Marino 	  /* This is only interesting for class type.  */
7991e4b17023SJohn Marino 	  && CLASS_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))))
7992e4b17023SJohn Marino 	flags = flags | LOOKUP_PREFER_RVALUE;
7993e4b17023SJohn Marino 
7994e4b17023SJohn Marino       /* First convert the value to the function's return type, then
7995e4b17023SJohn Marino 	 to the type of return value's location to handle the
7996e4b17023SJohn Marino 	 case that functype is smaller than the valtype.  */
7997e4b17023SJohn Marino       retval = convert_for_initialization
7998e4b17023SJohn Marino 	(NULL_TREE, functype, retval, flags, ICR_RETURN, NULL_TREE, 0,
7999e4b17023SJohn Marino          tf_warning_or_error);
8000e4b17023SJohn Marino       retval = convert (valtype, retval);
8001e4b17023SJohn Marino 
8002e4b17023SJohn Marino       /* If the conversion failed, treat this just like `return;'.  */
8003e4b17023SJohn Marino       if (retval == error_mark_node)
8004e4b17023SJohn Marino 	return retval;
8005e4b17023SJohn Marino       /* We can't initialize a register from a AGGR_INIT_EXPR.  */
8006e4b17023SJohn Marino       else if (! cfun->returns_struct
8007e4b17023SJohn Marino 	       && TREE_CODE (retval) == TARGET_EXPR
8008e4b17023SJohn Marino 	       && TREE_CODE (TREE_OPERAND (retval, 1)) == AGGR_INIT_EXPR)
8009e4b17023SJohn Marino 	retval = build2 (COMPOUND_EXPR, TREE_TYPE (retval), retval,
8010e4b17023SJohn Marino 			 TREE_OPERAND (retval, 0));
8011e4b17023SJohn Marino       else
8012e4b17023SJohn Marino 	maybe_warn_about_returning_address_of_local (retval);
8013e4b17023SJohn Marino     }
8014e4b17023SJohn Marino 
8015e4b17023SJohn Marino   /* Actually copy the value returned into the appropriate location.  */
8016e4b17023SJohn Marino   if (retval && retval != result)
8017e4b17023SJohn Marino     retval = build2 (INIT_EXPR, TREE_TYPE (result), result, retval);
8018e4b17023SJohn Marino 
8019e4b17023SJohn Marino   return retval;
8020e4b17023SJohn Marino }
8021e4b17023SJohn Marino 
8022e4b17023SJohn Marino 
8023e4b17023SJohn Marino /* Returns nonzero if the pointer-type FROM can be converted to the
8024e4b17023SJohn Marino    pointer-type TO via a qualification conversion.  If CONSTP is -1,
8025e4b17023SJohn Marino    then we return nonzero if the pointers are similar, and the
8026e4b17023SJohn Marino    cv-qualification signature of FROM is a proper subset of that of TO.
8027e4b17023SJohn Marino 
8028e4b17023SJohn Marino    If CONSTP is positive, then all outer pointers have been
8029e4b17023SJohn Marino    const-qualified.  */
8030e4b17023SJohn Marino 
8031e4b17023SJohn Marino static int
comp_ptr_ttypes_real(tree to,tree from,int constp)8032e4b17023SJohn Marino comp_ptr_ttypes_real (tree to, tree from, int constp)
8033e4b17023SJohn Marino {
8034e4b17023SJohn Marino   bool to_more_cv_qualified = false;
8035e4b17023SJohn Marino   bool is_opaque_pointer = false;
8036e4b17023SJohn Marino 
8037e4b17023SJohn Marino   for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from))
8038e4b17023SJohn Marino     {
8039e4b17023SJohn Marino       if (TREE_CODE (to) != TREE_CODE (from))
8040e4b17023SJohn Marino 	return 0;
8041e4b17023SJohn Marino 
8042e4b17023SJohn Marino       if (TREE_CODE (from) == OFFSET_TYPE
8043e4b17023SJohn Marino 	  && !same_type_p (TYPE_OFFSET_BASETYPE (from),
8044e4b17023SJohn Marino 			   TYPE_OFFSET_BASETYPE (to)))
8045e4b17023SJohn Marino 	return 0;
8046e4b17023SJohn Marino 
8047e4b17023SJohn Marino       /* Const and volatile mean something different for function types,
8048e4b17023SJohn Marino 	 so the usual checks are not appropriate.  */
8049e4b17023SJohn Marino       if (TREE_CODE (to) != FUNCTION_TYPE && TREE_CODE (to) != METHOD_TYPE)
8050e4b17023SJohn Marino 	{
8051e4b17023SJohn Marino 	  if (!at_least_as_qualified_p (to, from))
8052e4b17023SJohn Marino 	    return 0;
8053e4b17023SJohn Marino 
8054e4b17023SJohn Marino 	  if (!at_least_as_qualified_p (from, to))
8055e4b17023SJohn Marino 	    {
8056e4b17023SJohn Marino 	      if (constp == 0)
8057e4b17023SJohn Marino 		return 0;
8058e4b17023SJohn Marino 	      to_more_cv_qualified = true;
8059e4b17023SJohn Marino 	    }
8060e4b17023SJohn Marino 
8061e4b17023SJohn Marino 	  if (constp > 0)
8062e4b17023SJohn Marino 	    constp &= TYPE_READONLY (to);
8063e4b17023SJohn Marino 	}
8064e4b17023SJohn Marino 
8065e4b17023SJohn Marino       if (TREE_CODE (to) == VECTOR_TYPE)
8066e4b17023SJohn Marino 	is_opaque_pointer = vector_targets_convertible_p (to, from);
8067e4b17023SJohn Marino 
8068e4b17023SJohn Marino       if (TREE_CODE (to) != POINTER_TYPE && !TYPE_PTRMEM_P (to))
8069e4b17023SJohn Marino 	return ((constp >= 0 || to_more_cv_qualified)
8070e4b17023SJohn Marino 		&& (is_opaque_pointer
8071e4b17023SJohn Marino 		    || same_type_ignoring_top_level_qualifiers_p (to, from)));
8072e4b17023SJohn Marino     }
8073e4b17023SJohn Marino }
8074e4b17023SJohn Marino 
8075e4b17023SJohn Marino /* When comparing, say, char ** to char const **, this function takes
8076e4b17023SJohn Marino    the 'char *' and 'char const *'.  Do not pass non-pointer/reference
8077e4b17023SJohn Marino    types to this function.  */
8078e4b17023SJohn Marino 
8079e4b17023SJohn Marino int
comp_ptr_ttypes(tree to,tree from)8080e4b17023SJohn Marino comp_ptr_ttypes (tree to, tree from)
8081e4b17023SJohn Marino {
8082e4b17023SJohn Marino   return comp_ptr_ttypes_real (to, from, 1);
8083e4b17023SJohn Marino }
8084e4b17023SJohn Marino 
8085e4b17023SJohn Marino /* Returns true iff FNTYPE is a non-class type that involves
8086e4b17023SJohn Marino    error_mark_node.  We can get FUNCTION_TYPE with buried error_mark_node
8087e4b17023SJohn Marino    if a parameter type is ill-formed.  */
8088e4b17023SJohn Marino 
8089e4b17023SJohn Marino bool
error_type_p(const_tree type)8090e4b17023SJohn Marino error_type_p (const_tree type)
8091e4b17023SJohn Marino {
8092e4b17023SJohn Marino   tree t;
8093e4b17023SJohn Marino 
8094e4b17023SJohn Marino   switch (TREE_CODE (type))
8095e4b17023SJohn Marino     {
8096e4b17023SJohn Marino     case ERROR_MARK:
8097e4b17023SJohn Marino       return true;
8098e4b17023SJohn Marino 
8099e4b17023SJohn Marino     case POINTER_TYPE:
8100e4b17023SJohn Marino     case REFERENCE_TYPE:
8101e4b17023SJohn Marino     case OFFSET_TYPE:
8102e4b17023SJohn Marino       return error_type_p (TREE_TYPE (type));
8103e4b17023SJohn Marino 
8104e4b17023SJohn Marino     case FUNCTION_TYPE:
8105e4b17023SJohn Marino     case METHOD_TYPE:
8106e4b17023SJohn Marino       if (error_type_p (TREE_TYPE (type)))
8107e4b17023SJohn Marino 	return true;
8108e4b17023SJohn Marino       for (t = TYPE_ARG_TYPES (type); t; t = TREE_CHAIN (t))
8109e4b17023SJohn Marino 	if (error_type_p (TREE_VALUE (t)))
8110e4b17023SJohn Marino 	  return true;
8111e4b17023SJohn Marino       return false;
8112e4b17023SJohn Marino 
8113e4b17023SJohn Marino     case RECORD_TYPE:
8114e4b17023SJohn Marino       if (TYPE_PTRMEMFUNC_P (type))
8115e4b17023SJohn Marino 	return error_type_p (TYPE_PTRMEMFUNC_FN_TYPE (type));
8116e4b17023SJohn Marino       return false;
8117e4b17023SJohn Marino 
8118e4b17023SJohn Marino     default:
8119e4b17023SJohn Marino       return false;
8120e4b17023SJohn Marino     }
8121e4b17023SJohn Marino }
8122e4b17023SJohn Marino 
8123e4b17023SJohn Marino /* Returns 1 if to and from are (possibly multi-level) pointers to the same
8124e4b17023SJohn Marino    type or inheritance-related types, regardless of cv-quals.  */
8125e4b17023SJohn Marino 
8126e4b17023SJohn Marino int
ptr_reasonably_similar(const_tree to,const_tree from)8127e4b17023SJohn Marino ptr_reasonably_similar (const_tree to, const_tree from)
8128e4b17023SJohn Marino {
8129e4b17023SJohn Marino   for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from))
8130e4b17023SJohn Marino     {
8131e4b17023SJohn Marino       /* Any target type is similar enough to void.  */
8132e4b17023SJohn Marino       if (TREE_CODE (to) == VOID_TYPE)
8133e4b17023SJohn Marino 	return !error_type_p (from);
8134e4b17023SJohn Marino       if (TREE_CODE (from) == VOID_TYPE)
8135e4b17023SJohn Marino 	return !error_type_p (to);
8136e4b17023SJohn Marino 
8137e4b17023SJohn Marino       if (TREE_CODE (to) != TREE_CODE (from))
8138e4b17023SJohn Marino 	return 0;
8139e4b17023SJohn Marino 
8140e4b17023SJohn Marino       if (TREE_CODE (from) == OFFSET_TYPE
8141e4b17023SJohn Marino 	  && comptypes (TYPE_OFFSET_BASETYPE (to),
8142e4b17023SJohn Marino 			TYPE_OFFSET_BASETYPE (from),
8143e4b17023SJohn Marino 			COMPARE_BASE | COMPARE_DERIVED))
8144e4b17023SJohn Marino 	continue;
8145e4b17023SJohn Marino 
8146e4b17023SJohn Marino       if (TREE_CODE (to) == VECTOR_TYPE
8147e4b17023SJohn Marino 	  && vector_types_convertible_p (to, from, false))
8148e4b17023SJohn Marino 	return 1;
8149e4b17023SJohn Marino 
8150e4b17023SJohn Marino       if (TREE_CODE (to) == INTEGER_TYPE
8151e4b17023SJohn Marino 	  && TYPE_PRECISION (to) == TYPE_PRECISION (from))
8152e4b17023SJohn Marino 	return 1;
8153e4b17023SJohn Marino 
8154e4b17023SJohn Marino       if (TREE_CODE (to) == FUNCTION_TYPE)
8155e4b17023SJohn Marino 	return !error_type_p (to) && !error_type_p (from);
8156e4b17023SJohn Marino 
8157e4b17023SJohn Marino       if (TREE_CODE (to) != POINTER_TYPE)
8158e4b17023SJohn Marino 	return comptypes
8159e4b17023SJohn Marino 	  (TYPE_MAIN_VARIANT (to), TYPE_MAIN_VARIANT (from),
8160e4b17023SJohn Marino 	   COMPARE_BASE | COMPARE_DERIVED);
8161e4b17023SJohn Marino     }
8162e4b17023SJohn Marino }
8163e4b17023SJohn Marino 
8164e4b17023SJohn Marino /* Return true if TO and FROM (both of which are POINTER_TYPEs or
8165e4b17023SJohn Marino    pointer-to-member types) are the same, ignoring cv-qualification at
8166e4b17023SJohn Marino    all levels.  */
8167e4b17023SJohn Marino 
8168e4b17023SJohn Marino bool
comp_ptr_ttypes_const(tree to,tree from)8169e4b17023SJohn Marino comp_ptr_ttypes_const (tree to, tree from)
8170e4b17023SJohn Marino {
8171e4b17023SJohn Marino   bool is_opaque_pointer = false;
8172e4b17023SJohn Marino 
8173e4b17023SJohn Marino   for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from))
8174e4b17023SJohn Marino     {
8175e4b17023SJohn Marino       if (TREE_CODE (to) != TREE_CODE (from))
8176e4b17023SJohn Marino 	return false;
8177e4b17023SJohn Marino 
8178e4b17023SJohn Marino       if (TREE_CODE (from) == OFFSET_TYPE
8179e4b17023SJohn Marino 	  && same_type_p (TYPE_OFFSET_BASETYPE (from),
8180e4b17023SJohn Marino 			  TYPE_OFFSET_BASETYPE (to)))
8181e4b17023SJohn Marino 	  continue;
8182e4b17023SJohn Marino 
8183e4b17023SJohn Marino       if (TREE_CODE (to) == VECTOR_TYPE)
8184e4b17023SJohn Marino 	is_opaque_pointer = vector_targets_convertible_p (to, from);
8185e4b17023SJohn Marino 
8186e4b17023SJohn Marino       if (TREE_CODE (to) != POINTER_TYPE)
8187e4b17023SJohn Marino 	return (is_opaque_pointer
8188e4b17023SJohn Marino 		|| same_type_ignoring_top_level_qualifiers_p (to, from));
8189e4b17023SJohn Marino     }
8190e4b17023SJohn Marino }
8191e4b17023SJohn Marino 
8192e4b17023SJohn Marino /* Returns the type qualifiers for this type, including the qualifiers on the
8193e4b17023SJohn Marino    elements for an array type.  */
8194e4b17023SJohn Marino 
8195e4b17023SJohn Marino int
cp_type_quals(const_tree type)8196e4b17023SJohn Marino cp_type_quals (const_tree type)
8197e4b17023SJohn Marino {
8198e4b17023SJohn Marino   int quals;
8199e4b17023SJohn Marino   /* This CONST_CAST is okay because strip_array_types returns its
8200e4b17023SJohn Marino      argument unmodified and we assign it to a const_tree.  */
8201e4b17023SJohn Marino   type = strip_array_types (CONST_CAST_TREE (type));
8202e4b17023SJohn Marino   if (type == error_mark_node
8203e4b17023SJohn Marino       /* Quals on a FUNCTION_TYPE are memfn quals.  */
8204e4b17023SJohn Marino       || TREE_CODE (type) == FUNCTION_TYPE)
8205e4b17023SJohn Marino     return TYPE_UNQUALIFIED;
8206e4b17023SJohn Marino   quals = TYPE_QUALS (type);
8207e4b17023SJohn Marino   /* METHOD and REFERENCE_TYPEs should never have quals.  */
8208e4b17023SJohn Marino   gcc_assert ((TREE_CODE (type) != METHOD_TYPE
8209e4b17023SJohn Marino 	       && TREE_CODE (type) != REFERENCE_TYPE)
8210e4b17023SJohn Marino 	      || ((quals & (TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE))
8211e4b17023SJohn Marino 		  == TYPE_UNQUALIFIED));
8212e4b17023SJohn Marino   return quals;
8213e4b17023SJohn Marino }
8214e4b17023SJohn Marino 
8215e4b17023SJohn Marino /* Returns the function-cv-quals for TYPE, which must be a FUNCTION_TYPE or
8216e4b17023SJohn Marino    METHOD_TYPE.  */
8217e4b17023SJohn Marino 
8218e4b17023SJohn Marino int
type_memfn_quals(const_tree type)8219e4b17023SJohn Marino type_memfn_quals (const_tree type)
8220e4b17023SJohn Marino {
8221e4b17023SJohn Marino   if (TREE_CODE (type) == FUNCTION_TYPE)
8222e4b17023SJohn Marino     return TYPE_QUALS (type);
8223e4b17023SJohn Marino   else if (TREE_CODE (type) == METHOD_TYPE)
8224e4b17023SJohn Marino     return cp_type_quals (class_of_this_parm (type));
8225e4b17023SJohn Marino   else
8226e4b17023SJohn Marino     gcc_unreachable ();
8227e4b17023SJohn Marino }
8228e4b17023SJohn Marino 
8229e4b17023SJohn Marino /* Returns the FUNCTION_TYPE TYPE with its function-cv-quals changed to
8230e4b17023SJohn Marino    MEMFN_QUALS.  */
8231e4b17023SJohn Marino 
8232e4b17023SJohn Marino tree
apply_memfn_quals(tree type,cp_cv_quals memfn_quals)8233e4b17023SJohn Marino apply_memfn_quals (tree type, cp_cv_quals memfn_quals)
8234e4b17023SJohn Marino {
8235e4b17023SJohn Marino   /* Could handle METHOD_TYPE here if necessary.  */
8236e4b17023SJohn Marino   gcc_assert (TREE_CODE (type) == FUNCTION_TYPE);
8237e4b17023SJohn Marino   if (TYPE_QUALS (type) == memfn_quals)
8238e4b17023SJohn Marino     return type;
8239e4b17023SJohn Marino   /* This should really have a different TYPE_MAIN_VARIANT, but that gets
8240e4b17023SJohn Marino      complex.  */
8241e4b17023SJohn Marino   return build_qualified_type (type, memfn_quals);
8242e4b17023SJohn Marino }
8243e4b17023SJohn Marino 
8244e4b17023SJohn Marino /* Returns nonzero if TYPE is const or volatile.  */
8245e4b17023SJohn Marino 
8246e4b17023SJohn Marino bool
cv_qualified_p(const_tree type)8247e4b17023SJohn Marino cv_qualified_p (const_tree type)
8248e4b17023SJohn Marino {
8249e4b17023SJohn Marino   int quals = cp_type_quals (type);
8250e4b17023SJohn Marino   return (quals & (TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE)) != 0;
8251e4b17023SJohn Marino }
8252e4b17023SJohn Marino 
8253e4b17023SJohn Marino /* Returns nonzero if the TYPE contains a mutable member.  */
8254e4b17023SJohn Marino 
8255e4b17023SJohn Marino bool
cp_has_mutable_p(const_tree type)8256e4b17023SJohn Marino cp_has_mutable_p (const_tree type)
8257e4b17023SJohn Marino {
8258e4b17023SJohn Marino   /* This CONST_CAST is okay because strip_array_types returns its
8259e4b17023SJohn Marino      argument unmodified and we assign it to a const_tree.  */
8260e4b17023SJohn Marino   type = strip_array_types (CONST_CAST_TREE(type));
8261e4b17023SJohn Marino 
8262e4b17023SJohn Marino   return CLASS_TYPE_P (type) && CLASSTYPE_HAS_MUTABLE (type);
8263e4b17023SJohn Marino }
8264e4b17023SJohn Marino 
8265e4b17023SJohn Marino /* Set TREE_READONLY and TREE_VOLATILE on DECL as indicated by the
8266e4b17023SJohn Marino    TYPE_QUALS.  For a VAR_DECL, this may be an optimistic
8267e4b17023SJohn Marino    approximation.  In particular, consider:
8268e4b17023SJohn Marino 
8269e4b17023SJohn Marino      int f();
8270e4b17023SJohn Marino      struct S { int i; };
8271e4b17023SJohn Marino      const S s = { f(); }
8272e4b17023SJohn Marino 
8273e4b17023SJohn Marino    Here, we will make "s" as TREE_READONLY (because it is declared
8274e4b17023SJohn Marino    "const") -- only to reverse ourselves upon seeing that the
8275e4b17023SJohn Marino    initializer is non-constant.  */
8276e4b17023SJohn Marino 
8277e4b17023SJohn Marino void
cp_apply_type_quals_to_decl(int type_quals,tree decl)8278e4b17023SJohn Marino cp_apply_type_quals_to_decl (int type_quals, tree decl)
8279e4b17023SJohn Marino {
8280e4b17023SJohn Marino   tree type = TREE_TYPE (decl);
8281e4b17023SJohn Marino 
8282e4b17023SJohn Marino   if (type == error_mark_node)
8283e4b17023SJohn Marino     return;
8284e4b17023SJohn Marino 
8285e4b17023SJohn Marino   if (TREE_CODE (decl) == TYPE_DECL)
8286e4b17023SJohn Marino     return;
8287e4b17023SJohn Marino 
8288e4b17023SJohn Marino   gcc_assert (!(TREE_CODE (type) == FUNCTION_TYPE
8289e4b17023SJohn Marino 		&& type_quals != TYPE_UNQUALIFIED));
8290e4b17023SJohn Marino 
8291e4b17023SJohn Marino   /* Avoid setting TREE_READONLY incorrectly.  */
8292e4b17023SJohn Marino   /* We used to check TYPE_NEEDS_CONSTRUCTING here, but now a constexpr
8293e4b17023SJohn Marino      constructor can produce constant init, so rely on cp_finish_decl to
8294e4b17023SJohn Marino      clear TREE_READONLY if the variable has non-constant init.  */
8295e4b17023SJohn Marino 
8296e4b17023SJohn Marino   /* If the type has (or might have) a mutable component, that component
8297e4b17023SJohn Marino      might be modified.  */
8298e4b17023SJohn Marino   if (TYPE_HAS_MUTABLE_P (type) || !COMPLETE_TYPE_P (type))
8299e4b17023SJohn Marino     type_quals &= ~TYPE_QUAL_CONST;
8300e4b17023SJohn Marino 
8301e4b17023SJohn Marino   c_apply_type_quals_to_decl (type_quals, decl);
8302e4b17023SJohn Marino }
8303e4b17023SJohn Marino 
8304e4b17023SJohn Marino /* Subroutine of casts_away_constness.  Make T1 and T2 point at
8305e4b17023SJohn Marino    exemplar types such that casting T1 to T2 is casting away constness
8306e4b17023SJohn Marino    if and only if there is no implicit conversion from T1 to T2.  */
8307e4b17023SJohn Marino 
8308e4b17023SJohn Marino static void
casts_away_constness_r(tree * t1,tree * t2)8309e4b17023SJohn Marino casts_away_constness_r (tree *t1, tree *t2)
8310e4b17023SJohn Marino {
8311e4b17023SJohn Marino   int quals1;
8312e4b17023SJohn Marino   int quals2;
8313e4b17023SJohn Marino 
8314e4b17023SJohn Marino   /* [expr.const.cast]
8315e4b17023SJohn Marino 
8316e4b17023SJohn Marino      For multi-level pointer to members and multi-level mixed pointers
8317e4b17023SJohn Marino      and pointers to members (conv.qual), the "member" aspect of a
8318e4b17023SJohn Marino      pointer to member level is ignored when determining if a const
8319e4b17023SJohn Marino      cv-qualifier has been cast away.  */
8320e4b17023SJohn Marino   /* [expr.const.cast]
8321e4b17023SJohn Marino 
8322e4b17023SJohn Marino      For  two  pointer types:
8323e4b17023SJohn Marino 
8324e4b17023SJohn Marino 	    X1 is T1cv1,1 * ... cv1,N *   where T1 is not a pointer type
8325e4b17023SJohn Marino 	    X2 is T2cv2,1 * ... cv2,M *   where T2 is not a pointer type
8326e4b17023SJohn Marino 	    K is min(N,M)
8327e4b17023SJohn Marino 
8328e4b17023SJohn Marino      casting from X1 to X2 casts away constness if, for a non-pointer
8329e4b17023SJohn Marino      type T there does not exist an implicit conversion (clause
8330e4b17023SJohn Marino      _conv_) from:
8331e4b17023SJohn Marino 
8332e4b17023SJohn Marino 	    Tcv1,(N-K+1) * cv1,(N-K+2) * ... cv1,N *
8333e4b17023SJohn Marino 
8334e4b17023SJohn Marino      to
8335e4b17023SJohn Marino 
8336e4b17023SJohn Marino 	    Tcv2,(M-K+1) * cv2,(M-K+2) * ... cv2,M *.  */
8337e4b17023SJohn Marino   if ((!TYPE_PTR_P (*t1) && !TYPE_PTRMEM_P (*t1))
8338e4b17023SJohn Marino       || (!TYPE_PTR_P (*t2) && !TYPE_PTRMEM_P (*t2)))
8339e4b17023SJohn Marino     {
8340e4b17023SJohn Marino       *t1 = cp_build_qualified_type (void_type_node,
8341e4b17023SJohn Marino 				     cp_type_quals (*t1));
8342e4b17023SJohn Marino       *t2 = cp_build_qualified_type (void_type_node,
8343e4b17023SJohn Marino 				     cp_type_quals (*t2));
8344e4b17023SJohn Marino       return;
8345e4b17023SJohn Marino     }
8346e4b17023SJohn Marino 
8347e4b17023SJohn Marino   quals1 = cp_type_quals (*t1);
8348e4b17023SJohn Marino   quals2 = cp_type_quals (*t2);
8349e4b17023SJohn Marino 
8350e4b17023SJohn Marino   if (TYPE_PTRMEM_P (*t1))
8351e4b17023SJohn Marino     *t1 = TYPE_PTRMEM_POINTED_TO_TYPE (*t1);
8352e4b17023SJohn Marino   else
8353e4b17023SJohn Marino     *t1 = TREE_TYPE (*t1);
8354e4b17023SJohn Marino   if (TYPE_PTRMEM_P (*t2))
8355e4b17023SJohn Marino     *t2 = TYPE_PTRMEM_POINTED_TO_TYPE (*t2);
8356e4b17023SJohn Marino   else
8357e4b17023SJohn Marino     *t2 = TREE_TYPE (*t2);
8358e4b17023SJohn Marino 
8359e4b17023SJohn Marino   casts_away_constness_r (t1, t2);
8360e4b17023SJohn Marino   *t1 = build_pointer_type (*t1);
8361e4b17023SJohn Marino   *t2 = build_pointer_type (*t2);
8362e4b17023SJohn Marino   *t1 = cp_build_qualified_type (*t1, quals1);
8363e4b17023SJohn Marino   *t2 = cp_build_qualified_type (*t2, quals2);
8364e4b17023SJohn Marino }
8365e4b17023SJohn Marino 
8366e4b17023SJohn Marino /* Returns nonzero if casting from TYPE1 to TYPE2 casts away
8367e4b17023SJohn Marino    constness.
8368e4b17023SJohn Marino 
8369e4b17023SJohn Marino    ??? This function returns non-zero if casting away qualifiers not
8370e4b17023SJohn Marino    just const.  We would like to return to the caller exactly which
8371e4b17023SJohn Marino    qualifiers are casted away to give more accurate diagnostics.
8372e4b17023SJohn Marino */
8373e4b17023SJohn Marino 
8374e4b17023SJohn Marino static bool
casts_away_constness(tree t1,tree t2)8375e4b17023SJohn Marino casts_away_constness (tree t1, tree t2)
8376e4b17023SJohn Marino {
8377e4b17023SJohn Marino   if (TREE_CODE (t2) == REFERENCE_TYPE)
8378e4b17023SJohn Marino     {
8379e4b17023SJohn Marino       /* [expr.const.cast]
8380e4b17023SJohn Marino 
8381e4b17023SJohn Marino 	 Casting from an lvalue of type T1 to an lvalue of type T2
8382e4b17023SJohn Marino 	 using a reference cast casts away constness if a cast from an
8383e4b17023SJohn Marino 	 rvalue of type "pointer to T1" to the type "pointer to T2"
8384e4b17023SJohn Marino 	 casts away constness.  */
8385e4b17023SJohn Marino       t1 = (TREE_CODE (t1) == REFERENCE_TYPE ? TREE_TYPE (t1) : t1);
8386e4b17023SJohn Marino       return casts_away_constness (build_pointer_type (t1),
8387e4b17023SJohn Marino 				   build_pointer_type (TREE_TYPE (t2)));
8388e4b17023SJohn Marino     }
8389e4b17023SJohn Marino 
8390e4b17023SJohn Marino   if (TYPE_PTRMEM_P (t1) && TYPE_PTRMEM_P (t2))
8391e4b17023SJohn Marino     /* [expr.const.cast]
8392e4b17023SJohn Marino 
8393e4b17023SJohn Marino        Casting from an rvalue of type "pointer to data member of X
8394e4b17023SJohn Marino        of type T1" to the type "pointer to data member of Y of type
8395e4b17023SJohn Marino        T2" casts away constness if a cast from an rvalue of type
8396e4b17023SJohn Marino        "pointer to T1" to the type "pointer to T2" casts away
8397e4b17023SJohn Marino        constness.  */
8398e4b17023SJohn Marino     return casts_away_constness
8399e4b17023SJohn Marino       (build_pointer_type (TYPE_PTRMEM_POINTED_TO_TYPE (t1)),
8400e4b17023SJohn Marino        build_pointer_type (TYPE_PTRMEM_POINTED_TO_TYPE (t2)));
8401e4b17023SJohn Marino 
8402e4b17023SJohn Marino   /* Casting away constness is only something that makes sense for
8403e4b17023SJohn Marino      pointer or reference types.  */
8404e4b17023SJohn Marino   if (TREE_CODE (t1) != POINTER_TYPE
8405e4b17023SJohn Marino       || TREE_CODE (t2) != POINTER_TYPE)
8406e4b17023SJohn Marino     return false;
8407e4b17023SJohn Marino 
8408e4b17023SJohn Marino   /* Top-level qualifiers don't matter.  */
8409e4b17023SJohn Marino   t1 = TYPE_MAIN_VARIANT (t1);
8410e4b17023SJohn Marino   t2 = TYPE_MAIN_VARIANT (t2);
8411e4b17023SJohn Marino   casts_away_constness_r (&t1, &t2);
8412e4b17023SJohn Marino   if (!can_convert (t2, t1))
8413e4b17023SJohn Marino     return true;
8414e4b17023SJohn Marino 
8415e4b17023SJohn Marino   return false;
8416e4b17023SJohn Marino }
8417e4b17023SJohn Marino 
8418e4b17023SJohn Marino /* If T is a REFERENCE_TYPE return the type to which T refers.
8419e4b17023SJohn Marino    Otherwise, return T itself.  */
8420e4b17023SJohn Marino 
8421e4b17023SJohn Marino tree
non_reference(tree t)8422e4b17023SJohn Marino non_reference (tree t)
8423e4b17023SJohn Marino {
8424e4b17023SJohn Marino   if (t && TREE_CODE (t) == REFERENCE_TYPE)
8425e4b17023SJohn Marino     t = TREE_TYPE (t);
8426e4b17023SJohn Marino   return t;
8427e4b17023SJohn Marino }
8428e4b17023SJohn Marino 
8429e4b17023SJohn Marino 
8430e4b17023SJohn Marino /* Return nonzero if REF is an lvalue valid for this language;
8431e4b17023SJohn Marino    otherwise, print an error message and return zero.  USE says
8432e4b17023SJohn Marino    how the lvalue is being used and so selects the error message.  */
8433e4b17023SJohn Marino 
8434e4b17023SJohn Marino int
lvalue_or_else(tree ref,enum lvalue_use use,tsubst_flags_t complain)8435e4b17023SJohn Marino lvalue_or_else (tree ref, enum lvalue_use use, tsubst_flags_t complain)
8436e4b17023SJohn Marino {
8437e4b17023SJohn Marino   cp_lvalue_kind kind = lvalue_kind (ref);
8438e4b17023SJohn Marino 
8439e4b17023SJohn Marino   if (kind == clk_none)
8440e4b17023SJohn Marino     {
8441e4b17023SJohn Marino       if (complain & tf_error)
8442e4b17023SJohn Marino 	lvalue_error (input_location, use);
8443e4b17023SJohn Marino       return 0;
8444e4b17023SJohn Marino     }
8445e4b17023SJohn Marino   else if (kind & (clk_rvalueref|clk_class))
8446e4b17023SJohn Marino     {
8447e4b17023SJohn Marino       if (!(complain & tf_error))
8448e4b17023SJohn Marino 	return 0;
8449e4b17023SJohn Marino       if (kind & clk_class)
8450e4b17023SJohn Marino 	/* Make this a permerror because we used to accept it.  */
8451e4b17023SJohn Marino 	permerror (input_location, "using temporary as lvalue");
8452e4b17023SJohn Marino       else
8453e4b17023SJohn Marino 	error ("using xvalue (rvalue reference) as lvalue");
8454e4b17023SJohn Marino     }
8455e4b17023SJohn Marino   return 1;
8456e4b17023SJohn Marino }
8457e4b17023SJohn Marino 
8458e4b17023SJohn Marino /* Return true if a user-defined literal operator is a raw operator.  */
8459e4b17023SJohn Marino 
8460e4b17023SJohn Marino bool
check_raw_literal_operator(const_tree decl)8461e4b17023SJohn Marino check_raw_literal_operator (const_tree decl)
8462e4b17023SJohn Marino {
8463e4b17023SJohn Marino   tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl));
8464e4b17023SJohn Marino   tree argtype;
8465e4b17023SJohn Marino   int arity;
8466e4b17023SJohn Marino   bool maybe_raw_p = false;
8467e4b17023SJohn Marino 
8468e4b17023SJohn Marino   /* Count the number and type of arguments and check for ellipsis.  */
8469e4b17023SJohn Marino   for (argtype = argtypes, arity = 0;
8470e4b17023SJohn Marino        argtype && argtype != void_list_node;
8471e4b17023SJohn Marino        ++arity, argtype = TREE_CHAIN (argtype))
8472e4b17023SJohn Marino     {
8473e4b17023SJohn Marino       tree t = TREE_VALUE (argtype);
8474e4b17023SJohn Marino 
8475e4b17023SJohn Marino       if (same_type_p (t, const_string_type_node))
8476e4b17023SJohn Marino 	maybe_raw_p = true;
8477e4b17023SJohn Marino     }
8478e4b17023SJohn Marino   if (!argtype)
8479e4b17023SJohn Marino     return false; /* Found ellipsis.  */
8480e4b17023SJohn Marino 
8481e4b17023SJohn Marino   if (!maybe_raw_p || arity != 1)
8482e4b17023SJohn Marino     return false;
8483e4b17023SJohn Marino 
8484e4b17023SJohn Marino   return true;
8485e4b17023SJohn Marino }
8486e4b17023SJohn Marino 
8487e4b17023SJohn Marino 
8488e4b17023SJohn Marino /* Return true if a user-defined literal operator has one of the allowed
8489e4b17023SJohn Marino    argument types.  */
8490e4b17023SJohn Marino 
8491e4b17023SJohn Marino bool
check_literal_operator_args(const_tree decl,bool * long_long_unsigned_p,bool * long_double_p)8492e4b17023SJohn Marino check_literal_operator_args (const_tree decl,
8493e4b17023SJohn Marino 			     bool *long_long_unsigned_p, bool *long_double_p)
8494e4b17023SJohn Marino {
8495e4b17023SJohn Marino   tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl));
8496e4b17023SJohn Marino 
8497e4b17023SJohn Marino   *long_long_unsigned_p = false;
8498e4b17023SJohn Marino   *long_double_p = false;
8499e4b17023SJohn Marino   if (processing_template_decl || processing_specialization)
8500e4b17023SJohn Marino     return argtypes == void_list_node;
8501e4b17023SJohn Marino   else
8502e4b17023SJohn Marino     {
8503e4b17023SJohn Marino       tree argtype;
8504e4b17023SJohn Marino       int arity;
8505e4b17023SJohn Marino       int max_arity = 2;
8506e4b17023SJohn Marino 
8507e4b17023SJohn Marino       /* Count the number and type of arguments and check for ellipsis.  */
8508e4b17023SJohn Marino       for (argtype = argtypes, arity = 0;
8509e4b17023SJohn Marino 	   argtype && argtype != void_list_node;
8510e4b17023SJohn Marino 	   argtype = TREE_CHAIN (argtype))
8511e4b17023SJohn Marino 	{
8512e4b17023SJohn Marino 	  tree t = TREE_VALUE (argtype);
8513e4b17023SJohn Marino 	  ++arity;
8514e4b17023SJohn Marino 
8515e4b17023SJohn Marino 	  if (TREE_CODE (t) == POINTER_TYPE)
8516e4b17023SJohn Marino 	    {
8517e4b17023SJohn Marino 	      bool maybe_raw_p = false;
8518e4b17023SJohn Marino 	      t = TREE_TYPE (t);
8519e4b17023SJohn Marino 	      if (cp_type_quals (t) != TYPE_QUAL_CONST)
8520e4b17023SJohn Marino 		return false;
8521e4b17023SJohn Marino 	      t = TYPE_MAIN_VARIANT (t);
8522e4b17023SJohn Marino 	      if ((maybe_raw_p = same_type_p (t, char_type_node))
8523e4b17023SJohn Marino 		  || same_type_p (t, wchar_type_node)
8524e4b17023SJohn Marino 		  || same_type_p (t, char16_type_node)
8525e4b17023SJohn Marino 		  || same_type_p (t, char32_type_node))
8526e4b17023SJohn Marino 		{
8527e4b17023SJohn Marino 		  argtype = TREE_CHAIN (argtype);
8528e4b17023SJohn Marino 		  if (!argtype)
8529e4b17023SJohn Marino 		    return false;
8530e4b17023SJohn Marino 		  t = TREE_VALUE (argtype);
8531e4b17023SJohn Marino 		  if (maybe_raw_p && argtype == void_list_node)
8532e4b17023SJohn Marino 		    return true;
8533e4b17023SJohn Marino 		  else if (same_type_p (t, size_type_node))
8534e4b17023SJohn Marino 		    {
8535e4b17023SJohn Marino 		      ++arity;
8536e4b17023SJohn Marino 		      continue;
8537e4b17023SJohn Marino 		    }
8538e4b17023SJohn Marino 		  else
8539e4b17023SJohn Marino 		    return false;
8540e4b17023SJohn Marino 		}
8541e4b17023SJohn Marino 	    }
8542e4b17023SJohn Marino 	  else if (same_type_p (t, long_long_unsigned_type_node))
8543e4b17023SJohn Marino 	    {
8544e4b17023SJohn Marino 	      max_arity = 1;
8545e4b17023SJohn Marino 	      *long_long_unsigned_p = true;
8546e4b17023SJohn Marino 	    }
8547e4b17023SJohn Marino 	  else if (same_type_p (t, long_double_type_node))
8548e4b17023SJohn Marino 	    {
8549e4b17023SJohn Marino 	      max_arity = 1;
8550e4b17023SJohn Marino 	      *long_double_p = true;
8551e4b17023SJohn Marino 	    }
8552e4b17023SJohn Marino 	  else if (same_type_p (t, char_type_node))
8553e4b17023SJohn Marino 	    max_arity = 1;
8554e4b17023SJohn Marino 	  else if (same_type_p (t, wchar_type_node))
8555e4b17023SJohn Marino 	    max_arity = 1;
8556e4b17023SJohn Marino 	  else if (same_type_p (t, char16_type_node))
8557e4b17023SJohn Marino 	    max_arity = 1;
8558e4b17023SJohn Marino 	  else if (same_type_p (t, char32_type_node))
8559e4b17023SJohn Marino 	    max_arity = 1;
8560e4b17023SJohn Marino 	  else
8561e4b17023SJohn Marino 	    return false;
8562e4b17023SJohn Marino 	}
8563e4b17023SJohn Marino       if (!argtype)
8564e4b17023SJohn Marino 	return false; /* Found ellipsis.  */
8565e4b17023SJohn Marino 
8566e4b17023SJohn Marino       if (arity != max_arity)
8567e4b17023SJohn Marino 	return false;
8568e4b17023SJohn Marino 
8569e4b17023SJohn Marino       return true;
8570e4b17023SJohn Marino     }
8571e4b17023SJohn Marino }
8572