OSDN Git Service

PR c++/18451
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 8 Nov 2009 03:47:36 +0000 (03:47 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 8 Nov 2009 03:47:36 +0000 (03:47 +0000)
PR c++/40738
* cp-tree.h (cp_decl_specifier_seq): Add any_type_specifiers_p.
* parser.c (cp_parser_single_declaration): Call
cp_parser_parse_and_diagnose_invalid_type_name here, too.
(cp_parser_parameter_declaration): And here.
(cp_parser_parse_and_diagnose_invalid_type_name): Be
less picky about declarator form.  Don't skip to
the end of the block if we're in a declarator.
(cp_parser_decl_specifier_seq): Set any_type_specifiers_p.
(cp_parser_simple_declaration): Check it.
(cp_parser_member_declaration): Likewise.
(cp_parser_diagnose_invalid_type_name): Tweak error message.
(cp_parser_expression_statement): Likewise.
* decl2.c (grokfield): Mention decltype instead of typeof.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@154006 138bc75d-0d04-0410-961f-82ee72b054a4

27 files changed:
gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl2.c
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/variadic-ex1.C
gcc/testsuite/g++.dg/ext/typedef-init.C
gcc/testsuite/g++.dg/lookup/hidden-class1.C
gcc/testsuite/g++.dg/lookup/hidden-class10.C
gcc/testsuite/g++.dg/lookup/hidden-class5.C
gcc/testsuite/g++.dg/lookup/hidden-class7.C
gcc/testsuite/g++.dg/lookup/hidden-temp-class1.C
gcc/testsuite/g++.dg/lookup/hidden-temp-class4.C
gcc/testsuite/g++.dg/lookup/hidden-temp-class7.C
gcc/testsuite/g++.dg/lookup/strong-using-2.C
gcc/testsuite/g++.dg/other/typedef1.C
gcc/testsuite/g++.dg/parse/access10.C
gcc/testsuite/g++.dg/parse/constructor1.C
gcc/testsuite/g++.dg/parse/crash38.C
gcc/testsuite/g++.dg/parse/error3.C
gcc/testsuite/g++.dg/parse/error36.C
gcc/testsuite/g++.dg/parse/typespec1.C
gcc/testsuite/g++.dg/template/typedef5.C
gcc/testsuite/g++.old-deja/g++.pt/typename3.C
gcc/testsuite/g++.old-deja/g++.pt/typename4.C
gcc/testsuite/g++.old-deja/g++.pt/typename6.C
gcc/testsuite/g++.old-deja/g++.robertl/eb94.C

index b63977b..7dc1587 100644 (file)
@@ -1,3 +1,21 @@
+2009-11-07  Jason Merrill  <jason@redhat.com>
+
+       PR c++/18451
+       PR c++/40738
+       * cp-tree.h (cp_decl_specifier_seq): Add any_type_specifiers_p.
+       * parser.c (cp_parser_single_declaration): Call
+       cp_parser_parse_and_diagnose_invalid_type_name here, too.
+       (cp_parser_parameter_declaration): And here.
+       (cp_parser_parse_and_diagnose_invalid_type_name): Be
+       less picky about declarator form.  Don't skip to
+       the end of the block if we're in a declarator.
+       (cp_parser_decl_specifier_seq): Set any_type_specifiers_p.
+       (cp_parser_simple_declaration): Check it.
+       (cp_parser_member_declaration): Likewise.
+       (cp_parser_diagnose_invalid_type_name): Tweak error message.
+       (cp_parser_expression_statement): Likewise.
+       * decl2.c (grokfield): Mention decltype instead of typeof.
+
 2009-11-06  Jason Merrill  <jason@redhat.com>
 
        PR c++/15946
index c4b088b..68be934 100644 (file)
@@ -4267,6 +4267,8 @@ typedef struct cp_decl_specifier_seq {
   BOOL_BITFIELD conflicting_specifiers_p : 1;
   /* True iff at least one decl-specifier was found.  */
   BOOL_BITFIELD any_specifiers_p : 1;
+  /* True iff at least one type-specifier was found.  */
+  BOOL_BITFIELD any_type_specifiers_p : 1;
   /* True iff "int" was explicitly provided.  */
   BOOL_BITFIELD explicit_int_p : 1;
   /* True iff "char" was explicitly provided.  */
index 53f66ad..ba987f7 100644 (file)
@@ -789,7 +789,7 @@ grokfield (const cp_declarator *declarator,
 
   if (TREE_CODE (value) == TYPE_DECL && init)
     {
-      error ("typedef %qD is initialized (use __typeof__ instead)", value);
+      error ("typedef %qD is initialized (use decltype instead)", value);
       init = NULL_TREE;
     }
 
index 47f5f13..7bafb67 100644 (file)
@@ -2402,8 +2402,8 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser,
                  id, parser->scope);
       else if (TYPE_P (parser->scope)
               && dependent_scope_p (parser->scope))
-       error_at (location, "need %<typename%> before %<%T::%E%> to name "
-                 "a type in dependent scope %qT",
+       error_at (location, "need %<typename%> before %<%T::%E%> because "
+                 "%qT is a dependent scope",
                  parser->scope, id, parser->scope);
       else if (TYPE_P (parser->scope))
        error_at (location, "%qE in class %qT does not name a type",
@@ -2437,9 +2437,9 @@ cp_parser_parse_and_diagnose_invalid_type_name (cp_parser *parser)
                                /*template_p=*/NULL,
                                /*declarator_p=*/true,
                                /*optional_p=*/false);
-  /* After the id-expression, there should be a plain identifier,
-     otherwise this is not a simple variable declaration.  */
-  if (!cp_lexer_next_token_is (parser->lexer, CPP_NAME)
+  /* If the next token is a (, this is a function with no explicit return
+     type, i.e. constructor, destructor or conversion op.  */
+  if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)
       || TREE_CODE (id) == TYPE_DECL)
     {
       cp_parser_abort_tentative_parse (parser);
@@ -2451,9 +2451,11 @@ cp_parser_parse_and_diagnose_invalid_type_name (cp_parser *parser)
   /* Emit a diagnostic for the invalid type.  */
   cp_parser_diagnose_invalid_type_name (parser, parser->scope,
                                        id, token->location);
-  /* Skip to the end of the declaration; there's no point in
-     trying to process it.  */
-  cp_parser_skip_to_end_of_block_or_statement (parser);
+  /* If we aren't in the middle of a declarator (i.e. in a
+     parameter-declaration-clause), skip to the end of the declaration;
+     there's no point in trying to process it.  */
+  if (!parser->in_declarator_p)
+    cp_parser_skip_to_end_of_block_or_statement (parser);
   return true;
 }
 
@@ -7773,8 +7775,8 @@ cp_parser_expression_statement (cp_parser* parser, tree in_statement_expr)
   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 to name "
-             "a type in dependent scope %qT",
+    error_at (token->location, "need %<typename%> before %qE because "
+             "%qT is a dependent scope",
              statement, TREE_OPERAND (statement, 0));
 
   /* Consume the final `;'.  */
@@ -8846,7 +8848,7 @@ cp_parser_simple_declaration (cp_parser* parser,
        T t;
 
      where "T" should name a type -- but does not.  */
-  if (!decl_specifiers.type
+  if (!decl_specifiers.any_type_specifiers_p
       && cp_parser_parse_and_diagnose_invalid_type_name (parser))
     {
       /* If parsing tentatively, we should commit; we really are
@@ -9211,6 +9213,8 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
            {
              constructor_possible_p = false;
              found_decl_spec = true;
+             if (!is_cv_qualifier)
+               decl_specs->any_type_specifiers_p = true;
            }
        }
 
@@ -14973,6 +14977,11 @@ cp_parser_parameter_declaration (cp_parser *parser,
                                CP_PARSER_FLAGS_NONE,
                                &decl_specifiers,
                                &declares_class_or_enum);
+
+  /* Complain about missing 'typename' or other invalid type names.  */
+  if (!decl_specifiers.any_type_specifiers_p)
+    cp_parser_parse_and_diagnose_invalid_type_name (parser);
+
   /* If an error occurred, there's no reason to attempt to parse the
      rest of the declaration.  */
   if (cp_parser_error_occurred (parser))
@@ -16523,7 +16532,7 @@ cp_parser_member_declaration (cp_parser* parser)
   prefix_attributes = decl_specifiers.attributes;
   decl_specifiers.attributes = NULL_TREE;
   /* Check for an invalid type-name.  */
-  if (!decl_specifiers.type
+  if (!decl_specifiers.any_type_specifiers_p
       && cp_parser_parse_and_diagnose_invalid_type_name (parser))
     return;
   /* If there is no declarator, then the decl-specifier-seq should
@@ -18775,6 +18784,11 @@ cp_parser_single_declaration (cp_parser* parser,
          cp_parser_perform_template_parameter_access_checks (checks);
        }
     }
+
+  /* Complain about missing 'typename' or other invalid type names.  */
+  if (!decl_specifiers.any_type_specifiers_p)
+    cp_parser_parse_and_diagnose_invalid_type_name (parser);
+
   /* If it's not a template class, try for a template function.  If
      the next token is a `;', then this declaration does not declare
      anything.  But, if there were errors in the decl-specifiers, then
index df7e86d..d4dc136 100644 (file)
@@ -1,5 +1,30 @@
 2009-11-07  Jason Merrill  <jason@redhat.com>
 
+       PR c++/18451
+       PR c++/40738
+       * g++.dg/parse/error36.C: Add parameter and template cases.
+       * g++.dg/cpp0x/variadic-ex1.C: Update expected errors.
+       * g++.dg/ext/typedef-init.C: Likewise.
+       * g++.dg/lookup/hidden-class1.C: Likewise.
+       * g++.dg/lookup/hidden-class10.C: Likewise.
+       * g++.dg/lookup/hidden-class5.C: Likewise.
+       * g++.dg/lookup/hidden-class7.C: Likewise.
+       * g++.dg/lookup/hidden-temp-class1.C: Likewise.
+       * g++.dg/lookup/hidden-temp-class4.C: Likewise.
+       * g++.dg/lookup/hidden-temp-class7.C: Likewise.
+       * g++.dg/lookup/strong-using-2.C: Likewise.
+       * g++.dg/other/typedef1.C: Likewise.
+       * g++.dg/parse/access10.C: Likewise.
+       * g++.dg/parse/constructor1.C: Likewise.
+       * g++.dg/parse/crash38.C: Likewise.
+       * g++.dg/parse/error3.C: Likewise.
+       * g++.dg/parse/typespec1.C: Likewise.
+       * g++.dg/template/typedef5.C: Likewise.
+       * g++.old-deja/g++.pt/typename3.C: Likewise.
+       * g++.old-deja/g++.pt/typename4.C: Likewise.
+       * g++.old-deja/g++.pt/typename6.C: Likewise.
+       * g++.old-deja/g++.robertl/eb94.C: Likewise.
+
        * g++.dg/abi/regparm1.C: Fix execute test.
 
 2009-11-07  Jakub Jelinek  <jakub@redhat.com>
index d5ebf0d..485fffa 100644 (file)
@@ -1,4 +1,4 @@
 // { dg-options "-std=gnu++0x" }
 template<typename ... Elements> class Tuple;
 Tuple<>* t; // OK: Elements is empty
-Tuple* u; // { dg-error "expected" }
+Tuple* u; // { dg-error "template-name" }
index 95a96d5..153303d 100644 (file)
@@ -11,8 +11,7 @@
 
 /* Case A: just the bare name = initializer.  */
 
-typedef A = 0;  /* { dg-error "initialized" "A" } */
-                /* { dg-warning "no type" "A warns" { target *-*-* } 14 } */
+typedef A = 0;  /* { dg-error "does not name a type" "A" } */
 A a;            /* { dg-error "does not name a type" "A error cascade" } */
 
 /* Case B: with a type also.  */
@@ -24,9 +23,8 @@ B b;              /* { dg-error "does not name a type" "B error cascade" } */
    field declarations go by a different code path in C++ (ick).  */
 
 struct S {
-  typedef C = 0; /* { dg-error "initialized" "C" } */
-                 /* { dg-warning "no type" "C warns" { target *-*-* } 27 } */
-  C c;          /* { dg-bogus "" "C error cascade" } */
+  typedef C = 0; /* { dg-error "does not name a type" "C" } */
+  C c;          /* { dg-error "" "C error cascade" } */
 
   typedef int D = 0; /* { dg-error "initialized" "D" } */
   D d;              /* { dg-bogus "" "D error cascade" } */
index fc71e96..b3be4e8 100644 (file)
@@ -4,5 +4,5 @@
 
 class A {
   friend class B;
-  B *b;                // { dg-error "no type|expected" }
+  B *b;                // { dg-error "type|expected" }
 };
index f68196f..c9b5ca9 100644 (file)
@@ -7,5 +7,5 @@
 
 class A {
   friend class abort;
-  abort *b;    // { dg-error "no type|expected" }
+  abort *b;    // { dg-error "type|expected" }
 };
index 1cf06bc..c241354 100644 (file)
@@ -6,4 +6,4 @@ class A {
   friend class B;
 };
 
-B* b;          // { dg-error "expected" }
+B* b;          // { dg-error "type|expected" }
index f681cd6..a46ae71 100644 (file)
@@ -10,4 +10,4 @@ class C {
   friend class B;
 };
 
-B *b;          // { dg-error "expected" }
+B *b;          // { dg-error "type|expected" }
index c92b7f6..8cdb235 100644 (file)
@@ -4,5 +4,5 @@
 
 class A {
   template <class T> friend class B;
-  B<int> *b;   // { dg-error "no type|expected" }
+  B<int> *b;   // { dg-error "type|expected" }
 };
index 02dc9c3..3d085e2 100644 (file)
@@ -6,4 +6,4 @@ class A {
   template <class T> friend class B;
 };
 
-B<int> *b;     // { dg-error "expected" }
+B<int> *b;     // { dg-error "type|expected" }
index 22804d7..19dd952 100644 (file)
@@ -10,4 +10,4 @@ class C {
   template <class T> friend class B;
 };
 
-B<int> *b;     // { dg-error "expected" }
+B<int> *b;     // { dg-error "type|expected" }
index 5c4b425..314aa52 100644 (file)
@@ -20,4 +20,4 @@ namespace baz {
 
 foo::T *t1;
 bar::T *t2;
-baz::T *t3; // { dg-error "(ambiguous|expected|extra)" "" }
+baz::T *t3; // { dg-error "(ambiguous|does not name a type)" "" }
index 55d62bb..ef1684d 100644 (file)
@@ -2,6 +2,6 @@
 // { dg-do compile }
 
 void f1(typedef) {}        // { dg-error "no type|typedef declaration" }
-void f2(typedef x) {}      // { dg-error "no type|typedef declaration" }
-void f3(typedef x[]) {}    // { dg-error "no type|typedef declaration" }
+void f2(typedef x) {}      // { dg-error "type|typedef declaration" }
+void f3(typedef x[]) {}    // { dg-error "type|typedef declaration" }
 void f4(typedef int x) {}  // { dg-error "typedef declaration" }
index ebfeea9..62adc1b 100644 (file)
@@ -7,7 +7,5 @@ template<int> struct A
     ::A~();                    // { dg-bogus "using-declaration" }
 };
 
-// Instead of the bogus error we get 3 separate errors.
-// { dg-error "no type" "" { target *-*-* } 7 }
-// { dg-error "::" "" { target *-*-* } 7 }
-// { dg-error "~" "" { target *-*-* } 7 }
+// Instead of the bogus error we get a different error.
+// { dg-error "template-name" "" { target *-*-* } 7 }
index 1796531..1bb9ee0 100644 (file)
@@ -1,8 +1,8 @@
 // { dg-do compile }
 // { dg-options "-fshow-column" }
 
-ACE_Process_Descriptor::ACE_Process_Descriptor () : // { dg-error "declared" "declared" }
-  // { dg-error "no type" "no type" { target *-*-* } 4 }
-  process_ (0) // { dg-error "3: only constructors take base initializers" }
+ACE_Process_Descriptor::ACE_Process_Descriptor () :
+  // { dg-error "does not name a type" "no type" { target *-*-* } 4 }
+  process_ (0)
 {
 }
index c050b93..724f9b8 100644 (file)
@@ -3,7 +3,7 @@
 /* This would not ICE.  */
 namespace M { } /* { dg-error "previous declaration" } */
 struct M; /* { dg-error "redeclared as different kind of symbol" } */
-M *p; /* { dg-error "expected constructor" } */
+M *p; /* { dg-error "does not name a type" } */
 
 /* This would ICE when processing 'p'.  */
 namespace N { } /* { dg-error "previous declaration" } */
index 55ae024..7e8cf8d 100644 (file)
@@ -5,5 +5,5 @@ static void InstantiateConstraint(const float&, unsigned,
                                   void(*AddFunction)(const TYPE&,bool&,
                                                      char*, char*,
                                                      unsigned*));
-// { dg-error "64:expected ',' or '...' before '&' token" "" { target *-*-* }  { 5 } }
-// { dg-error "60:ISO C\\+\\+ forbids declaration of 'TYPE' with no type" "" { target *-*-* } { 5 } }
+// { dg-error "64: ISO C\\+\\+ forbids declaration of 'parameter' with no type" "" { target *-*-* }  { 5 } }
+// { dg-error "60: 'TYPE' does not name a type" "" { target *-*-* } { 5 } }
index 92101e9..0d7f8cf 100644 (file)
@@ -1,17 +1,33 @@
+// PR c++/15946
 // Test for helpful error message about missing typename.
 
-template <class T> struct A { typedef T foo; typedef T bar; };
+template <class T> struct A
+{
+  struct B { };
+  static B b;
+};
+
 template <class T>
 void f(T t)
 {
   typedef A<T>::foo type;      // { dg-error "typename" }
   A<T>::bar b;                 // { dg-error "typename" }
-} // { dg-error "expected ';'" "" { target *-*-* } 8 }
+} // { dg-error "expected ';'" "" { target *-*-* } 14 }
 
+// PR c++/36353
 template <class T> struct B
 {
   void f()
   {
     A<T>::baz z;               // { dg-error "typename" }
-  } // { dg-error "expected ';'" "" { target *-*-* } 15 }
+  } // { dg-error "expected ';'" "" { target *-*-* } 22 }
 };
+
+// PR c++/40738
+template <class T>
+void g(const A<T>::type &t);   // { dg-error "typename" }
+// { dg-error "no type" "" { target *-*-* } 28 }
+
+// PR c++/18451
+template <class T> A<T>::B A<T>::b; // { dg-error "typename" }
+// { dg-error "expected" "" { target *-*-* } 32 }
index a371f8b..44ee116 100644 (file)
@@ -1,4 +1,4 @@
 // PR c++/26571
 
 struct A {};
-unsigned A a;                  // { dg-error "multiple" }
+unsigned A a;                  // { dg-error "expected initializer" }
index abd9ebb..04b8eac 100644 (file)
@@ -2,6 +2,6 @@
 // { dg-do compile }
 
 template<typedef,int>        struct A1; // { dg-error "no type|typedef declaration|default argument" }
-template<typedef x,int>      struct A2; // { dg-error "no type|typedef declaration|default argument" }
-template<typedef x[],int>    struct A3; // { dg-error "no type|typedef declaration|default argument" }
+template<typedef x,int>      struct A2; // { dg-error "type|typedef declaration|default argument" }
+template<typedef x[],int>    struct A3; // { dg-error "no type|typedef declaration|expected" }
 template<typedef int x, int> struct A4; // { dg-error "typedef declaration|default argument" }
index 9b41275..0708f1f 100644 (file)
@@ -17,5 +17,5 @@ struct B : public A<U>
 
 
 template <class U>
-B<U>::A_Type B<U>::Func() { // { dg-error "expected" } implicit typename
-}
+B<U>::A_Type B<U>::Func() { // { dg-error "typename" } implicit typename
+}                          // { dg-error "expected" }
index 286795c..7238470 100644 (file)
@@ -22,5 +22,5 @@ struct C : public B<U>
 
 
 template <class U>
-C<U>::A_Type C<U>::Func() { // { dg-error "expected" } implicit typename
-}
+C<U>::A_Type C<U>::Func() { // { dg-error "typename" } implicit typename
+}                          // { dg-error "expected" }
index 2794479..0a5f018 100644 (file)
@@ -15,6 +15,6 @@ struct B : public A<U>
 };
 
 template <class U>
-A<U>::A_Type B<U>::Func()       // { dg-error "expected" } function
+A<U>::A_Type B<U>::Func()       // { dg-error "typename" } function
 {                              
-}
+} // { dg-error "expected" }
index b3d2da1..5350236 100644 (file)
@@ -10,7 +10,7 @@ static int variable;
 class myClass : public baseClass
 {
 private:
-static int variable;                    // this is intentionally duplicated
+static int variable;                    // { dg-error "private" }
 };
 
 myClass::variable = 0;                  //{ dg-error "" } no type