This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH: PR c++/16964, c++/16904, c++/16929


This patch fixes three little C++ regressions on the GCC 3.4 branch.

Tested on i686-pc-linux-gnu, applied on the branch and on the
mainline.

--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com

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-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.

Index: cp/parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.233
diff -c -5 -p -r1.233 parser.c
*** cp/parser.c	11 Aug 2004 00:14:35 -0000	1.233
--- cp/parser.c	11 Aug 2004 20:01:51 -0000
*************** cp_parser_class_specifier (cp_parser* pa
*** 12306,12315 ****
--- 12306,12316 ----
    tree attributes = NULL_TREE;
    int has_trailing_semicolon;
    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);
  
    /* Parse the class-head.  */
    type = cp_parser_class_head (parser,
*************** cp_parser_class_specifier (cp_parser* pa
*** 12341,12351 ****
      = parser->num_template_parameter_lists;
    parser->num_template_parameter_lists = 0;
  
    /* Start the class.  */
    if (nested_name_specifier_p)
!     pop_p = push_scope (CP_DECL_CONTEXT (TYPE_MAIN_DECL (type)));
    type = begin_class_definition (type);
  
    if (type == error_mark_node)
      /* If the type is erroneous, skip the entire body of the class.  */
      cp_parser_skip_to_closing_brace (parser);
--- 12342,12355 ----
      = parser->num_template_parameter_lists;
    parser->num_template_parameter_lists = 0;
  
    /* Start the class.  */
    if (nested_name_specifier_p)
!     {
!       scope = CP_DECL_CONTEXT (TYPE_MAIN_DECL (type));
!       pop_p = push_scope (scope);
!     }
    type = begin_class_definition (type);
  
    if (type == error_mark_node)
      /* If the type is erroneous, skip the entire body of the class.  */
      cp_parser_skip_to_closing_brace (parser);
*************** cp_parser_class_specifier (cp_parser* pa
*** 12366,12376 ****
        attributes = chainon (attributes, sub_attr);
      }
    if (type != error_mark_node)
      type = finish_struct (type, attributes);
    if (pop_p)
!     pop_scope (CP_DECL_CONTEXT (TYPE_MAIN_DECL (type)));
    /* 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
       are not always processed immediately following the
       class-specifier for that class.  Consider:
--- 12370,12380 ----
        attributes = chainon (attributes, sub_attr);
      }
    if (type != error_mark_node)
      type = finish_struct (type, attributes);
    if (pop_p)
!     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
       are not always processed immediately following the
       class-specifier for that class.  Consider:
Index: cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.901
diff -c -5 -p -r1.901 pt.c
*** cp/pt.c	4 Aug 2004 05:27:51 -0000	1.901
--- cp/pt.c	11 Aug 2004 20:01:52 -0000
*************** tsubst_aggr_type (tree t, 
*** 5940,5949 ****
--- 5940,5952 ----
     FN), which has the indicated TYPE.  */
  
  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: 
       
         template <class T>
*************** tsubst_default_argument (tree fn, tree t
*** 5957,5972 ****
--- 5960,5990 ----
    push_access_scope (fn);
    /* The default argument expression should not be considered to be
       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.  */
    arg = check_default_argument (type, arg);
  
*************** tsubst_copy_and_build (tree t, 
*** 8493,8502 ****
--- 8511,8535 ----
  	      {
  		qualified_name_lookup_error (TREE_TYPE (object), tmpl);
  		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);
  
  	return finish_class_member_access_expr (object, member);
        }
Index: testsuite/g++.dg/parse/error16.C
===================================================================
RCS file: testsuite/g++.dg/parse/error16.C
diff -N testsuite/g++.dg/parse/error16.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/parse/error16.C	11 Aug 2004 20:01:53 -0000
***************
*** 0 ****
--- 1,8 ----
+ // PR c++/16964
+ 
+ struct A
+ {
+   struct B {}; // { dg-error "" }
+ };
+ 
+ struct A::B{}; // { dg-error "" }
Index: testsuite/g++.dg/template/error14.C
===================================================================
RCS file: testsuite/g++.dg/template/error14.C
diff -N testsuite/g++.dg/template/error14.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/template/error14.C	11 Aug 2004 20:01:53 -0000
***************
*** 0 ****
--- 1,8 ----
+ // PR c++/16904
+ 
+ template<typename T> struct X
+ {
+   X() { this->T::i; } // { dg-error "" }
+ };
+ 
+ X<int> x;
Index: testsuite/g++.dg/template/error15.C
===================================================================
RCS file: testsuite/g++.dg/template/error15.C
diff -N testsuite/g++.dg/template/error15.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/template/error15.C	11 Aug 2004 20:01:53 -0000
***************
*** 0 ****
--- 1,24 ----
+ // PR c++/16929
+ 
+ template <class T>
+ class A {
+   int x;
+ };
+ 
+ template <class T>
+ class B {
+ protected:
+     
+   A<T> a;
+     
+   void f(const A<T> * a1 = &a);
+     
+   void g(void);
+ };
+ 
+ template <class T>
+ void B<T>::g(void) {
+   f();
+ }
+ 
+ template class B<long>;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]