re PR c++/16964 (ICE in cp_parser_class_specifier due to redefinition)
authorMark Mitchell <mark@codesourcery.com>
Wed, 11 Aug 2004 22:13:32 +0000 (22:13 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Wed, 11 Aug 2004 22:13:32 +0000 (22:13 +0000)
PR c++/16964
* parser.c (cp_parser_class_specifier): Robustify.

PR c++/16904
* pt.c (tsubst_copy_and_build): Complain about invalid
qualification.

PR c++/16929
* pt.c (tsubst_default_argument): Clear out current_class_ptr and
current_class_ref while tsubsting.

PR c++/16964
* g++.dg/parse/error16.C: New test.

PR c++/16904
* g++.dg/template/error14.C: New test.

PR c++/16929
* g++.dg/template/error15.C: New test.

From-SVN: r85824

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/parse/error16.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/error14.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/error15.C [new file with mode: 0644]

index 269b20bd15e06161415d4116d1a9417e2a5fa035..d15b6faff70b707283f10c1bca48d43d911d34a0 100644 (file)
@@ -1,3 +1,16 @@
+2004-08-11  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/16964
+       * parser.c (cp_parser_class_specifier): Robustify.
+
+       PR c++/16904
+       * pt.c (tsubst_copy_and_build): Complain about invalid
+       qualification.
+
+       PR c++/16929
+       * pt.c (tsubst_default_argument): Clear out current_class_ptr and
+       current_class_ref while tsubsting.
+       
 2004-08-10  Mark Mitchell  <mark@codesourcery.com>
 
        PR c++/16971
index 2176e05eecefeb02703afbcd0798c70fd6731cb5..65872c8de5e81e501d83e3f334965b1db8227b6d 100644 (file)
@@ -12308,6 +12308,7 @@ cp_parser_class_specifier (cp_parser* parser)
   bool nested_name_specifier_p;
   unsigned saved_num_template_parameter_lists;
   bool pop_p = false;
+  tree scope = NULL_TREE;
 
   push_deferring_access_checks (dk_no_deferred);
 
@@ -12343,7 +12344,10 @@ cp_parser_class_specifier (cp_parser* parser)
 
   /* Start the class.  */
   if (nested_name_specifier_p)
-    pop_p = push_scope (CP_DECL_CONTEXT (TYPE_MAIN_DECL (type)));
+    {
+      scope = CP_DECL_CONTEXT (TYPE_MAIN_DECL (type));
+      pop_p = push_scope (scope);
+    }
   type = begin_class_definition (type);
 
   if (type == error_mark_node)
@@ -12368,7 +12372,7 @@ cp_parser_class_specifier (cp_parser* parser)
   if (type != error_mark_node)
     type = finish_struct (type, attributes);
   if (pop_p)
-    pop_scope (CP_DECL_CONTEXT (TYPE_MAIN_DECL (type)));
+    pop_scope (scope);
   /* If this class is not itself within the scope of another class,
      then we need to parse the bodies of all of the queued function
      definitions.  Note that the queued functions defined in a class
index 14b0c837cf24a9bea4a21a25c20a5015b5d1bdba..0574f44f1ad3efc5ab86ee6fc7cc06ab993c2eb2 100644 (file)
@@ -5942,6 +5942,9 @@ tsubst_aggr_type (tree t,
 tree
 tsubst_default_argument (tree fn, tree type, tree arg)
 {
+  tree saved_class_ptr = NULL_TREE;
+  tree saved_class_ref = NULL_TREE;
+
   /* This default argument came from a template.  Instantiate the
      default argument here, not in tsubst.  In the case of
      something like: 
@@ -5959,12 +5962,27 @@ tsubst_default_argument (tree fn, tree type, tree arg)
      within the scope of FN.  Since push_access_scope sets
      current_function_decl, we must explicitly clear it here.  */
   current_function_decl = NULL_TREE;
+  /* The "this" pointer is not valid in a default argument.  */
+  if (cfun)
+    {
+      saved_class_ptr = current_class_ptr;
+      cp_function_chain->x_current_class_ptr = NULL_TREE;
+      saved_class_ref = current_class_ref;
+      cp_function_chain->x_current_class_ref = NULL_TREE;
+    }
 
   push_deferring_access_checks(dk_no_deferred);
   arg = tsubst_expr (arg, DECL_TI_ARGS (fn),
                     tf_error | tf_warning, NULL_TREE);
   pop_deferring_access_checks();
 
+  /* Restore the "this" pointer.  */
+  if (cfun)
+    {
+      cp_function_chain->x_current_class_ptr = saved_class_ptr;
+      cp_function_chain->x_current_class_ref = saved_class_ref;
+    }
+
   pop_access_scope (fn);
 
   /* Make sure the default argument is reasonable.  */
@@ -8495,6 +8513,21 @@ tsubst_copy_and_build (tree t,
                return error_mark_node;
              }
          }
