summaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2012-03-08 10:11:09 +0000
committerbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2012-03-08 10:11:09 +0000
commit6195c0dd4e15f50ac89491b48e050751f8231304 (patch)
tree1f49de2cfcd902f18c22b5539315d7b0fb4db972 /gcc/cp
parentd7ce7f9586bca838e0dcc7e39100ffe6edcd74f3 (diff)
downloadgcc-6195c0dd4e15f50ac89491b48e050751f8231304.tar.gz
2012-03-08 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk [future 4.8] rev 185094 using svnmerge 2011-03-08 Basile Starynkevitch <basile@starynkevitch.net> [gcc/] * melt-build.tpl (meltframe.args): Add -Iinclude-fixed if it exists. * melt-build.mk: Regenerate. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@185096 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog64
-rw-r--r--gcc/cp/call.c5
-rw-r--r--gcc/cp/class.c10
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/decl.c24
-rw-r--r--gcc/cp/decl2.c35
-rw-r--r--gcc/cp/init.c6
-rw-r--r--gcc/cp/mangle.c28
-rw-r--r--gcc/cp/method.c7
-rw-r--r--gcc/cp/name-lookup.c15
-rw-r--r--gcc/cp/parser.c6
-rw-r--r--gcc/cp/pt.c55
-rw-r--r--gcc/cp/search.c10
-rw-r--r--gcc/cp/typeck2.c28
14 files changed, 194 insertions, 101 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 2c81a8a4119..69677aea99a 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,67 @@
+2012-03-07 Jason Merrill <jason@redhat.com>
+
+ PR c++/52521
+ * mangle.c (write_literal_operator_name): The length comes after the
+ operator prefix.
+
+2012-03-05 Jakub Jelinek <jakub@redhat.com>
+
+ * pt.c (local_specializations): Change from htab_t into
+ struct pointer_map_t *.
+ (retrieve_local_specializations, register_local_specialization,
+ tsubst_pack_expansion, instantiate_decl): Adjust users.
+ (eq_local_specializations, hash_local_specialization): Remove.
+
+2012-03-05 Jason Merrill <jason@redhat.com>
+
+ PR c++/51930
+ * decl2.c (determine_visibility): Correct calculation of class
+ args depth.
+ * decl.c (check_tag_decl): Adjust warning.
+
+ * method.c (synthesized_method_walk): Cleanups don't affect the EH
+ spec either.
+
+2012-03-03 Jason Merrill <jason@redhat.com>
+
+ * init.c (perform_member_init): Cope with uninstantiated NSDMI.
+
+ Core 1270
+ * call.c (build_aggr_conv): Call reshape_init.
+ (convert_like_real): Likewise.
+ * typeck2.c (process_init_constructor): Clear TREE_CONSTANT if
+ not all constant.
+
+ * mangle.c (write_nested_name): Use decl_mangling_context.
+ (write_prefix, write_template_prefix): Likewise.
+
+ PR c++/36797
+ * mangle.c (write_expression): Improve diagnostic for TRAIT_EXPR.
+
+ * class.c (add_method): Always build an OVERLOAD for using-decls.
+ * search.c (lookup_member): Handle getting an OVERLOAD for a
+ single function.
+
+2012-03-02 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51989
+ * typeck2.c (build_x_arrow): Take a tsubst_flags_t argument and
+ propagate it.
+ * cp-tree.h (build_x_arrow): Adjust prototype.
+ * pt.c (tsubst_copy_and_build): Adjust call.
+ * parser.c (cp_parser_postfix_dot_deref_expression): Likewise.
+
+2012-03-02 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * name-lookup.c (binding_to_template_parms_of_scope_p): Clean up.
+
+2012-02-29 Jason Merrill <jason@redhat.com>
+
+ PR c++/51930
+ * decl.c (check_tag_decl): Move warning for misplaced attributes here.
+ (shadow_tag): From here.
+ * parser.c (cp_parser_explicit_instantiation): Don't warn here.
+
2012-02-21 Jakub Jelinek <jakub@redhat.com>
PR c++/52312
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index c962ca0bd53..8baad827f6d 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -886,6 +886,10 @@ build_aggr_conv (tree type, tree ctor, int flags)
tree field = next_initializable_field (TYPE_FIELDS (type));
tree empty_ctor = NULL_TREE;
+ ctor = reshape_init (type, ctor, tf_none);
+ if (ctor == error_mark_node)
+ return NULL;
+
for (; field; field = next_initializable_field (DECL_CHAIN (field)))
{
tree ftype = TREE_TYPE (field);
@@ -5795,6 +5799,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
expr = build2 (COMPLEX_EXPR, totype, real, imag);
return fold_if_not_in_template (expr);
}
+ expr = reshape_init (totype, expr, complain);
return get_target_expr (digest_init (totype, expr, complain));
default:
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 5d834d9ae5d..6ed4cde6b51 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -1117,9 +1117,13 @@ add_method (tree type, tree method, tree using_decl)
return false;
/* Add the new binding. */
- overload = build_overload (method, current_fns);
- if (using_decl && TREE_CODE (overload) == OVERLOAD)
- OVL_USED (overload) = true;
+ if (using_decl)
+ {
+ overload = ovl_cons (method, current_fns);
+ OVL_USED (overload) = true;
+ }
+ else
+ overload = build_overload (method, current_fns);
if (conv_p)
TYPE_HAS_CONVERSION (type) = 1;
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index d435dbdaa0a..71573ff0b37 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5880,7 +5880,7 @@ extern void check_narrowing (tree, tree);
extern tree digest_init (tree, tree, tsubst_flags_t);
extern tree digest_init_flags (tree, tree, int);
extern tree build_scoped_ref (tree, tree, tree *);
-extern tree build_x_arrow (tree);
+extern tree build_x_arrow (tree, tsubst_flags_t);
extern tree build_m_component_ref (tree, tree);
extern tree build_functional_cast (tree, tree, tsubst_flags_t);
extern tree add_exception_specifier (tree, tree, int);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 2a6a5160fb6..a18b312841d 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -4216,6 +4216,22 @@ check_tag_decl (cp_decl_specifier_seq *declspecs)
error ("%<constexpr%> cannot be used for type declarations");
}
+ if (declspecs->attributes && warn_attributes)
+ {
+ location_t loc;
+ if (!CLASSTYPE_TEMPLATE_INSTANTIATION (declared_type))
+ /* For a non-template class, use the name location. */
+ loc = location_of (declared_type);
+ else
+ /* For a template class (an explicit instantiation), use the
+ current location. */
+ loc = input_location;
+ warning_at (loc, OPT_Wattributes, "attribute ignored in declaration "
+ "of %q#T", declared_type);
+ inform (loc, "attribute for %q#T must follow the %qs keyword",
+ declared_type, class_key_or_enum_as_string (declared_type));
+ }
+
return declared_type;
}
@@ -4240,14 +4256,6 @@ shadow_tag (cp_decl_specifier_seq *declspecs)
if (!t)
return NULL_TREE;
- if (declspecs->attributes)
- {
- warning (0, "attribute ignored in declaration of %q+#T", t);
- warning (0, "attribute for %q+#T must follow the %qs keyword",
- t, class_key_or_enum_as_string (t));
-
- }
-
if (maybe_process_partial_specialization (t) == error_mark_node)
return NULL_TREE;
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index bdc962abcf9..7eccf672546 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -2181,12 +2181,8 @@ determine_visibility (tree decl)
? TYPE_ATTRIBUTES (TREE_TYPE (decl))
: DECL_ATTRIBUTES (decl));
- if (args != error_mark_node
- /* Template argument visibility outweighs #pragma or namespace
- visibility, but not an explicit attribute. */
- && !lookup_attribute ("visibility", attribs))
+ if (args != error_mark_node)
{
- int depth = TMPL_ARGS_DEPTH (args);
tree pattern = DECL_TEMPLATE_RESULT (TI_TEMPLATE (tinfo));
if (!DECL_VISIBILITY_SPECIFIED (decl))
@@ -2202,10 +2198,31 @@ determine_visibility (tree decl)
}
}
- /* FIXME should TMPL_ARGS_DEPTH really return 1 for null input? */
- if (args && depth > template_class_depth (class_type))
- /* Limit visibility based on its template arguments. */
- constrain_visibility_for_template (decl, args);
+ if (args
+ /* Template argument visibility outweighs #pragma or namespace
+ visibility, but not an explicit attribute. */
+ && !lookup_attribute ("visibility", attribs))
+ {
+ int depth = TMPL_ARGS_DEPTH (args);
+ int class_depth = 0;
+ if (class_type && CLASSTYPE_TEMPLATE_INFO (class_type))
+ class_depth = TMPL_ARGS_DEPTH (CLASSTYPE_TI_ARGS (class_type));
+ if (DECL_VISIBILITY_SPECIFIED (decl))
+ {
+ /* A class template member with explicit visibility
+ overrides the class visibility, so we need to apply
+ all the levels of template args directly. */
+ int i;
+ for (i = 1; i <= depth; ++i)
+ {
+ tree lev = TMPL_ARGS_LEVEL (args, i);
+ constrain_visibility_for_template (decl, lev);
+ }
+ }
+ else if (depth > class_depth)
+ /* Limit visibility based on its template arguments. */
+ constrain_visibility_for_template (decl, args);
+ }
}
}
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 2355a04de23..1b2a1ef15ae 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -540,6 +540,12 @@ perform_member_init (tree member, tree init)
else
{
init = DECL_INITIAL (member);
+ if (init && TREE_CODE (init) == DEFAULT_ARG)
+ {
+ error ("constructor required before non-static data member "
+ "for %qD has been parsed", member);
+ init = NULL_TREE;
+ }
/* Strip redundant TARGET_EXPR so we don't need to remap it, and
so the aggregate init code below will see a CONSTRUCTOR. */
if (init && TREE_CODE (init) == TARGET_EXPR
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index 34f19efc42e..5d6beb5d578 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -942,7 +942,7 @@ write_nested_name (const tree decl)
}
else
{
- write_prefix (CP_DECL_CONTEXT (decl));
+ write_prefix (decl_mangling_context (decl));
write_unqualified_name (decl);
}
}
@@ -1030,7 +1030,7 @@ write_prefix (const tree node)
}
else
{
- write_prefix (CP_DECL_CONTEXT (decl));
+ write_prefix (decl_mangling_context (decl));
write_unqualified_name (decl);
}
}
@@ -1060,7 +1060,7 @@ write_template_prefix (const tree node)
{
tree decl = DECL_P (node) ? node : TYPE_NAME (node);
tree type = DECL_P (node) ? TREE_TYPE (node) : node;
- tree context = CP_DECL_CONTEXT (decl);
+ tree context = decl_mangling_context (decl);
tree template_info;
tree templ;
tree substitution;
@@ -1292,18 +1292,16 @@ write_source_name (tree identifier)
}
/* Write a user-defined literal operator.
+ ::= li <source-name> # "" <source-name>
IDENTIFIER is an LITERAL_IDENTIFIER_NODE. */
static void
write_literal_operator_name (tree identifier)
{
const char* suffix = UDLIT_OP_SUFFIX (identifier);
- char* buffer = XNEWVEC (char, strlen (UDLIT_OP_MANGLED_PREFIX)
- + strlen (suffix) + 10);
- sprintf (buffer, UDLIT_OP_MANGLED_FORMAT, suffix);
-
- write_unsigned_number (strlen (buffer));
- write_identifier (buffer);
+ write_identifier (UDLIT_OP_MANGLED_PREFIX);
+ write_unsigned_number (strlen (suffix));
+ write_identifier (suffix);
}
/* Encode 0 as _, and 1+ as n-1_. */
@@ -2808,7 +2806,17 @@ write_expression (tree expr)
if (name == NULL)
{
- sorry ("mangling %C", code);
+ switch (code)
+ {
+ case TRAIT_EXPR:
+ error ("use of built-in trait %qE in function signature; "
+ "use library traits instead", expr);
+ break;
+
+ default:
+ sorry ("mangling %C", code);
+ break;
+ }
return;
}
else
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index cf2a713aa2a..07189168d1f 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -1272,8 +1272,11 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
rval = locate_fn_flags (base_binfo, complete_dtor_identifier,
NULL_TREE, flags, complain);
/* Note that we don't pass down trivial_p; the subobject
- destructors don't affect triviality of the constructor. */
- process_subob_fn (rval, false, spec_p, NULL,
+ destructors don't affect triviality of the constructor. Nor
+ do they affect constexpr-ness (a constant expression doesn't
+ throw) or exception-specification (a throw from one of the
+ dtors would be a double-fault). */
+ process_subob_fn (rval, false, NULL, NULL,
deleted_p, NULL, NULL,
basetype);
}
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 235134249ac..e85d603d22f 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -4467,20 +4467,17 @@ binding_to_template_parms_of_scope_p (cxx_binding *binding,
cp_binding_level *scope)
{
tree binding_value;
+ tree tinfo;
- if (!binding || !scope)
+ if (!binding || !scope || !scope->this_entity)
return false;
binding_value = binding->value ? binding->value : binding->type;
+ tinfo = get_template_info (scope->this_entity);
- return (scope
- && scope->this_entity
- && get_template_info (scope->this_entity)
- && PRIMARY_TEMPLATE_P (TI_TEMPLATE
- (get_template_info (scope->this_entity)))
- && parameter_of_template_p (binding_value,
- TI_TEMPLATE (get_template_info \
- (scope->this_entity))));
+ return (tinfo
+ && PRIMARY_TEMPLATE_P (TI_TEMPLATE (tinfo))
+ && parameter_of_template_p (binding_value, TI_TEMPLATE (tinfo)));
}
/* Return the innermost non-namespace binding for NAME from a scope
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 3e2be97f9c9..c6bd2906203 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -5910,7 +5910,8 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
/* If this is a `->' operator, dereference the pointer. */
if (token_type == CPP_DEREF)
- postfix_expression = build_x_arrow (postfix_expression);
+ postfix_expression = build_x_arrow (postfix_expression,
+ tf_warning_or_error);
/* Check to see whether or not the expression is type-dependent. */
dependent_p = type_dependent_expression_p (postfix_expression);
/* The identifier following the `->' or `.' is not qualified. */
@@ -13122,9 +13123,6 @@ cp_parser_explicit_instantiation (cp_parser* parser)
tree type;
type = check_tag_decl (&decl_specifiers);
- if (decl_specifiers.attributes)
- warning (OPT_Wattributes,
- "attributes ignored on explicit type instantiation");
/* Turn access control back on for names used during
template instantiation. */
pop_deferring_access_checks ();
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index c9cd953decc..4980c19ae06 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -79,7 +79,7 @@ static tree cur_stmt_expr;
/* A map from local variable declarations in the body of the template
presently being instantiated to the corresponding instantiated
local variables. */
-static htab_t local_specializations;
+static struct pointer_map_t *local_specializations;
typedef struct GTY(()) spec_entry
{
@@ -189,7 +189,6 @@ static tree for_each_template_parm_r (tree *, int *, void *);
static tree copy_default_args_to_explicit_spec_1 (tree, tree);
static void copy_default_args_to_explicit_spec (tree);
static int invalid_nontype_parm_type_p (tree, tsubst_flags_t);
-static int eq_local_specializations (const void *, const void *);
static bool dependent_template_arg_p (tree);
static bool any_template_arguments_need_structural_equality_p (tree);
static bool dependent_type_p_r (tree);
@@ -1078,14 +1077,13 @@ retrieve_specialization (tree tmpl, tree args, hashval_t hash)
static tree
retrieve_local_specialization (tree tmpl)
{
- tree spec;
+ void **slot;
if (local_specializations == NULL)
return NULL_TREE;
- spec = (tree) htab_find_with_hash (local_specializations, tmpl,
- htab_hash_pointer (tmpl));
- return spec ? TREE_PURPOSE (spec) : NULL_TREE;
+ slot = pointer_map_contains (local_specializations, tmpl);
+ return slot ? (tree) *slot : NULL_TREE;
}
/* Returns nonzero iff DECL is a specialization of TMPL. */
@@ -1677,24 +1675,6 @@ reregister_specialization (tree spec, tree tinfo, tree new_spec)
return 0;
}
-/* Compare an entry in the local specializations hash table P1 (which
- is really a pointer to a TREE_LIST) with P2 (which is really a
- DECL). */
-
-static int
-eq_local_specializations (const void *p1, const void *p2)
-{
- return TREE_VALUE ((const_tree) p1) == (const_tree) p2;
-}
-
-/* Hash P1, an entry in the local specializations table. */
-
-static hashval_t
-hash_local_specialization (const void* p1)
-{
- return htab_hash_pointer (TREE_VALUE ((const_tree) p1));
-}
-
/* Like register_specialization, but for local declarations. We are
registering SPEC, an instantiation of TMPL. */
@@ -1703,9 +1683,8 @@ register_local_specialization (tree spec, tree tmpl)
{
void **slot;
- slot = htab_find_slot_with_hash (local_specializations, tmpl,
- htab_hash_pointer (tmpl), INSERT);
- *slot = build_tree_list (spec, tmpl);
+ slot = pointer_map_insert (local_specializations, tmpl);
+ *slot = spec;
}
/* TYPE is a class type. Returns true if TYPE is an explicitly
@@ -9307,7 +9286,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
int missing_level = 0;
int i, len = -1;
tree result;
- htab_t saved_local_specializations = NULL;
+ struct pointer_map_t *saved_local_specializations = NULL;
bool need_local_specializations = false;
int levels;
@@ -9492,14 +9471,11 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
if (need_local_specializations)
{
/* We're in a late-specified return type, so create our own local
- specializations table; the current table is either NULL or (in the
+ specializations map; the current map is either NULL or (in the
case of recursive unification) might have bindings that we don't
want to use or alter. */
saved_local_specializations = local_specializations;
- local_specializations = htab_create (37,
- hash_local_specialization,
- eq_local_specializations,
- NULL);
+ local_specializations = pointer_map_create ();
}
/* For each argument in each argument pack, substitute into the
@@ -9586,7 +9562,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
if (need_local_specializations)
{
- htab_delete (local_specializations);
+ pointer_map_destroy (local_specializations);
local_specializations = saved_local_specializations;
}
@@ -13691,7 +13667,7 @@ tsubst_copy_and_build (tree t,
/* Remember that there was a reference to this entity. */
if (DECL_P (op1))
mark_used (op1);
- return build_x_arrow (op1);
+ return build_x_arrow (op1, complain);
case NEW_EXPR:
{
@@ -18704,7 +18680,7 @@ instantiate_decl (tree d, int defer_ok,
synthesize_method (d);
else if (TREE_CODE (d) == FUNCTION_DECL)
{
- htab_t saved_local_specializations;
+ struct pointer_map_t *saved_local_specializations;
tree subst_decl;
tree tmpl_parm;
tree spec_parm;
@@ -18714,10 +18690,7 @@ instantiate_decl (tree d, int defer_ok,
saved_local_specializations = local_specializations;
/* Set up the list of local specializations. */
- local_specializations = htab_create (37,
- hash_local_specialization,
- eq_local_specializations,
- NULL);
+ local_specializations = pointer_map_create ();
/* Set up context. */
start_preparsed_function (d, NULL_TREE, SF_PRE_PARSED);
@@ -18759,7 +18732,7 @@ instantiate_decl (tree d, int defer_ok,
input_location = DECL_STRUCT_FUNCTION (code_pattern)->function_end_locus;
/* We don't need the local specializations any more. */
- htab_delete (local_specializations);
+ pointer_map_destroy (local_specializations);
local_specializations = saved_local_specializations;
/* Finish the function. */
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index e48dcec0589..a1f8a3db173 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -1250,10 +1250,12 @@ lookup_member (tree xbasetype, tree name, int protect, bool want_type,
only the first call to "f" is valid. However, if the function is
static, we can check. */
if (rval && protect
- && !really_overloaded_fn (rval)
- && !(TREE_CODE (rval) == FUNCTION_DECL
- && DECL_NONSTATIC_MEMBER_FUNCTION_P (rval)))
- perform_or_defer_access_check (basetype_path, rval, rval);
+ && !really_overloaded_fn (rval))
+ {
+ tree decl = is_overloaded_fn (rval) ? get_first_fn (rval) : rval;
+ if (!DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
+ perform_or_defer_access_check (basetype_path, decl, decl);
+ }
if (errstr && protect)
{
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 7793744ae4f..974f92ff89c 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -1392,7 +1392,10 @@ process_init_constructor (tree type, tree init, tsubst_flags_t complain)
TREE_TYPE (init) = type;
if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type) == NULL_TREE)
cp_complete_array_type (&TREE_TYPE (init), init, /*do_default=*/0);
- if (!(flags & PICFLAG_NOT_ALL_CONSTANT))
+ if (flags & PICFLAG_NOT_ALL_CONSTANT)
+ /* Make sure TREE_CONSTANT isn't set from build_constructor. */
+ TREE_CONSTANT (init) = false;
+ else
{
TREE_CONSTANT (init) = 1;
if (!(flags & PICFLAG_NOT_ALL_SIMPLE))
@@ -1462,7 +1465,7 @@ build_scoped_ref (tree datum, tree basetype, tree* binfo_p)
delegation is detected. */
tree
-build_x_arrow (tree expr)
+build_x_arrow (tree expr, tsubst_flags_t complain)
{
tree orig_expr = expr;
tree type = TREE_TYPE (expr);
@@ -1486,7 +1489,7 @@ build_x_arrow (tree expr)
while ((expr = build_new_op (COMPONENT_REF, LOOKUP_NORMAL, expr,
NULL_TREE, NULL_TREE,
- &fn, tf_warning_or_error)))
+ &fn, complain)))
{
if (expr == error_mark_node)
return error_mark_node;
@@ -1497,7 +1500,8 @@ build_x_arrow (tree expr)
if (vec_member (TREE_TYPE (expr), types_memoized))
{
- error ("circular pointer delegation detected");
+ if (complain & tf_error)
+ error ("circular pointer delegation detected");
return error_mark_node;
}
@@ -1510,7 +1514,8 @@ build_x_arrow (tree expr)
if (last_rval == NULL_TREE)
{
- error ("base operand of %<->%> has non-pointer type %qT", type);
+ if (complain & tf_error)
+ error ("base operand of %<->%> has non-pointer type %qT", type);
return error_mark_node;
}
@@ -1530,13 +1535,16 @@ build_x_arrow (tree expr)
return expr;
}
- return cp_build_indirect_ref (last_rval, RO_NULL, tf_warning_or_error);
+ return cp_build_indirect_ref (last_rval, RO_NULL, complain);
}
- if (types_memoized)
- error ("result of %<operator->()%> yields non-pointer result");
- else
- error ("base operand of %<->%> is not a pointer");
+ if (complain & tf_error)
+ {
+ if (types_memoized)
+ error ("result of %<operator->()%> yields non-pointer result");
+ else
+ error ("base operand of %<->%> is not a pointer");
+ }
return error_mark_node;
}