C++ PATCH: PR 21514

Mark Mitchell mark@codesourcery.com
Fri Sep 16 15:47:00 GMT 2005


This patch fixes PR 21514, which is also the subject of DR 488. 

The key question is whether or not SFINAE applies to trying to use a
template function in such a way that an anonymous type would have to
be bound to a template parameter.  A strict reading of the standard
grants no exemption for that case, so before GCC 4.0 I made this an
error.

However, the expected resolution of DR 488 means that SFINAE will
apply.  Since the issue is in draft state, we wouldn't normally adjust
the compiler, but, as others have argued, (a) the change can only
accept invalid programs, not reject valid ones, and (b) the outcome in
the committee seems all but certain, and (c) searching the internet
shows that this issue is frustruating a lot of people upgrade to GCC
4.0.x.  So, I've made the change.

Tested on x86_64-unknown-linux-gnu, applied to mainline and 4.0
branch.

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

2005-09-16  Mark Mitchell  <mark@codesourcery.com>

	PR c++/21514
	* pt.c (check_instantiated_args): Treat uses of anonymous types as
	causing type-deduction failure.

2005-09-16  Mark Mitchell  <mark@codesourcery.com>

	PR c++/21514
	* g++.dg/template/crash19.C: Remove dg-error marker.
	* g++.dg/template/local4.C: New test.

Index: gcc/cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.1037
diff -c -5 -p -r1.1037 pt.c
*** gcc/cp/pt.c	16 Sep 2005 01:50:16 -0000	1.1037
--- gcc/cp/pt.c	16 Sep 2005 04:55:35 -0000
*************** tsubst_copy_and_build (tree t,
*** 8965,8975 ****
  static bool
  check_instantiated_args (tree tmpl, tree args, tsubst_flags_t complain)
  {
    int ix, len = DECL_NTPARMS (tmpl);
    bool result = false;
-   bool error_p = complain & tf_error;
  
    for (ix = 0; ix != len; ix++)
      {
        tree t = TREE_VEC_ELT (args, ix);
  
--- 8965,8974 ----
*************** check_instantiated_args (tree tmpl, tree
*** 8982,8997 ****
  	     template arguments.  */
  	  tree nt = no_linkage_check (t, /*relaxed_p=*/false);
  
  	  if (nt)
  	    {
! 	      if (TYPE_ANONYMOUS_P (nt))
! 		error ("%qT is/uses anonymous type", t);
! 	      else
! 		error ("%qT uses local type %qT", t, nt);
  	      result = true;
- 	      error_p = true;
  	    }
  	  /* In order to avoid all sorts of complications, we do not
  	     allow variably-modified types as template arguments.  */
  	  else if (variably_modified_type_p (t, NULL_TREE))
  	    {
--- 8981,9000 ----
  	     template arguments.  */
  	  tree nt = no_linkage_check (t, /*relaxed_p=*/false);
  
  	  if (nt)
  	    {
! 	      /* DR 488 makes use of a type with no linkage causes
! 		 type deduction to fail.  */ 
! 	      if (complain & tf_error)
! 		{
! 		  if (TYPE_ANONYMOUS_P (nt))
! 		    error ("%qT is/uses anonymous type", t);
! 		  else
! 		    error ("%qT uses local type %qT", t, nt);
! 		}
  	      result = true;
  	    }
  	  /* In order to avoid all sorts of complications, we do not
  	     allow variably-modified types as template arguments.  */
  	  else if (variably_modified_type_p (t, NULL_TREE))
  	    {
*************** check_instantiated_args (tree tmpl, tree
*** 9009,9019 ****
  	  if (complain & tf_error)
  	    error ("integral expression %qE is not constant", t);
  	  result = true;
  	}
      }
!   if (result && error_p)
      error ("  trying to instantiate %qD", tmpl);
    return result;
  }
  
  /* Instantiate the indicated variable or function template TMPL with
--- 9012,9022 ----
  	  if (complain & tf_error)
  	    error ("integral expression %qE is not constant", t);
  	  result = true;
  	}
      }
!   if (result && (complain & tf_error))
      error ("  trying to instantiate %qD", tmpl);
    return result;
  }
  
  /* Instantiate the indicated variable or function template TMPL with
Index: gcc/testsuite/g++.dg/template/crash19.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/template/crash19.C,v
retrieving revision 1.3
diff -c -5 -p -r1.3 crash19.C
*** gcc/testsuite/g++.dg/template/crash19.C	23 Dec 2004 19:54:09 -0000	1.3
--- gcc/testsuite/g++.dg/template/crash19.C	16 Sep 2005 04:55:35 -0000
*************** struct S 
*** 7,17 ****
  int operator *(const double, const S &); 
  template <class T>
  struct X { 
      enum { SIXTY_FOUR=64 }; 
      struct node {
!       unsigned char *ptr[sizeof(T)*SIXTY_FOUR]; // { dg-error "" }
          void d() {}
      };
      node *head; 
  };
  template struct X<int>;
--- 7,17 ----
  int operator *(const double, const S &); 
  template <class T>
  struct X { 
      enum { SIXTY_FOUR=64 }; 
      struct node {
!       unsigned char *ptr[sizeof(T)*SIXTY_FOUR];
          void d() {}
      };
      node *head; 
  };
  template struct X<int>;
Index: gcc/testsuite/g++.dg/template/local4.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/template/local4.C,v
retrieving revision 1.3
diff -c -5 -p -r1.3 local4.C
*** gcc/testsuite/g++.dg/template/local4.C	15 Mar 2005 02:16:24 -0000	1.3
--- gcc/testsuite/g++.dg/template/local4.C	16 Sep 2005 04:55:35 -0000
***************
*** 2,11 ****
  
  template <typename T> void foo() {}
  
  int main () {
    struct S {};
!   // We do not simply use "local|match" on line 10 because we want to
!   // make sure that "local" appears.
!   // { dg-error "local" "local" { target *-*-* } 10 }
!   foo<S> (); // { dg-error "trying|match" } 
  }
--- 2,8 ----
  
  template <typename T> void foo() {}
  
  int main () {
    struct S {};
!   foo<S> (); // { dg-error "match" } 
  }



More information about the Gcc-patches mailing list