re PR c++/38634 (ICE with wrong number of template parameters)
authorPaolo Carlini <paolo.carlini@oracle.com>
Thu, 4 Jul 2013 21:58:35 +0000 (21:58 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Thu, 4 Jul 2013 21:58:35 +0000 (21:58 +0000)
/cp
2013-07-04  Paolo Carlini  <paolo.carlini@oracle.com>

PR c++/38634
* decl.c (start_preparsed_function): Return a bool, false if
push_template_decl fails.
(start_function): Adjust.
* cp-tree.h: Update.

/testsuite
2013-07-04  Paolo Carlini  <paolo.carlini@oracle.com>

PR c++/38634
* g++.dg/template/crash116.C: New.

From-SVN: r200682

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/crash116.C [new file with mode: 0644]

index 92fefea845cb3ccb2370084d2a172a1506decf2b..3a0ba58f7438be58f9b9ce46122064a0c6d0e263 100644 (file)
@@ -1,3 +1,11 @@
+2013-07-04  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       PR c++/38634
+       * decl.c (start_preparsed_function): Return a bool, false if
+       push_template_decl fails.
+       (start_function): Adjust.
+       * cp-tree.h: Update.
+
 2013-07-03  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/57771
index 3e8043a4162692600d4a3a0375232321859c897c..1b0b2435c53d7f6008253fea21316c061ba6745c 100644 (file)
@@ -5206,8 +5206,9 @@ extern void finish_enum_value_list                (tree);
 extern void finish_enum                                (tree);
 extern void build_enumerator                   (tree, tree, tree, location_t);
 extern tree lookup_enumerator                  (tree, tree);
-extern void start_preparsed_function           (tree, tree, int);
-extern int start_function                      (cp_decl_specifier_seq *, const cp_declarator *, tree);
+extern bool start_preparsed_function           (tree, tree, int);
+extern bool start_function                     (cp_decl_specifier_seq *,
+                                                const cp_declarator *, tree);
 extern tree begin_function_body                        (void);
 extern void finish_function_body               (tree);
 extern tree outer_curly_brace_block            (tree);
index 047fd77fd74abb7f83fcc418b347a9c0054cfa4c..54bede00bb1d88881eb20cccf78cb5e75d999baa 100644 (file)
@@ -12993,7 +12993,7 @@ check_function_type (tree decl, tree current_function_parms)
    error_mark_node if the function has never been defined, or
    a BLOCK if the function has been defined somewhere.  */
 
-void
+bool
 start_preparsed_function (tree decl1, tree attrs, int flags)
 {
   tree ctype = NULL_TREE;
@@ -13090,10 +13090,14 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
      by push_nested_class.)  */
   if (processing_template_decl)
     {
-      /* FIXME: Handle error_mark_node more gracefully.  */
       tree newdecl1 = push_template_decl (decl1);
-      if (newdecl1 != error_mark_node)
-       decl1 = newdecl1;
+      if (newdecl1 == error_mark_node)
+       {
+         if (ctype || DECL_STATIC_FUNCTION_P (decl1))
+           pop_nested_class ();
+         return false;
+       }
+      decl1 = newdecl1;
     }
 
   /* We are now in the scope of the function being defined.  */
@@ -13204,7 +13208,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
   /* This function may already have been parsed, in which case just
      return; our caller will skip over the body without parsing.  */
   if (DECL_INITIAL (decl1) != error_mark_node)
-    return;
+    return true;
 
   /* Initialize RTL machinery.  We cannot do this until
      CURRENT_FUNCTION_DECL and DECL_RESULT are set up.  We do this
@@ -13366,17 +13370,19 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
   start_fname_decls ();
 
   store_parm_decls (current_function_parms);
+
+  return true;
 }
 
 
 /* Like start_preparsed_function, except that instead of a
    FUNCTION_DECL, this function takes DECLSPECS and DECLARATOR.
 
-   Returns 1 on success.  If the DECLARATOR is not suitable for a function
-   (it defines a datum instead), we return 0, which tells
-   yyparse to report a parse error.  */
+   Returns true on success.  If the DECLARATOR is not suitable
+   for a function, we return false, which tells the parser to
+   skip the entire function.  */
 
-int
+bool
 start_function (cp_decl_specifier_seq *declspecs,
                const cp_declarator *declarator,
                tree attrs)
@@ -13385,13 +13391,13 @@ start_function (cp_decl_specifier_seq *declspecs,
 
   decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1, &attrs);
   if (decl1 == error_mark_node)
-    return 0;
+    return false;
   /* If the declarator is not suitable for a function definition,
      cause a syntax error.  */
   if (decl1 == NULL_TREE || TREE_CODE (decl1) != FUNCTION_DECL)
     {
       error ("invalid function declaration");
-      return 0;
+      return false;
     }
 
   if (DECL_MAIN_P (decl1))
@@ -13400,9 +13406,7 @@ start_function (cp_decl_specifier_seq *declspecs,
     gcc_assert (same_type_p (TREE_TYPE (TREE_TYPE (decl1)),
                             integer_type_node));
 
-  start_preparsed_function (decl1, attrs, /*flags=*/SF_DEFAULT);
-
-  return 1;
+  return start_preparsed_function (decl1, attrs, /*flags=*/SF_DEFAULT);
 }
 \f
 /* Returns true iff an EH_SPEC_BLOCK should be created in the body of
index 7e72edf668f0b83fcc29ba7f192d8e83f1c06085..09599ffb5de5d9e42c3d3d3b1f83d45bfd4252c5 100644 (file)
@@ -1,3 +1,8 @@
+2013-07-04  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       PR c++/38634
+       * g++.dg/template/crash116.C: New.
+
 2013-07-04  Joern Rennecke <joern.rennecke@embecosm.com>
 
        * gcc.dg/tree-ssa/vrp66.c: Make conditional on { target { ! int16 } } .
diff --git a/gcc/testsuite/g++.dg/template/crash116.C b/gcc/testsuite/g++.dg/template/crash116.C
new file mode 100644 (file)
index 0000000..d26c591
--- /dev/null
@@ -0,0 +1,13 @@
+// PR c++/38634
+
+template<int> struct A
+{
+  A();
+};
+
+template<int N, char> A<N>::A()  // { dg-error "template|required" }
+{
+  struct B {};
+}
+
+A<0> a;