OSDN Git Service

PR c++/42137
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 24 Nov 2009 20:55:24 +0000 (20:55 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 24 Nov 2009 20:55:24 +0000 (20:55 +0000)
* 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

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/lookup/name-clash4.C
gcc/testsuite/g++.dg/tc1/dr147.C
gcc/testsuite/g++.old-deja/g++.pt/ctor2.C

index ba3bbf2..72d7832 100644 (file)
@@ -1,5 +1,14 @@
 2009-11-24  Jason Merrill  <jason@redhat.com>
 
+       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<>".
 
index c7560a8..0b6fa01 100644 (file)
@@ -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<T>::A<T>() */
-       error_at (location, "invalid use of constructor %<%T::%E%> as "
-                 "template", parser->scope, id);
+              && constructor_name_p (id, parser->scope))
+       {
+         /* A<T>::A<T>() */
+         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 %<typename%> 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<T>::type t;"  */
+  /* Give a helpful message for "A<T>::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 %<typename%> 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 %<typename%> 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);
index dcf5724..cc5e804 100644 (file)
@@ -1,5 +1,11 @@
 2009-11-23  Jason Merrill  <jason@redhat.com>
 
+       * 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  <jason@redhat.com>
+
        * g++.dg/template/spec15.C: Check for helpful message.
 
 2009-11-24  Janis Johnson  <janis187@us.ibm.com>
index d6c6d97..490f750 100644 (file)
@@ -9,4 +9,4 @@ struct A
     template<int> 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" }
index 9c90d98..9006be9 100644 (file)
@@ -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 <class T> struct A {
   template <class T2> A(T2);
   static A x;
 };
+template<> template <> A<char>::A<char>(char);
 template<> A<int>::A<int>(A<int>::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() { }
+};
index 802c2a4..eb8f312 100644 (file)
@@ -8,6 +8,6 @@ struct A {
 };
 
 template <class T>
-A<T>::A<T>()   // { dg-error "invalid use of constructor|qualified name" }
+A<T>::A<T>()   // { dg-error "constructor|qualified name" }
 {
 } // { dg-error "end of input" }