diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index 66e8a973cce..6b686d75a49 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -4536,7 +4536,7 @@ make_typename_type (tree context, tree name, enum tag_types tag_type, else t = NULL_TREE; - if ((!t || TREE_CODE (t) == TREE_LIST) && dependent_type_p (context)) + if ((!t || TREE_CODE (t) == TREE_LIST) && dependentish_scope_p (context)) return build_typename_type (context, name, fullname, tag_type); want_template = TREE_CODE (fullname) == TEMPLATE_ID_EXPR; diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc index e35448f5434..6d99cb27703 100644 --- a/gcc/cp/error.cc +++ b/gcc/cp/error.cc @@ -4714,7 +4714,8 @@ qualified_name_lookup_error (tree scope, tree name, ; /* We already complained. */ else if (TYPE_P (scope)) { - if (!COMPLETE_TYPE_P (scope)) + if (!COMPLETE_TYPE_P (scope) + && !currently_open_class (scope)) error_at (location, "incomplete type %qT used in nested name specifier", scope); else if (TREE_CODE (decl) == TREE_LIST) diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 1dd0efaf963..efd5d6f29a7 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -3888,7 +3888,8 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser, tree id, else if (TYPE_P (parser->scope)) { auto_diagnostic_group d; - if (!COMPLETE_TYPE_P (parser->scope)) + if (!COMPLETE_TYPE_P (parser->scope) + && !currently_open_class (parser->scope)) cxx_incomplete_type_error (location_of (id), NULL_TREE, parser->scope); else if (cp_lexer_next_token_is (parser->lexer, CPP_LESS)) @@ -17514,7 +17515,10 @@ cp_parser_conversion_function_id (cp_parser* parser) In order to see that `I' is a type-name in the definition, we must be in the scope of `S'. */ - if (saved_scope) + if (saved_scope + /* In A::operator I(), we don't want to enter A if we're + in an expression rather than declaration context. */ + && adjust_type_for_entering_scope (saved_scope) == saved_scope) pushed_scope = push_scope (saved_scope); /* Parse the conversion-type-id. */ type = cp_parser_conversion_type_id (parser); @@ -32219,7 +32223,7 @@ cp_parser_lookup_name (cp_parser *parser, tree name, /* If the scope is a dependent type and either we deferred lookup or we did lookup but didn't find the name, rememeber the name. */ if (decl == error_mark_node && TYPE_P (parser->scope) - && dependent_type_p (parser->scope)) + && dependentish_scope_p (parser->scope)) { if (tag_type) { diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc index cd3df13772d..c21572e5d7f 100644 --- a/gcc/cp/semantics.cc +++ b/gcc/cp/semantics.cc @@ -4353,7 +4353,7 @@ finish_id_expression_1 (tree id_expression, /* Name lookup failed. */ if (scope && (!TYPE_P (scope) - || (!dependent_type_p (scope) + || (!dependentish_scope_p (scope) && !(identifier_p (id_expression) && IDENTIFIER_CONV_OP_P (id_expression) && dependent_type_p (TREE_TYPE (id_expression)))))) diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc index 15e5577f670..8df8b871676 100644 --- a/gcc/cp/typeck.cc +++ b/gcc/cp/typeck.cc @@ -3542,7 +3542,7 @@ finish_class_member_access_expr (cp_expr object, tree name, bool template_p, afi.maybe_suggest_accessor (TYPE_READONLY (object_type)); if (member == NULL_TREE) { - if (dependent_type_p (object_type)) + if (dependentish_scope_p (object_type)) /* Try again at instantiation time. */ goto dependent; if (complain & tf_error) diff --git a/gcc/testsuite/g++.dg/cpp0x/alignas18.C b/gcc/testsuite/g++.dg/cpp0x/alignas18.C index 820bdd2d7ca..9c25cd0942b 100644 --- a/gcc/testsuite/g++.dg/cpp0x/alignas18.C +++ b/gcc/testsuite/g++.dg/cpp0x/alignas18.C @@ -3,6 +3,5 @@ template struct S { using U = S; - // FIXME: This is ill-formed; see PR90847. - void fn() alignas(U::X); + void fn() alignas(U::X); // { dg-error "not a member" } }; diff --git a/gcc/testsuite/g++.dg/cpp0x/forw_enum13.C b/gcc/testsuite/g++.dg/cpp0x/forw_enum13.C index b8027f0c28d..37ffad9b956 100644 --- a/gcc/testsuite/g++.dg/cpp0x/forw_enum13.C +++ b/gcc/testsuite/g++.dg/cpp0x/forw_enum13.C @@ -18,13 +18,13 @@ class D2 template class D3 { - enum D3::A { foo } c; // { dg-error "extra qualification not allowed" } + enum D3::A { foo } c; // { dg-error "does not name an enumeration" } }; template class D4 { - enum D4::A { foo } c; // { dg-error "extra qualification not allowed" } + enum D4::A { foo } c; // { dg-error "does not name an enumeration" } }; template @@ -32,7 +32,7 @@ class D5 { class D6 { - enum D6::A { foo } c; // { dg-error "extra qualification not allowed" } + enum D6::A { foo } c; // { dg-error "does not name an enumeration" } }; }; diff --git a/gcc/testsuite/g++.dg/parse/access13.C b/gcc/testsuite/g++.dg/parse/access13.C index 41463c5dde5..ea3cf1111a8 100644 --- a/gcc/testsuite/g++.dg/parse/access13.C +++ b/gcc/testsuite/g++.dg/parse/access13.C @@ -2,6 +2,7 @@ template struct A { + struct E { static int V; }; A::E::V; // { dg-warning "access decl" } enum { V }; // { dg-error "conflicts with a previous decl" } }; diff --git a/gcc/testsuite/g++.dg/parse/enum11.C b/gcc/testsuite/g++.dg/parse/enum11.C index 68ddedbeeec..8bab16a6799 100644 --- a/gcc/testsuite/g++.dg/parse/enum11.C +++ b/gcc/testsuite/g++.dg/parse/enum11.C @@ -2,5 +2,5 @@ template struct A { - enum A::B::C {}; // { dg-error "has not been declared" } + enum A::B::C {}; // { dg-error "" } }; diff --git a/gcc/testsuite/g++.dg/template/crash123.C b/gcc/testsuite/g++.dg/template/crash123.C index 20a49619c6f..20a71cf192b 100644 --- a/gcc/testsuite/g++.dg/template/crash123.C +++ b/gcc/testsuite/g++.dg/template/crash123.C @@ -4,7 +4,7 @@ template struct VI {}; template struct IP { - static const bool r = IP::r; // { dg-error "depth" } + static const bool r = IP::r; // { dg-error "depth" } }; template struct V { diff --git a/gcc/testsuite/g++.dg/template/crash124.C b/gcc/testsuite/g++.dg/template/crash124.C index 4931aa8e9c6..5788ead4630 100644 --- a/gcc/testsuite/g++.dg/template/crash124.C +++ b/gcc/testsuite/g++.dg/template/crash124.C @@ -4,12 +4,12 @@ template struct VI {}; template struct IP { - static const bool r = IP::r; // { dg-error "depth" } + static const bool r = IP::r; // { dg-error "depth" } }; template struct V { - static const bool r = IP::r; + static const bool r = IP::r; VI vi; }; struct X; diff --git a/gcc/testsuite/g++.dg/template/crash7.C b/gcc/testsuite/g++.dg/template/crash7.C index 691628e7878..977b4e454ba 100644 --- a/gcc/testsuite/g++.dg/template/crash7.C +++ b/gcc/testsuite/g++.dg/template/crash7.C @@ -7,9 +7,7 @@ template struct A { - template A(typename A::X) {} // { dg-error "incomplete" } + template A(typename A::X) {} // { dg-error "does not name a type" } }; -// We currently don't give the "no match" error because we don't add the -// invalid constructor template to TYPE_METHODS. -A a; // { dg-message "required" } +A a; // { dg-error "no match" } diff --git a/gcc/testsuite/g++.dg/template/dtor6.C b/gcc/testsuite/g++.dg/template/dtor6.C index a3d778a1ea1..46ebf9ff95f 100644 --- a/gcc/testsuite/g++.dg/template/dtor6.C +++ b/gcc/testsuite/g++.dg/template/dtor6.C @@ -3,6 +3,7 @@ template struct A { static int i; + ~A(); }; template int A::i = { A::~A }; // { dg-error "36:invalid use of non-static member function" } diff --git a/gcc/testsuite/g++.dg/template/error22.C b/gcc/testsuite/g++.dg/template/error22.C index a7e61721113..af87992219b 100644 --- a/gcc/testsuite/g++.dg/template/error22.C +++ b/gcc/testsuite/g++.dg/template/error22.C @@ -4,6 +4,6 @@ struct A { template struct B {}; void ::foo(); // { dg-error "10:invalid use" } - B<&A::foo> b; // { dg-error "incomplete type|template argument" } + B<&A::foo> b; // { dg-error "'foo' is not a member of 'A'|template argument" } }; diff --git a/gcc/testsuite/g++.dg/template/non-dependent34.C b/gcc/testsuite/g++.dg/template/non-dependent34.C new file mode 100644 index 00000000000..4f369ff6b3e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/non-dependent34.C @@ -0,0 +1,44 @@ +// Verify we diagnose failed qualified lookup into the current +// instantiation ahead of time. + +namespace without_dependent_base { +template +struct A { + void f(A& other) { + A::x; // { dg-error "'x' is not a member" } + this->x; // { dg-error "no member named 'x'" } + other.y; // { dg-error "no member named 'y'" } + typename A::type z; // { dg-error "does not name a type" } + + struct B { + void g(A& other) { + A::x; // { dg-error "'x' is not a member" } + this->x; // { dg-error "no member named 'x'" } + other.y; // { dg-error "no member named 'y'" } + typename A::type z; // { dg-error "does not name a type" } + } + }; + } +}; +} + +namespace with_dependent_base { +template +struct A : T { + void f(A& other) { + A::x; + this->x; + other.y; + typename A::type z; + + struct B : T { + void g(A& other) { + A::x; + this->x; + other.y; + typename A::type z; + } + }; + } +}; +} diff --git a/gcc/testsuite/g++.dg/template/static30.C b/gcc/testsuite/g++.dg/template/static30.C index 07dafe23ffa..248f9e9025e 100644 --- a/gcc/testsuite/g++.dg/template/static30.C +++ b/gcc/testsuite/g++.dg/template/static30.C @@ -6,5 +6,5 @@ template struct A static const int i2; }; -template const int A::i1(A::i); -template const int A::i2(3, A::i); // { dg-error "expression list" } +template const int A::i1(A::i1); +template const int A::i2(3, A::i2); // { dg-error "expression list" } diff --git a/gcc/testsuite/g++.old-deja/g++.other/decl5.C b/gcc/testsuite/g++.old-deja/g++.other/decl5.C index 26556aaa7ef..c24957f8bbe 100644 --- a/gcc/testsuite/g++.old-deja/g++.other/decl5.C +++ b/gcc/testsuite/g++.old-deja/g++.other/decl5.C @@ -18,7 +18,7 @@ struct A { struct Z; expand me; // { dg-error "'expand' does not name a type" } void foo(struct A::e); - void foo(struct A::z); // { dg-error "incomplete" } + void foo(struct A::z); // { dg-error "does not name a type" } }; struct Q; diff --git a/libstdc++-v3/include/experimental/socket b/libstdc++-v3/include/experimental/socket index 02c27d66c6a..3fe83a001e6 100644 --- a/libstdc++-v3/include/experimental/socket +++ b/libstdc++-v3/include/experimental/socket @@ -2450,7 +2450,7 @@ inline namespace v1 // XXX ??? ^^^^^^^ { // XXX ??? this->init(std::addressof(_M_sb)); - this->set_rbduf(std::addressof(_M_sb)); + this->set_rdbuf(std::addressof(_M_sb)); } template diff --git a/libstdc++-v3/include/tr2/dynamic_bitset b/libstdc++-v3/include/tr2/dynamic_bitset index 274c4f6a138..f0878d7429e 100644 --- a/libstdc++-v3/include/tr2/dynamic_bitset +++ b/libstdc++-v3/include/tr2/dynamic_bitset @@ -304,7 +304,7 @@ namespace tr2 bool _M_is_proper_subset_of(const __dynamic_bitset_base& __b) const noexcept { - if (this->is_subset_of(__b)) + if (this->_M_is_subset_of(__b)) { if (*this == __b) return false;