aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/call.c14
-rw-r--r--gcc/cp/cp-tree.h5
-rw-r--r--gcc/cp/init.c12
-rw-r--r--gcc/cp/method.c7
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/g++.dg/init/synth4.C18
7 files changed, 54 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;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f0aeca5..e505dad 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
2010-12-08 Jason Merrill <jason@redhat.com>
+ PR c++/45822
+ * g++.dg/init/synth4.C: New.
+
PR c++/46736
* g++.dg/cpp0x/defaulted21.C: New.
diff --git a/gcc/testsuite/g++.dg/init/synth4.C b/gcc/testsuite/g++.dg/init/synth4.C
new file mode 100644
index 0000000..2b0b0b9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/synth4.C
@@ -0,0 +1,18 @@
+// PR c++/45822
+
+struct A
+{
+ A(int);
+};
+
+struct B
+{
+ B(A = 0);
+};
+
+struct C
+{
+ B b;
+};
+
+C c;