]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/18124 (ICE with invalid template template parameter)
authorMark Mitchell <mark@codesourcery.com>
Wed, 3 Nov 2004 02:48:44 +0000 (02:48 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Wed, 3 Nov 2004 02:48:44 +0000 (02:48 +0000)
PR c++/18124
* parser.c (cp_parser_type_parameter): Robustify.

PR c++/18155
* parser.c (cp_parser_single_declaration): Disallow template
typedefs.

PR c++/18177
* typeck.c (build_const_cast): Use error_operand_p.

PR c++/18124
* g++.dg/template/crash25.C: New test.

PR c++/18155
* g++.dg/template/typedef2.C: New test.
* g++.dg/parse/crash13.C: Adjust error markers.

PR c++/18177
* g++.dg/conversion/const3.C: New test.

From-SVN: r90016

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/conversion/const3.C [new file with mode: 0644]
gcc/testsuite/g++.dg/parse/crash13.C
gcc/testsuite/g++.dg/template/crash25.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/typedef2.C [new file with mode: 0644]

index 61691e9d98c24fc3b89bc3a4f82837047fc33bb6..ef855e337a82cd3be79502c082839a583b6726a4 100644 (file)
@@ -1,3 +1,15 @@
+2004-11-02  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/18124
+       * parser.c (cp_parser_type_parameter): Robustify.
+
+       PR c++/18155
+       * parser.c (cp_parser_single_declaration): Disallow template
+       typedefs.
+
+       PR c++/18177
+       * typeck.c (build_const_cast): Use error_operand_p.
+
 2004-11-02  Ziemowit Laski  <zlaski@apple.com>
 
        * cp-lang.c (cxx_types_compatible_p): Remove prototype and definition.
index e2afb3b192b2318da048c634d39f90023a34e7d3..bea2f61ec3f0c295a51cc0658f42a34df619c1e2 100644 (file)
@@ -8186,9 +8186,15 @@ cp_parser_type_parameter (cp_parser* parser)
        if (cp_lexer_next_token_is_not (parser->lexer, CPP_EQ)
            && cp_lexer_next_token_is_not (parser->lexer, CPP_GREATER)
            && cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
-         identifier = cp_parser_identifier (parser);
+         {
+           identifier = cp_parser_identifier (parser);
+           /* Treat invalid names as if the parameter were nameless. */
+           if (identifier == error_mark_node)
+             identifier = NULL_TREE;
+         }
        else
          identifier = NULL_TREE;
+
        /* Create the template parameter.  */
        parameter = finish_template_template_parm (class_type_node,
                                                   identifier);
@@ -8231,15 +8237,13 @@ cp_parser_type_parameter (cp_parser* parser)
 
        /* Create the combined representation of the parameter and the
           default argument.  */
-       parameter =  build_tree_list (default_argument, parameter);
+       parameter = build_tree_list (default_argument, parameter);
       }
       break;
 
     default:
-      /* Anything else is an error.  */
-      cp_parser_error (parser,
-                      "expected %<class%>, %<typename%>, or %<template%>");
-      parameter = error_mark_node;
+      gcc_unreachable ();
+      break;
     }
 
   return parameter;
@@ -14801,6 +14805,11 @@ cp_parser_single_declaration (cp_parser* parser,
   cp_decl_specifier_seq decl_specifiers;
   bool function_definition_p = false;
 
+  /* This function is only used when processing a template
+     declaration.  */
+  gcc_assert (innermost_scope_kind () == sk_template_parms
+             || innermost_scope_kind () == sk_template_spec);
+
   /* Defer access checks until we know what is being declared.  */
   push_deferring_access_checks (dk_deferred);
 
@@ -14812,6 +14821,14 @@ cp_parser_single_declaration (cp_parser* parser,
                                &declares_class_or_enum);
   if (friend_p)
     *friend_p = cp_parser_friend_p (&decl_specifiers);
+
+  /* There are no template typedefs.  */
+  if (decl_specifiers.specs[(int) ds_typedef])
+    {
+      error ("template declaration of %qs", "typedef");
+      decl = error_mark_node;
+    }
+
   /* Gather up the access checks that occurred the
      decl-specifier-seq.  */
   stop_deferring_access_checks ();
@@ -14843,8 +14860,6 @@ cp_parser_single_declaration (cp_parser* parser,
            decl = error_mark_node;
        }
     }
-  else
-    decl = NULL_TREE;
   /* 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
@@ -14869,7 +14884,8 @@ cp_parser_single_declaration (cp_parser* parser,
   parser->object_scope = NULL_TREE;
   /* Look for a trailing `;' after the declaration.  */
   if (!function_definition_p
-      && !cp_parser_require (parser, CPP_SEMICOLON, "`;'"))
+      && (decl == error_mark_node
+         || !cp_parser_require (parser, CPP_SEMICOLON, "`;'")))
     cp_parser_skip_to_end_of_block_or_statement (parser);
 
   return decl;
index 3796acee56f9cd3a697c092b16703a3b3b604c24..325dd5682f227b04d98c0a960931ad70763f5a80 100644 (file)
@@ -5099,7 +5099,7 @@ build_const_cast_1 (tree dst_type, tree expr, bool complain,
 tree
 build_const_cast (tree type, tree expr)
 {
-  if (type == error_mark_node || expr == error_mark_node)
+  if (type == error_mark_node || error_operand_p (expr))
     return error_mark_node;
 
   if (processing_template_decl)
index 4ccbd0903f29cdcc759a21eaf790f4cf8e007717..68f830e313f4dbb406cd233d173de782996d5373 100644 (file)
@@ -1,3 +1,15 @@
+2004-11-02  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/18124
+       * g++.dg/template/crash25.C: New test.
+
+       PR c++/18155
+       * g++.dg/template/typedef2.C: New test.
+       * g++.dg/parse/crash13.C: Adjust error markers.
+
+       PR c++/18177
+       * g++.dg/conversion/const3.C: New test.
+       
 2004-11-03  Tobias Schlueter  <tobias.schlueter@physik.uni-muenchen.de>
 
        PR fortran/17535
diff --git a/gcc/testsuite/g++.dg/conversion/const3.C b/gcc/testsuite/g++.dg/conversion/const3.C
new file mode 100644 (file)
index 0000000..faa9f81
--- /dev/null
@@ -0,0 +1,7 @@
+// PR c++/18177
+
+void foo()
+{
+  X; // { dg-error "" }
+  const_cast<int&>(X);
+}
index d9e9087fa0d8d423d81e511b34d68f62ef8fe627..3c298ec8ede58f767d05e6a6eeabcd40ddd8a6bd 100644 (file)
@@ -13,7 +13,7 @@ struct A
 
 template <typename T> 
 void func(A<T>::B* )   // { dg-error "variable|template|expression" }
-{                      // { dg-error ";" }
+{
 }
 
 int main() 
diff --git a/gcc/testsuite/g++.dg/template/crash25.C b/gcc/testsuite/g++.dg/template/crash25.C
new file mode 100644 (file)
index 0000000..fa77f0d
--- /dev/null
@@ -0,0 +1,3 @@
+// PR c++/18124
+
+template <template <int> class class> class A {}; // { dg-error "" }
diff --git a/gcc/testsuite/g++.dg/template/typedef2.C b/gcc/testsuite/g++.dg/template/typedef2.C
new file mode 100644 (file)
index 0000000..6c65671
--- /dev/null
@@ -0,0 +1,3 @@
+// PR c++/18155
+
+template<int> typedef struct A; // { dg-error "" }