+       else if (TREE_CODE (member) == SCOPE_REF
+                && !CLASS_TYPE_P (TREE_OPERAND (member, 0))
+                && TREE_CODE (TREE_OPERAND (member, 0)) != NAMESPACE_DECL)
+         {
+           if (complain & tf_error)
+             {
+               if (TYPE_P (TREE_OPERAND (member, 0)))
+                 error ("`%T' is not a class or namespace", 
+                        TREE_OPERAND (member, 0));
+               else
+                 error ("`%D' is not a class or namespace", 
+                        TREE_OPERAND (member, 0));
+             }
+           return error_mark_node;
+         }
        else if (TREE_CODE (member) == FIELD_DECL)
          return finish_non_static_data_member (member, object, NULL_TREE);
 
index c4226dc7b0acd399b18f917ddfd2e6aaee00f20f..9959a9d170948ed22a9cfb0f500059b4e9339a15 100644 (file)
@@ -1,3 +1,14 @@
+2004-08-11  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/16964
+       * g++.dg/parse/error16.C: New test.
+
+       PR c++/16904
+       * g++.dg/template/error14.C: New test.
+
+       PR c++/16929
+       * g++.dg/template/error15.C: New test.
+
 2004-08-11  Devang Patel  <dpatel@apple.com>
 
        * gcc.dg/darwin-ld-20040809-1.c: New test.
diff --git a/gcc/testsuite/g++.dg/parse/error16.C b/gcc/testsuite/g++.dg/parse/error16.C
new file mode 100644 (file)
index 0000000..afc790e
--- /dev/null
@@ -0,0 +1,8 @@
+// PR c++/16964
+
+struct A
+{
+  struct B {}; // { dg-error "" }
+};
+
+struct A::B{}; // { dg-error "" }
diff --git a/gcc/testsuite/g++.dg/template/error14.C b/gcc/testsuite/g++.dg/template/error14.C
new file mode 100644 (file)
index 0000000..c5043cf
--- /dev/null
@@ -0,0 +1,8 @@
+// PR c++/16904
+
+template<typename T> struct X
+{
+  X() { this->T::i; } // { dg-error "" }
+};
+
+X<int> x;
diff --git a/gcc/testsuite/g++.dg/template/error15.C b/gcc/testsuite/g++.dg/template/error15.C
new file mode 100644 (file)
index 0000000..5a1a322
--- /dev/null
@@ -0,0 +1,24 @@
+// PR c++/16929
+
+template <class T>
+class A {
+  int x;
+};
+
+template <class T>
+class B {
+protected:
+    
+  A<T> a; // { dg-error "" }
+    
+  void f(const A<T> * a1 = &a);
+    
+  void g(void);
+};
+
+template <class T>
+void B<T>::g(void) {
+  f(); // { dg-error "" }
+}
+
+template class B<long>; // { dg-error "" }