aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2012-12-06 15:21:08 -0500
committerJason Merrill <jason@gcc.gnu.org>2012-12-06 15:21:08 -0500
commit5cd5a78c9b13d563f8fae2ed4f619ff5705863bf (patch)
treea29426df85df5c1f3893e6c6b00b12bea934c634
parent1e8671f733a879525232e2e2f7b77d00362032d7 (diff)
downloadgcc-5cd5a78c9b13d563f8fae2ed4f619ff5705863bf.zip
gcc-5cd5a78c9b13d563f8fae2ed4f619ff5705863bf.tar.gz
gcc-5cd5a78c9b13d563f8fae2ed4f619ff5705863bf.tar.bz2
re PR c++/54744 (internal compiler error: Segmentation fault, by dependent base, member typedef and ctor-initializer)
PR c++/54744 * pt.c (resolve_typename_type): Check TYPENAME_IS_RESOLVING_P on scope. * init.c (expand_member_init): Check for being in a template first. * parser.c (cp_parser_mem_initializer_list): Only check class types for equivalence to the current class. From-SVN: r194267
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/init.c4
-rw-r--r--gcc/cp/parser.c2
-rw-r--r--gcc/cp/pt.c11
-rw-r--r--gcc/testsuite/g++.dg/template/meminit3.C12
5 files changed, 31 insertions, 4 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 28f8c67..bcad0c2 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,11 @@
2012-12-06 Jason Merrill <jason@redhat.com>
+ PR c++/54744
+ * pt.c (resolve_typename_type): Check TYPENAME_IS_RESOLVING_P on scope.
+ * init.c (expand_member_init): Check for being in a template first.
+ * parser.c (cp_parser_mem_initializer_list): Only check class types
+ for equivalence to the current class.
+
PR c++/54913
* semantics.c (finish_qualified_id_expr): convert_from_reference
after building a SCOPE_REF.
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 76a31c1b..2206c16 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -1370,8 +1370,8 @@ expand_member_init (tree name)
tree virtual_binfo;
int i;
- if (same_type_p (basetype, current_class_type)
- || current_template_parms)
+ if (current_template_parms
+ || same_type_p (basetype, current_class_type))
return basetype;
class_binfo = TYPE_BINFO (current_class_type);
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index a010f1f..3566d74 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -11592,7 +11592,7 @@ cp_parser_mem_initializer_list (cp_parser* parser)
}
/* Look for a target constructor. */
if (mem_initializer != error_mark_node
- && TYPE_P (TREE_PURPOSE (mem_initializer))
+ && CLASS_TYPE_P (TREE_PURPOSE (mem_initializer))
&& same_type_p (TREE_PURPOSE (mem_initializer), current_class_type))
{
maybe_warn_cpp0x (CPP0X_DELEGATING_CTORS);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 8b0ead1..87cd337 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -20079,7 +20079,16 @@ resolve_typename_type (tree type, bool only_current_p)
/* If the SCOPE is itself a TYPENAME_TYPE, then we need to resolve
it first before we can figure out what NAME refers to. */
if (TREE_CODE (scope) == TYPENAME_TYPE)
- scope = resolve_typename_type (scope, only_current_p);
+ {
+ if (TYPENAME_IS_RESOLVING_P (scope))
+ /* Given a class template A with a dependent base with nested type C,
+ typedef typename A::C::C C will land us here, as trying to resolve
+ the initial A::C leads to the local C typedef, which leads back to
+ A::C::C. So we break the recursion now. */
+ return type;
+ else
+ scope = resolve_typename_type (scope, only_current_p);
+ }
/* If we don't know what SCOPE refers to, then we cannot resolve the
TYPENAME_TYPE. */
if (TREE_CODE (scope) == TYPENAME_TYPE)
diff --git a/gcc/testsuite/g++.dg/template/meminit3.C b/gcc/testsuite/g++.dg/template/meminit3.C
new file mode 100644
index 0000000..b682449
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/meminit3.C
@@ -0,0 +1,12 @@
+// PR c++/54744
+
+template <typename T>
+struct base {
+ typedef base base_type;
+};
+
+template <typename T>
+struct derived : base<T> {
+ typedef typename derived::base_type::base_type base_type;
+ derived() : base_type() {}
+};