diff options
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/call.c | 14 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 5 | ||||
-rw-r--r-- | gcc/cp/init.c | 12 | ||||
-rw-r--r-- | gcc/cp/method.c | 7 |
5 files changed, 33 insertions, 13 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index b04f33a..e8329c1 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,13 @@ 2010-12-08 Jason Merrill <jason@redhat.com> + PR c++/45822 + * cp-tree.h (LOOKUP_DEFAULTED): New. + * call.c (add_function_candidate): Check it. + * method.c (synthesized_method_walk): Set it. + (do_build_copy_assign): Likewise. + * init.c (perform_member_init): Likewise. + (emit_mem_initializers): Likewise. + PR c++/46736 * decl.c (cp_finish_decl): Complain about an implicitly deleted method defaulted outside the class. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index d538cf2..1e0b328 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -1645,13 +1645,10 @@ add_function_candidate (struct z_candidate **candidates, else if (!sufficient_parms_p (parmnode)) viable = 0; - /* Kludge: When looking for a function from a subobject while generating - an implicit copy/move constructor/operator=, don't consider anything - that takes (a reference to) an unrelated type. See c++/44909. */ - else if (parmlist - && ((flags & LOOKUP_SPECULATIVE) - || (current_function_decl - && DECL_DEFAULTED_FN (current_function_decl)))) + /* When looking for a function from a subobject from an implicit + copy/move constructor/operator=, don't consider anything that takes (a + reference to) an unrelated type. See c++/44909 and core 1092. */ + else if (parmlist && (flags & LOOKUP_DEFAULTED)) { if (DECL_CONSTRUCTOR_P (fn)) i = 1; @@ -1667,6 +1664,9 @@ add_function_candidate (struct z_candidate **candidates, ctype)) viable = 0; } + + /* This only applies at the top level. */ + flags &= ~LOOKUP_DEFAULTED; } if (! viable) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index aba8dfd..03c02fc 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4227,9 +4227,12 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, TYPENAME_FLAG }; another mechanism. Exiting early also avoids problems with trying to perform argument conversions when the class isn't complete yet. */ #define LOOKUP_SPECULATIVE (LOOKUP_LIST_ONLY << 1) +/* Used by calls from defaulted functions to limit the overload set to avoid + cycles trying to declare them (core issue 1092). */ +#define LOOKUP_DEFAULTED (LOOKUP_SPECULATIVE << 1) /* Used in calls to store_init_value to suppress its usual call to digest_init. */ -#define LOOKUP_ALREADY_DIGESTED (LOOKUP_SPECULATIVE << 1) +#define LOOKUP_ALREADY_DIGESTED (LOOKUP_DEFAULTED << 1) #define LOOKUP_NAMESPACES_ONLY(F) \ (((F) & LOOKUP_PREFER_NAMESPACES) && !((F) & LOOKUP_PREFER_TYPES)) diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 9de8c9f6..5a4f91c 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -503,6 +503,9 @@ perform_member_init (tree member, tree init) } else { + int flags = LOOKUP_NORMAL; + if (DECL_DEFAULTED_FN (current_function_decl)) + flags |= LOOKUP_DEFAULTED; if (CP_TYPE_CONST_P (type) && init == NULL_TREE && !type_has_user_provided_default_constructor (type)) @@ -511,7 +514,7 @@ perform_member_init (tree member, tree init) permerror (DECL_SOURCE_LOCATION (current_function_decl), "uninitialized member %qD with %<const%> type %qT", member, type); - finish_expr_stmt (build_aggr_init (decl, init, 0, + finish_expr_stmt (build_aggr_init (decl, init, flags, tf_warning_or_error)); } } @@ -852,11 +855,16 @@ sort_mem_initializers (tree t, tree mem_inits) void emit_mem_initializers (tree mem_inits) { + int flags = LOOKUP_NORMAL; + /* We will already have issued an error message about the fact that the type is incomplete. */ if (!COMPLETE_TYPE_P (current_class_type)) return; + if (DECL_DEFAULTED_FN (current_function_decl)) + flags |= LOOKUP_DEFAULTED; + /* Sort the mem-initializers into the order in which the initializations should be performed. */ mem_inits = sort_mem_initializers (current_class_type, mem_inits); @@ -908,7 +916,7 @@ emit_mem_initializers (tree mem_inits) cp_build_indirect_ref (base_addr, RO_NULL, tf_warning_or_error), arguments, - LOOKUP_NORMAL, + flags, tf_warning_or_error); expand_cleanup_for_base (subobject, NULL_TREE); } diff --git a/gcc/cp/method.c b/gcc/cp/method.c index dc72355..149910c 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -583,6 +583,7 @@ do_build_copy_assign (tree fndecl) tree compound_stmt; bool move_p = move_fn_p (fndecl); bool trivial = trivial_fn_p (fndecl); + int flags = LOOKUP_NORMAL | LOOKUP_NONVIRTUAL | LOOKUP_DEFAULTED; compound_stmt = begin_compound_stmt (0); parm = convert_from_reference (parm); @@ -622,7 +623,7 @@ do_build_copy_assign (tree fndecl) ansi_assopname (NOP_EXPR), &parmvec, base_binfo, - LOOKUP_NORMAL | LOOKUP_NONVIRTUAL, + flags, tf_warning_or_error)); release_tree_vector (parmvec); } @@ -1175,12 +1176,12 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p, if (diag) { - flags = LOOKUP_NORMAL|LOOKUP_SPECULATIVE; + flags = LOOKUP_NORMAL|LOOKUP_SPECULATIVE|LOOKUP_DEFAULTED; complain = tf_warning_or_error; } else { - flags = LOOKUP_PROTECT|LOOKUP_SPECULATIVE; + flags = LOOKUP_PROTECT|LOOKUP_SPECULATIVE|LOOKUP_DEFAULTED; complain = tf_none; } |