From: jason Date: Tue, 24 Nov 2009 20:55:24 +0000 (+0000) Subject: PR c++/42137 X-Git-Tag: upstream/4.9.2~32423 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=5570fae0813fdc67b5d514f819839e1963266e3d;p=platform%2Fupstream%2Flinaro-gcc.git PR c++/42137 * parser.c (cp_parser_mem_initializer_id): Pass typename_type to cp_parser_class_name. (cp_parser_unqualified_id): Same, rather than class_type. PR c++/11764 * parser.c (cp_parser_expression_statement): Give helpful error for constructor name used as type. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@154519 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ba3bbf2..72d7832 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,14 @@ 2009-11-24 Jason Merrill + PR c++/42137 + * parser.c (cp_parser_mem_initializer_id): Pass typename_type to + cp_parser_class_name. + (cp_parser_unqualified_id): Same, rather than class_type. + + PR c++/11764 + * parser.c (cp_parser_expression_statement): Give helpful error + for constructor name used as type. + * pt.c (determine_specialization): Give helpful error about missing "template<>". diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index c7560a8..0b6fa01 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -2401,11 +2401,15 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser, error_at (location, "%qE in namespace %qE does not name a type", id, parser->scope); else if (CLASS_TYPE_P (parser->scope) - && constructor_name_p (id, parser->scope) - && cp_lexer_next_token_is (parser->lexer, CPP_LESS)) - /* A::A() */ - error_at (location, "invalid use of constructor %<%T::%E%> as " - "template", parser->scope, id); + && constructor_name_p (id, parser->scope)) + { + /* A::A() */ + error_at (location, "%<%T::%E%> names the constructor, not" + " the type", parser->scope, id); + if (cp_lexer_next_token_is (parser->lexer, CPP_LESS)) + error_at (location, "and %qT has no template constructors", + parser->scope); + } else if (TYPE_P (parser->scope) && dependent_scope_p (parser->scope)) error_at (location, "need % before %<%T::%E%> because " @@ -3906,9 +3910,9 @@ cp_parser_unqualified_id (cp_parser* parser, /* If there was an explicit qualification (S::~T), first look in the scope given by the qualification (i.e., S). - Note: in the calls to cp_parser_class_name below we pretend that - the lookup had an explicit 'class' tag so that lookup finds the - injected-class-name rather than the constructor. */ + Note: in the calls to cp_parser_class_name below we pass + typename_type so that lookup finds the injected-class-name + rather than the constructor. */ done = false; type_decl = NULL_TREE; if (scope) @@ -3917,7 +3921,7 @@ cp_parser_unqualified_id (cp_parser* parser, type_decl = cp_parser_class_name (parser, /*typename_keyword_p=*/false, /*template_keyword_p=*/false, - class_type, + typename_type, /*check_dependency=*/false, /*class_head_p=*/false, declarator_p); @@ -3935,7 +3939,7 @@ cp_parser_unqualified_id (cp_parser* parser, = cp_parser_class_name (parser, /*typename_keyword_p=*/false, /*template_keyword_p=*/false, - class_type, + typename_type, /*check_dependency=*/false, /*class_head_p=*/false, declarator_p); @@ -3953,7 +3957,7 @@ cp_parser_unqualified_id (cp_parser* parser, = cp_parser_class_name (parser, /*typename_keyword_p=*/false, /*template_keyword_p=*/false, - class_type, + typename_type, /*check_dependency=*/false, /*class_head_p=*/false, declarator_p); @@ -3972,7 +3976,7 @@ cp_parser_unqualified_id (cp_parser* parser, = cp_parser_class_name (parser, /*typename_keyword_p=*/false, /*template_keyword_p=*/false, - class_type, + typename_type, /*check_dependency=*/false, /*class_head_p=*/false, declarator_p); @@ -7800,13 +7804,24 @@ cp_parser_expression_statement (cp_parser* parser, tree in_statement_expr) if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)) statement = cp_parser_expression (parser, /*cast_p=*/false, NULL); - /* Give a helpful message for "A::type t;" */ + /* Give a helpful message for "A::type t;" and the like. */ if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON) - && !cp_parser_uncommitted_to_tentative_parse_p (parser) - && TREE_CODE (statement) == SCOPE_REF) - error_at (token->location, "need % before %qE because " - "%qT is a dependent scope", - statement, TREE_OPERAND (statement, 0)); + && !cp_parser_uncommitted_to_tentative_parse_p (parser)) + { + if (TREE_CODE (statement) == SCOPE_REF) + error_at (token->location, "need % before %qE because " + "%qT is a dependent scope", + statement, TREE_OPERAND (statement, 0)); + else if (is_overloaded_fn (statement) + && DECL_CONSTRUCTOR_P (get_first_fn (statement))) + { + /* A::A a; */ + tree fn = get_first_fn (statement); + error_at (token->location, + "%<%T::%D%> names the constructor, not the type", + DECL_CONTEXT (fn), DECL_NAME (fn)); + } + } /* Consume the final `;'. */ cp_parser_consume_semicolon_at_end_of_statement (parser); @@ -10020,7 +10035,7 @@ cp_parser_mem_initializer_id (cp_parser* parser) return cp_parser_class_name (parser, /*typename_keyword_p=*/true, /*template_keyword_p=*/template_p, - none_type, + typename_type, /*check_dependency_p=*/true, /*class_head_p=*/false, /*is_declaration=*/true); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index dcf57249..cc5e804 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,11 @@ 2009-11-23 Jason Merrill + * g++.dg/tc1/dr147.C: Check for helpful messages. Add DR 318 tests. + * g++.old-deja/g++.pt/ctor2.C: Adjust. + * g++.dg/lookup/name-clash4.C: Adjust. + +2009-11-23 Jason Merrill + * g++.dg/template/spec15.C: Check for helpful message. 2009-11-24 Janis Johnson diff --git a/gcc/testsuite/g++.dg/lookup/name-clash4.C b/gcc/testsuite/g++.dg/lookup/name-clash4.C index d6c6d97..490f750 100644 --- a/gcc/testsuite/g++.dg/lookup/name-clash4.C +++ b/gcc/testsuite/g++.dg/lookup/name-clash4.C @@ -9,4 +9,4 @@ struct A template struct A {}; // { dg-error "same name" } }; -A::A<0> a; // { dg-error "not a template|invalid use of constructor" } +A::A<0> a; // { dg-error "not a template|constructor" } diff --git a/gcc/testsuite/g++.dg/tc1/dr147.C b/gcc/testsuite/g++.dg/tc1/dr147.C index 9c90d98..9006be9 100644 --- a/gcc/testsuite/g++.dg/tc1/dr147.C +++ b/gcc/testsuite/g++.dg/tc1/dr147.C @@ -11,8 +11,12 @@ A::A() { } B::B() { } B::A ba; -A::A a; // { dg-error "" "the injected-class-name can never be found through qualified lookup" } +A::A a; // { dg-error "constructor" "the injected-class-name can never be found through qualified lookup" } +void f() +{ + A::A a; // { dg-error "constructor" } +} // { dg-error "" "" { target *-*-* } 18 } error cascade } namespace N2 { @@ -26,6 +30,22 @@ template struct A { template A(T2); static A x; }; +template<> template <> A::A(char); template<> A::A(A::x); // { dg-error "" "this is an invalid declaration of the constructor" } } + +// But DR 318 says that in situations where a type is syntactically +// required, lookup finds it. + +struct C +{ + C(); + typedef int T; +}; +struct C::C c; +C::C::T t; +struct D: C::C +{ + D(): C::C() { } +}; diff --git a/gcc/testsuite/g++.old-deja/g++.pt/ctor2.C b/gcc/testsuite/g++.old-deja/g++.pt/ctor2.C index 802c2a4..eb8f312 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/ctor2.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/ctor2.C @@ -8,6 +8,6 @@ struct A { }; template -A::A() // { dg-error "invalid use of constructor|qualified name" } +A::A() // { dg-error "constructor|qualified name" } { } // { dg-error "end of input" }