diff options
author | Jason Merrill <jason@redhat.com> | 2012-12-06 15:21:08 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2012-12-06 15:21:08 -0500 |
commit | 5cd5a78c9b13d563f8fae2ed4f619ff5705863bf (patch) | |
tree | a29426df85df5c1f3893e6c6b00b12bea934c634 | |
parent | 1e8671f733a879525232e2e2f7b77d00362032d7 (diff) | |
download | gcc-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/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/init.c | 4 | ||||
-rw-r--r-- | gcc/cp/parser.c | 2 | ||||
-rw-r--r-- | gcc/cp/pt.c | 11 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/meminit3.C | 12 |
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() {} +}; |