summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorfabien <fabien@138bc75d-0d04-0410-961f-82ee72b054a4>2014-02-02 20:02:37 +0000
committerfabien <fabien@138bc75d-0d04-0410-961f-82ee72b054a4>2014-02-02 20:02:37 +0000
commit1b8cb5ee613a5101f24cf3f31d894061166888fe (patch)
treeb5cd3b5b66192646a47ac9095f2196b774f7fca6 /gcc
parent1129c81996e64b74b801507821c31ed9129086d8 (diff)
downloadgcc-1b8cb5ee613a5101f24cf3f31d894061166888fe.tar.gz
2014-02-02 Fabien Chene <fabien@gcc.gnu.org>
PR c++/37140 * parser.c (cp_parser_nonclass_name): Call strip_using_decl and move the code handling dependent USING_DECLs... * name-lookup.c (strip_using_decl): ...Here. 2014-02-02 Fabien Chene <fabien@gcc.gnu.org> PR c++/37140 * g++.dg/template/using27.C: New. * g++.dg/template/using28.C: New. * g++.dg/template/using29.C: New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@207408 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/parser.c20
-rw-r--r--gcc/testsuite/g++.dg/template/using27.C33
-rw-r--r--gcc/testsuite/g++.dg/template/using28.C17
-rw-r--r--gcc/testsuite/g++.dg/template/using29.C21
4 files changed, 72 insertions, 19 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index a53597d205e..57001c65c37 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -14812,25 +14812,7 @@ cp_parser_nonclass_name (cp_parser* parser)
/* Look up the type-name. */
type_decl = cp_parser_lookup_name_simple (parser, identifier, token->location);
- if (TREE_CODE (type_decl) == USING_DECL)
- {
- if (!DECL_DEPENDENT_P (type_decl))
- type_decl = strip_using_decl (type_decl);
- else if (USING_DECL_TYPENAME_P (type_decl))
- {
- /* We have found a type introduced by a using
- declaration at class scope that refers to a dependent
- type.
-
- using typename :: [opt] nested-name-specifier unqualified-id ;
- */
- type_decl = make_typename_type (TREE_TYPE (type_decl),
- DECL_NAME (type_decl),
- typename_type, tf_error);
- if (type_decl != error_mark_node)
- type_decl = TYPE_NAME (type_decl);
- }
- }
+ type_decl = strip_using_decl (type_decl);
if (TREE_CODE (type_decl) != TYPE_DECL
&& (objc_is_id (identifier) || objc_is_class_name (identifier)))
diff --git a/gcc/testsuite/g++.dg/template/using27.C b/gcc/testsuite/g++.dg/template/using27.C
new file mode 100644
index 00000000000..f1835e17161
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/using27.C
@@ -0,0 +1,33 @@
+// PR c++/37140
+
+struct X
+{
+ typedef int nested_type;
+};
+
+template <class T>
+struct A
+{
+ typedef X type;
+};
+
+template <class T>
+struct B : A<T>
+{
+ using typename A<T>::type;
+ typename type::nested_type x;
+};
+
+template <class T>
+struct C : B<T>
+{
+ using typename B<T>::type;
+ typename type::nested_type y;
+};
+
+struct D : C<int>
+{
+ using C<int>::type;
+ type::nested_type z;
+};
+
diff --git a/gcc/testsuite/g++.dg/template/using28.C b/gcc/testsuite/g++.dg/template/using28.C
new file mode 100644
index 00000000000..52f68cfe467
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/using28.C
@@ -0,0 +1,17 @@
+// PR c++/37140
+
+struct C
+{
+ static const int block_size = 1;
+};
+
+template <typename T> struct A {
+ typedef C type;
+};
+
+template <typename T> struct B : public A<T> {
+ using typename A<T>::type;
+ static const int block_size = type::block_size;
+};
+
+template class B<int>;
diff --git a/gcc/testsuite/g++.dg/template/using29.C b/gcc/testsuite/g++.dg/template/using29.C
new file mode 100644
index 00000000000..8726547efdb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/using29.C
@@ -0,0 +1,21 @@
+// PR c++/58047
+
+template <int N>
+struct print_arg { };
+
+struct const_holder {
+ static const int CONSTANT = 42;
+};
+
+template <typename T>
+struct identity {
+ typedef T type;
+};
+
+template <class T>
+struct test_case : public identity<T> {
+ using typename identity<T>::type;
+ print_arg<type::CONSTANT> printer;
+};
+
+template struct test_case<const_holder>;