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 18389, 18429, 18436, 18407


Here are fixes for a few miscellaneous regressions.

18389: start_decl had a confusing interface.  In some cases it failed
to initialize one of its out parameters, and it sometimes returned
NULL_TREE to indicate error; other times it returned error_mark_node.
Fixed by making it (a) initialize the parameter, and (b) always return
error_mark_node on error.

18429: An ICE involving VLAs as non-static data members in template
classes.  Fixed by making the parser detect the situation early, issue
an error message, which avoids the rest of the front end ever seeing
such dubious constructs.

18436: We were doing Koenig lookup even after unqualified name lookup
found a member function, which is wrong.

18407: When a template function used a qualified name to call a
function in a base class, we got confused about adjusting the "this"
pointer.  Fixed by doing a bit more of what we would do in the
non-template case.

Tested on i686-pc-linux-gnu, applied on the mainline.  The 18389,
18407, and 18436 fixes will go on the 3.4 branch as well, after
testing.

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

2004-11-12  Mark Mitchell  <mark@codesourcery.com>

	PR c++/18389
	* decl.c (start_decl): Make sure to set *pop_scope_p.  Return
	error_mark_node to indicate errors.

	PR c++/18429
	* parser.c (cp_parser_direct_declarator): Disallow non-constant
	array bounds when not inside a function.

	PR c++/18436
	* pt.c (tsubst_copy_and_build): Do not do Koenig lookup when an
	unqualified name resolves to a member function.

	PR c++/18407
	* pt.c (tsubst_copy_and_build): Handle qualified names used from a
	derived class correctly.
	
	* decl2.c (import_export_decl): Fix typo in comment.
	* tree.c (pod_type_p): Likewise.

2004-11-12  Mark Mitchell  <mark@codesourcery.com>

	PR c++/18389
	* g++.dg/parse/cond1.C: New test.

	PR c++/18429
	* g++.dg/template/array9.C: New test.
	* g++.dg/ext/vla1.C: Adjust error messages.
	* g++.dg/ext/vlm1.C: Likewise.
	* g++.dg/template/crash2.C: Likewise.

	PR c++/18436
	* g++.dg/template/call3.C: New test.

	PR c++/18407
	* g++.dg/template/ptrmem11.C: New test.

Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.1326
diff -c -5 -p -r1.1326 decl.c
*** cp/decl.c	9 Nov 2004 10:12:33 -0000	1.1326
--- cp/decl.c	12 Nov 2004 21:24:21 -0000
*************** start_decl (const cp_declarator *declara
*** 3668,3677 ****
--- 3668,3679 ----
  {
    tree decl;
    tree type, tem;
    tree context;
  
+   *pop_scope_p = false;
+  
    /* This should only be done once on the top most decl.  */
    if (have_extern_spec)
      {
        declspecs->storage_class = sc_extern;
        have_extern_spec = false;
*************** start_decl (const cp_declarator *declara
*** 3688,3710 ****
  			 &attributes);
  
    deprecated_state = DEPRECATED_NORMAL;
  
    if (decl == NULL_TREE || TREE_CODE (decl) == VOID_TYPE)
!     return NULL_TREE;
  
    type = TREE_TYPE (decl);
  
    if (type == error_mark_node)
!     return NULL_TREE;
  
    context = DECL_CONTEXT (decl);
  
    if (context)
      *pop_scope_p = push_scope (context);
-   else
-     *pop_scope_p = false;
    
    /* We are only interested in class contexts, later.  */
    if (context && TREE_CODE (context) == NAMESPACE_DECL)
      context = NULL_TREE;
  
--- 3690,3710 ----
  			 &attributes);
  
    deprecated_state = DEPRECATED_NORMAL;
  
    if (decl == NULL_TREE || TREE_CODE (decl) == VOID_TYPE)
!     return error_mark_node;
  
    type = TREE_TYPE (decl);
  
    if (type == error_mark_node)
!     return error_mark_node;
  
    context = DECL_CONTEXT (decl);
  
    if (context)
      *pop_scope_p = push_scope (context);
    
    /* We are only interested in class contexts, later.  */
    if (context && TREE_CODE (context) == NAMESPACE_DECL)
      context = NULL_TREE;
  
Index: cp/decl2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl2.c,v
retrieving revision 1.756
diff -c -5 -p -r1.756 decl2.c
*** cp/decl2.c	9 Nov 2004 10:12:35 -0000	1.756
--- cp/decl2.c	12 Nov 2004 21:24:21 -0000
*************** import_export_decl (tree decl)
*** 1741,1751 ****
    /* Object file linkage for explicit instantiations is handled in
       mark_decl_instantiated.  For static variables in functions with
       vague linkage, maybe_commonize_var is used.
  
       Therefore, the only declarations that should be provided to this
!      function are those with external linkage that:
  
       * implicit instantiations of function templates
  
       * inline function
  
--- 1741,1751 ----
    /* Object file linkage for explicit instantiations is handled in
       mark_decl_instantiated.  For static variables in functions with
       vague linkage, maybe_commonize_var is used.
  
       Therefore, the only declarations that should be provided to this
!      function are those with external linkage that are:
  
       * implicit instantiations of function templates
  
       * inline function
  
Index: cp/parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.278
diff -c -5 -p -r1.278 parser.c
*** cp/parser.c	9 Nov 2004 10:12:37 -0000	1.278
--- cp/parser.c	12 Nov 2004 21:24:21 -0000
*************** cp_parser_direct_declarator (cp_parser* 
*** 10958,10967 ****
--- 10958,10972 ----
  		= cp_parser_constant_expression (parser,
  						 /*allow_non_constant=*/true,
  						 &non_constant_p);
  	      if (!non_constant_p)
  		bounds = fold_non_dependent_expr (bounds);
+ 	      else if (!at_function_scope_p ())
+ 		{
+ 		  error ("array bound is not an integer constant");
+ 		  bounds = error_mark_node;
+ 		}
  	    }
  	  else
  	    bounds = NULL_TREE;
  	  /* Look for the closing `]'.  */
  	  if (!cp_parser_require (parser, CPP_CLOSE_SQUARE, "`]'"))
