diff options
author | Momchil Velikov <momchil.velikov@gmail.com> | 2015-04-14 15:29:21 +0000 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2015-04-14 11:29:21 -0400 |
commit | 2fd16d0f9007f2e9a991b80c6ae2e4c5f85272b6 (patch) | |
tree | 9c81b516ff7b99da9d474e39696137390b743930 | |
parent | b42e7064553ea0deb7081e6ee7cf2aa898f6de78 (diff) | |
download | gcc-2fd16d0f9007f2e9a991b80c6ae2e4c5f85272b6.zip gcc-2fd16d0f9007f2e9a991b80c6ae2e4c5f85272b6.tar.gz gcc-2fd16d0f9007f2e9a991b80c6ae2e4c5f85272b6.tar.bz2 |
re PR c++/60994 (gcc does not recognize hidden/shadowed enumeration as valid nested-name-specifier)
PR c++/60994
* parser.c (cp_parser_class_name): Add enum_ok parameter.
(cp_parser_qualifying_entity): Use it instead of cp_parser_type_name.
(cp_parser_diagnose_invalid_type_name): Don't assume a template is
a class template.
Co-Authored-By: Jason Merrill <jason@redhat.com>
From-SVN: r222094
-rw-r--r-- | gcc/cp/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cp/parser.c | 56 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/scoped_enum3.C | 14 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/scoped_enum4.C | 20 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/var-templ23.C | 4 |
5 files changed, 66 insertions, 37 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e5a6ae2..2e43e4d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2015-04-14 Momchil Velikov <momchil.velikov@gmail.com> + Jason Merrill <jason@redhat.com> + + PR c++/60994 + * parser.c (cp_parser_class_name): Add enum_ok parameter. + (cp_parser_qualifying_entity): Use it instead of cp_parser_type_name. + (cp_parser_diagnose_invalid_type_name): Don't assume a template is + a class template. + 2015-04-12 Jakub Jelinek <jakub@redhat.com> PR c++/65736 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 4d6b479..c457a29 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -2193,7 +2193,7 @@ static tree finish_fully_implicit_template /* Classes [gram.class] */ static tree cp_parser_class_name - (cp_parser *, bool, bool, enum tag_types, bool, bool, bool); + (cp_parser *, bool, bool, enum tag_types, bool, bool, bool, bool = false); static tree cp_parser_class_specifier (cp_parser *); static tree cp_parser_class_head @@ -2957,10 +2957,13 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser, tree id, return; /* If the lookup found a template-name, it means that the user forgot to specify an argument list. Emit a useful error message. */ - if (TREE_CODE (decl) == TEMPLATE_DECL) - error_at (location, - "invalid use of template-name %qE without an argument list", - decl); + if (DECL_TYPE_TEMPLATE_P (decl)) + { + error_at (location, + "invalid use of template-name %qE without an argument list", + decl); + inform (DECL_SOURCE_LOCATION (decl), "%qD declared here", decl); + } else if (TREE_CODE (id) == BIT_NOT_EXPR) error_at (location, "invalid use of destructor %qD as a type", id); else if (TREE_CODE (decl) == TYPE_DECL) @@ -3037,6 +3040,8 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser, tree id, error_at (location_of (id), "%qE in namespace %qE does not name a type", id, parser->scope); + if (DECL_P (decl)) + inform (DECL_SOURCE_LOCATION (decl), "%qD declared here", decl); } else if (CLASS_TYPE_P (parser->scope) && constructor_name_p (id, parser->scope)) @@ -3063,6 +3068,8 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser, tree id, error_at (location_of (id), "%qE in %q#T does not name a type", id, parser->scope); + if (DECL_P (decl)) + inform (DECL_SOURCE_LOCATION (decl), "%qD declared here", decl); } else gcc_unreachable (); @@ -5710,35 +5717,9 @@ cp_parser_qualifying_entity (cp_parser *parser, type_p ? class_type : none_type, check_dependency_p, /*class_head_p=*/false, - is_declaration); + is_declaration, + /*enum_ok=*/cxx_dialect > cxx98); successful_parse_p = only_class_p || cp_parser_parse_definitely (parser); - /* If that didn't work and we're in C++0x mode, try for a type-name. */ - if (!only_class_p - && cxx_dialect != cxx98 - && !successful_parse_p) - { - /* Restore the saved scope. */ - parser->scope = saved_scope; - parser->qualifying_scope = saved_qualifying_scope; - parser->object_scope = saved_object_scope; - - /* Parse tentatively. */ - cp_parser_parse_tentatively (parser); - - /* Parse a type-name */ - scope = cp_parser_type_name (parser); - - /* "If the name found does not designate a namespace or a class, - enumeration, or dependent type, the program is ill-formed." - - We cover classes and dependent types above and namespaces below, - so this code is only looking for enums. */ - if (!scope || TREE_CODE (scope) != TYPE_DECL - || TREE_CODE (TREE_TYPE (scope)) != ENUMERAL_TYPE) - cp_parser_simulate_error (parser); - - successful_parse_p = cp_parser_parse_definitely (parser); - } /* If that didn't work, try for a namespace-name. */ if (!only_class_p && !successful_parse_p) { @@ -19608,7 +19589,8 @@ cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p) is a template. TAG_TYPE indicates the explicit tag given before the type name, if any. If CHECK_DEPENDENCY_P is FALSE, names are looked up in dependent scopes. If CLASS_HEAD_P is TRUE, this class - is the class being defined in a class-head. + is the class being defined in a class-head. If ENUM_OK is TRUE, + enum-names are also accepted. Returns the TYPE_DECL representing the class. */ @@ -19619,7 +19601,8 @@ cp_parser_class_name (cp_parser *parser, enum tag_types tag_type, bool check_dependency_p, bool class_head_p, - bool is_declaration) + bool is_declaration, + bool enum_ok) { tree decl; tree scope; @@ -19747,7 +19730,8 @@ cp_parser_class_name (cp_parser *parser, } else if (TREE_CODE (decl) != TYPE_DECL || TREE_TYPE (decl) == error_mark_node - || !MAYBE_CLASS_TYPE_P (TREE_TYPE (decl)) + || !(MAYBE_CLASS_TYPE_P (TREE_TYPE (decl)) + || (enum_ok && TREE_CODE (TREE_TYPE (decl)) == ENUMERAL_TYPE)) /* In Objective-C 2.0, a classname followed by '.' starts a dot-syntax expression, and it's not a type-name. */ || (c_dialect_objc () diff --git a/gcc/testsuite/g++.dg/cpp0x/scoped_enum3.C b/gcc/testsuite/g++.dg/cpp0x/scoped_enum3.C new file mode 100644 index 0000000..67a3d17 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/scoped_enum3.C @@ -0,0 +1,14 @@ +// PR c++/60994 +// { dg-do compile { target c++11 } } + +enum struct A +{ + n = 3 +}; + +A +foo() +{ + int A; + return A::n; +} diff --git a/gcc/testsuite/g++.dg/cpp0x/scoped_enum4.C b/gcc/testsuite/g++.dg/cpp0x/scoped_enum4.C new file mode 100644 index 0000000..80798ef --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/scoped_enum4.C @@ -0,0 +1,20 @@ +// PR c++/60994 +// { dg-do compile { target c++11 } } + +struct B { + enum struct A + { + n = 3 + }; +}; + +struct C: B +{ + using B::A; + + A foo() + { + int A; + return A::n; + } +}; diff --git a/gcc/testsuite/g++.dg/cpp1y/var-templ23.C b/gcc/testsuite/g++.dg/cpp1y/var-templ23.C index a5b19d2..80d8217 100644 --- a/gcc/testsuite/g++.dg/cpp1y/var-templ23.C +++ b/gcc/testsuite/g++.dg/cpp1y/var-templ23.C @@ -3,5 +3,7 @@ namespace std { template <typename T> int declval; - typename std::declval<> d; // { dg-error "not a type" } + typename std::declval<> d; // { dg-error "type" } } + +// { dg-prune-output "expected" } |