Index: cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.944
diff -c -5 -p -r1.944 pt.c
*** cp/pt.c	9 Nov 2004 10:12:40 -0000	1.944
--- cp/pt.c	12 Nov 2004 21:24:21 -0000
*************** tsubst_copy_and_build (tree t, 
*** 8541,8551 ****
  
  	/* We do not perform argument-dependent lookup if normal
  	   lookup finds a non-function, in accordance with the
  	   expected resolution of DR 218.  */
  	if (koenig_p
! 	    && (is_overloaded_fn (function)
  		|| TREE_CODE (function) == IDENTIFIER_NODE))
  	  function = perform_koenig_lookup (function, call_args);
  
  	if (TREE_CODE (function) == IDENTIFIER_NODE)
  	  {
--- 8541,8555 ----
  
  	/* We do not perform argument-dependent lookup if normal
  	   lookup finds a non-function, in accordance with the
  	   expected resolution of DR 218.  */
  	if (koenig_p
! 	    && ((is_overloaded_fn (function)
! 		 /* If lookup found a member function, the Koenig lookup is
! 		    not appropriate, even if an unqualified-name was used
! 		    to denote the function.  */
! 		 && !DECL_FUNCTION_MEMBER_P (get_first_fn (function)))
  		|| TREE_CODE (function) == IDENTIFIER_NODE))
  	  function = perform_koenig_lookup (function, call_args);
  
  	if (TREE_CODE (function) == IDENTIFIER_NODE)
  	  {
*************** tsubst_copy_and_build (tree t, 
*** 8657,8669 ****
  	    args = TREE_OPERAND (TREE_OPERAND (member, 1), 1);
  	    member = lookup_qualified_name (TREE_OPERAND (member, 0), tmpl, 
  					    /*is_type_p=*/false,
  					    /*complain=*/false);
  	    if (BASELINK_P (member))
! 	      BASELINK_FUNCTIONS (member) 
! 		= build_nt (TEMPLATE_ID_EXPR, BASELINK_FUNCTIONS (member),
! 			    args);
  	    else
  	      {
  		qualified_name_lookup_error (TREE_TYPE (object), tmpl,
  					     member);
  		return error_mark_node;
--- 8661,8678 ----
  	    args = TREE_OPERAND (TREE_OPERAND (member, 1), 1);
  	    member = lookup_qualified_name (TREE_OPERAND (member, 0), tmpl, 
  					    /*is_type_p=*/false,
  					    /*complain=*/false);
  	    if (BASELINK_P (member))
! 	      {
! 		BASELINK_FUNCTIONS (member) 
! 		  = build_nt (TEMPLATE_ID_EXPR, BASELINK_FUNCTIONS (member),
! 			      args);
! 		member = (adjust_result_of_qualified_name_lookup 
! 			  (member, BINFO_TYPE (BASELINK_BINFO (member)), 
! 			   TREE_TYPE (object)));
! 	      }
  	    else
  	      {
  		qualified_name_lookup_error (TREE_TYPE (object), tmpl,
  					     member);
  		return error_mark_node;
Index: cp/tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/tree.c,v
retrieving revision 1.418
diff -c -5 -p -r1.418 tree.c
*** cp/tree.c	18 Oct 2004 17:21:28 -0000	1.418
--- cp/tree.c	12 Nov 2004 21:24:25 -0000
*************** pod_type_p (tree t)
*** 1714,1724 ****
      return 1; /* pointer to non-member */
    if (TYPE_PTR_TO_MEMBER_P (t))
      return 1; /* pointer to member */
  
    if (TREE_CODE (t) == VECTOR_TYPE)
!     return 1; /* vectors are (small) arrays if scalars */
  
    if (! CLASS_TYPE_P (t))
      return 0; /* other non-class type (reference or function) */
    if (CLASSTYPE_NON_POD_P (t))
      return 0;
--- 1714,1724 ----
      return 1; /* pointer to non-member */
    if (TYPE_PTR_TO_MEMBER_P (t))
      return 1; /* pointer to member */
  
    if (TREE_CODE (t) == VECTOR_TYPE)
!     return 1; /* vectors are (small) arrays of scalars */
  
    if (! CLASS_TYPE_P (t))
      return 0; /* other non-class type (reference or function) */
    if (CLASSTYPE_NON_POD_P (t))
      return 0;
Index: testsuite/g++.dg/ext/vla1.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/ext/vla1.C,v
retrieving revision 1.1
diff -c -5 -p -r1.1 vla1.C
*** testsuite/g++.dg/ext/vla1.C	25 Oct 2002 17:26:52 -0000	1.1
--- testsuite/g++.dg/ext/vla1.C	12 Nov 2004 21:24:31 -0000
*************** A::A (int i)
*** 17,26 ****
  class B { B (int); };
  
  B::B (int i)
  {
    struct S {
!     int ar[1][i];  // { dg-error "variable-size|variably modified" }
    } s;
  
    s.ar[0][0] = 0;  // { dg-error "no member" }
  }
--- 17,26 ----
  class B { B (int); };
  
  B::B (int i)
  {
    struct S {
!     int ar[1][i];  // { dg-error "array" }
    } s;
  
    s.ar[0][0] = 0;  // { dg-error "no member" }
  }
Index: testsuite/g++.dg/ext/vlm1.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/ext/vlm1.C,v
retrieving revision 1.2
diff -c -5 -p -r1.2 vlm1.C
*** testsuite/g++.dg/ext/vlm1.C	22 Mar 2003 15:34:40 -0000	1.2
--- testsuite/g++.dg/ext/vlm1.C	12 Nov 2004 21:24:31 -0000
***************
*** 2,12 ****
  
  template <class T> struct A {};
   
  struct B {
    static const int s;
!   A<int[s]> a; // { dg-error "variably modified|no type|trying to instantiate" }
  };
   
  const int B::s=16;
   
  B b;
--- 2,12 ----
  
  template <class T> struct A {};
   
  struct B {
    static const int s;
!   A<int[s]> a; // { dg-error "array|template" }
  };
   
  const int B::s=16;
   
  B b;
Index: testsuite/g++.dg/parse/cond1.C
===================================================================
RCS file: testsuite/g++.dg/parse/cond1.C
diff -N testsuite/g++.dg/parse/cond1.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/parse/cond1.C	12 Nov 2004 21:24:31 -0000
***************
*** 0 ****
--- 1,6 ----
+ // PR c++/18389
+ 
+ void foo()
+ {
+   for (; struct A {}; ); // { dg-error "" }
+ }
Index: testsuite/g++.dg/template/array9.C
===================================================================
RCS file: testsuite/g++.dg/template/array9.C
diff -N testsuite/g++.dg/template/array9.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/template/array9.C	12 Nov 2004 21:24:31 -0000
***************
*** 0 ****
--- 1,18 ----
+ // PR c++/18407
+ 
+ int subtrees = 4;
+ template< class T >
+ struct Tree {
+   Tree* L[subtrees]; // { dg-error "" }
+   Tree* R[subtrees]; // { dg-error "" }
+   ~Tree()
+   {
+     delete [] L[0]; // { dg-error "" }
+     delete [] R[0]; // { dg-error "" }
+   }
+ };
+ 
+ void f()
+ {
+   Tree<int> t;
+ }
Index: testsuite/g++.dg/template/call3.C
===================================================================
RCS file: testsuite/g++.dg/template/call3.C
diff -N testsuite/g++.dg/template/call3.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/template/call3.C	12 Nov 2004 21:24:31 -0000
***************
*** 0 ****
--- 1,15 ----
+ // PR c++/18436
+ 
+ void foo(int);
+ 
+ struct A
+ {
+   static void foo(A);
+ };
+ 
+ template <typename T> struct B : T
+ {
+   B() { foo(T()); }
+ };
+ 
+ B<A> b;
Index: testsuite/g++.dg/template/crash2.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/template/crash2.C,v
retrieving revision 1.2
diff -c -5 -p -r1.2 crash2.C
*** testsuite/g++.dg/template/crash2.C	16 Jan 2003 20:30:46 -0000	1.2
--- testsuite/g++.dg/template/crash2.C	12 Nov 2004 21:24:31 -0000
***************
*** 3,13 ****
  template <class EnumType>
  class A
  {
  public:
    static const EnumType size = max; // { dg-error "" }
!   int table[size];
  };
  template <class EnumType>
  const EnumType A<EnumType>::size;
   
   
--- 3,13 ----
  template <class EnumType>
  class A
  {
  public:
    static const EnumType size = max; // { dg-error "" }
!   int table[size]; // { dg-error "" }
  };
  template <class EnumType>
  const EnumType A<EnumType>::size;
   
   
Index: testsuite/g++.dg/template/ptrmem11.C
===================================================================
RCS file: testsuite/g++.dg/template/ptrmem11.C
diff -N testsuite/g++.dg/template/ptrmem11.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/template/ptrmem11.C	12 Nov 2004 21:24:31 -0000
***************
*** 0 ****
--- 1,19 ----
+ // PR c++/18407
+ 
+ template <typename Class>
+ struct the_base{
+   template <void (Class::*Fn)()> void foo() { }
+ };
+ 
+ template <typename T>
+ struct derivedT: the_base<derivedT<T> > {
+   typedef the_base<derivedT<T> > parent;
+   void ice(){
+     this->parent::template foo< &derivedT<T>::ice>();
+   }
+ };
+ 
+ int main() {
+   derivedT<int> dT;
+   dT.ice();
+ }


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