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]:Fix 14007


Mark,
this patch fixes 14007.  Although I think we were all in agreement
about what should happen, only John Spicer could point to the bit
in the standard which says it.

This patch is against 3.4 and fixes our non-implementation of DR295.
I'm installing this on HEAD. I am retargetting the bug to 3.4.1, to remind
us to fix it there too.

built & tested on i686-pc-linux-gnu.

nathan
--
Nathan Sidwell    ::   http://www.codesourcery.com   ::     CodeSourcery LLC
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk

2004-04-02  Nathan Sidwell  <nathan@codesourcery.com>

	PR c++/14007
	* pt.c (check_cv_quals_for_unify): Correct logic for disallowed
	cv-qualifier unification.
	* tree.c (cp_build_qualified_type_real): Renable DR295 logic.

Index: cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.816.2.23
diff -c -3 -p -r1.816.2.23 pt.c
*** cp/pt.c	31 Mar 2004 02:09:59 -0000	1.816.2.23
--- cp/pt.c	1 Apr 2004 14:12:45 -0000
*************** template_decl_level (tree decl)
*** 9540,9546 ****
  
  /* Decide whether ARG can be unified with PARM, considering only the
     cv-qualifiers of each type, given STRICT as documented for unify.
!    Returns nonzero iff the unification is OK on that basis.*/
  
  static int
  check_cv_quals_for_unify (int strict, tree arg, tree parm)
--- 9540,9546 ----
  
  /* Decide whether ARG can be unified with PARM, considering only the
     cv-qualifiers of each type, given STRICT as documented for unify.
!    Returns nonzero iff the unification is OK on that basis. */
  
  static int
  check_cv_quals_for_unify (int strict, tree arg, tree parm)
*************** check_cv_quals_for_unify (int strict, tr
*** 9550,9564 ****
  
    if (TREE_CODE (parm) == TEMPLATE_TYPE_PARM)
      {
!       /* If the cvr quals of parm will not unify with ARG, they'll be
! 	 ignored in instantiation, so we have to do the same here.  */
!       if (TREE_CODE (arg) == REFERENCE_TYPE)
! 	parm_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
!       if (!POINTER_TYPE_P (arg) &&
! 	  TREE_CODE (arg) != TEMPLATE_TYPE_PARM)
! 	parm_quals &= ~TYPE_QUAL_RESTRICT;
      }
!   
    if (!(strict & (UNIFY_ALLOW_MORE_CV_QUAL | UNIFY_ALLOW_OUTER_MORE_CV_QUAL))
        && (arg_quals & parm_quals) != parm_quals)
      return 0;
--- 9550,9571 ----
  
    if (TREE_CODE (parm) == TEMPLATE_TYPE_PARM)
      {
!       /*  Although a CVR qualifier is ignored when being applied to a
!           substituted template parameter ([8.3.2]/1 for example), that
!           does not apply during deduction [14.8.2.4]/1, (even though
!           that is not explicitly mentioned, [14.8.2.4]/9 indicates
!           this). */
!       if ((TREE_CODE (arg) == REFERENCE_TYPE
! 	   || TREE_CODE (arg) == FUNCTION_TYPE
! 	   || TREE_CODE (arg) == METHOD_TYPE)
! 	  && (parm_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE)))
! 	return 0;
! 
!       if ((!POINTER_TYPE_P (arg) && TREE_CODE (arg) != TEMPLATE_TYPE_PARM)
! 	  && (parm_quals & TYPE_QUAL_RESTRICT))
! 	return 0;
      }
! 
    if (!(strict & (UNIFY_ALLOW_MORE_CV_QUAL | UNIFY_ALLOW_OUTER_MORE_CV_QUAL))
        && (arg_quals & parm_quals) != parm_quals)
      return 0;
Index: cp/tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/tree.c,v
retrieving revision 1.360.4.5
diff -c -3 -p -r1.360.4.5 tree.c
*** cp/tree.c	19 Mar 2004 07:13:37 -0000	1.360.4.5
--- cp/tree.c	1 Apr 2004 14:12:49 -0000
*************** cp_build_qualified_type_real (tree type,
*** 427,437 ****
  {
    tree result;
    int bad_quals = TYPE_UNQUALIFIED;
-   /* We keep bad function qualifiers separate, so that we can decide
-      whether to implement DR 295 or not. DR 295 break existing code,
-      unfortunately. Remove this variable to implement the defect
-      report.  */
-   int bad_func_quals = TYPE_UNQUALIFIED;
  
    if (type == error_mark_node)
      return type;
--- 427,432 ----
*************** cp_build_qualified_type_real (tree type,
*** 501,508 ****
  	  || TREE_CODE (type) == METHOD_TYPE))
      {
        bad_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
-       if (TREE_CODE (type) != REFERENCE_TYPE)
- 	bad_func_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
        type_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
      }
    
--- 496,501 ----
*************** cp_build_qualified_type_real (tree type,
*** 521,541 ****
      /*OK*/;
    else if (!(complain & (tf_error | tf_ignore_bad_quals)))
      return error_mark_node;
-   else if (bad_func_quals && !(complain & tf_error))
-     return error_mark_node;
    else
      {
        if (complain & tf_ignore_bad_quals)
   	/* We're not going to warn about constifying things that can't
   	   be constified.  */
   	bad_quals &= ~TYPE_QUAL_CONST;
-       bad_quals |= bad_func_quals;
        if (bad_quals)
   	{
   	  tree bad_type = build_qualified_type (ptr_type_node, bad_quals);
   
!  	  if (!(complain & tf_ignore_bad_quals)
! 	      || bad_func_quals)
   	    error ("`%V' qualifiers cannot be applied to `%T'",
  		   bad_type, type);
   	}
--- 514,530 ----
      /*OK*/;
    else if (!(complain & (tf_error | tf_ignore_bad_quals)))
      return error_mark_node;
    else
      {
        if (complain & tf_ignore_bad_quals)
   	/* We're not going to warn about constifying things that can't
   	   be constified.  */
   	bad_quals &= ~TYPE_QUAL_CONST;
        if (bad_quals)
   	{
   	  tree bad_type = build_qualified_type (ptr_type_node, bad_quals);
   
!  	  if (!(complain & tf_ignore_bad_quals))
   	    error ("`%V' qualifiers cannot be applied to `%T'",
  		   bad_type, type);
   	}
Index: testsuite/g++.dg/template/qualttp20.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/template/qualttp20.C,v
retrieving revision 1.4
diff -c -3 -p -r1.4 qualttp20.C
*** testsuite/g++.dg/template/qualttp20.C	16 Sep 2002 19:09:05 -0000	1.4
--- testsuite/g++.dg/template/qualttp20.C	1 Apr 2004 14:13:15 -0000
*************** template <typename T> struct B1 : T
*** 19,35 ****
    typedef typename T::myT __restrict__ p;// { dg-warning "ignoring `__restrict'" "" { xfail *-*-* } }
  
    // The following are DR 295 dependent
!   typedef typename T::myT volatile *myvolatile; // { dg-error "qualifiers" ""  }
!   typename T::myT volatile *a;    // { dg-error "qualifiers" "" }
!   myvolatile b;			 // { dg-error "qualifiers" "" }
  };
  template <typename T> struct B2 : T
  {
    // The following are DR 295 dependent
!   typedef typename T::myT const *myconst; // { dg-error "qualifiers" "" }
!   typename T::myT const *a; // { dg-error "qualifiers" "" }
!   myconst b; // { dg-error "qualifiers" "" }
  };
  
  B1<AS> b1;	// { dg-error "instantiated" "" }
! B2<AS> b2;      // { dg-error "instantiated" "" }	
--- 19,35 ----
    typedef typename T::myT __restrict__ p;// { dg-warning "ignoring `__restrict'" "" { xfail *-*-* } }
  
    // The following are DR 295 dependent
!   typedef typename T::myT volatile *myvolatile;
!   typename T::myT volatile *a;
!   myvolatile b;
  };
  template <typename T> struct B2 : T
  {
    // The following are DR 295 dependent
!   typedef typename T::myT const *myconst;
!   typename T::myT const *a;
!   myconst b;
  };
  
  B1<AS> b1;	// { dg-error "instantiated" "" }
! B2<AS> b2;
Index: testsuite/g++.old-deja/g++.jason/report.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.old-deja/g++.jason/report.C,v
retrieving revision 1.10
diff -c -3 -p -r1.10 report.C
*** testsuite/g++.old-deja/g++.jason/report.C	1 May 2003 02:02:40 -0000	1.10
--- testsuite/g++.old-deja/g++.jason/report.C	1 Apr 2004 14:13:20 -0000
*************** class X{
*** 47,54 ****
  
  typedef int const * bart ();
  //The following is DR295 dependant
! typedef bart const * const * bar2; // { dg-error "" } constifying qualifiers
! typedef bart volatile * const * bar2v; // { dg-error "" } qualifiers
  
  bar2 baz (X::Y y)
  {				// { dg-error "" } in this context
--- 47,54 ----
  
  typedef int const * bart ();
  //The following is DR295 dependant
! typedef bart const * const * bar2;
! typedef bart volatile * const * bar2v;
  
  bar2 baz (X::Y y)
  {				// { dg-error "" } in this context
Index: testsuite/g++.old-deja/g++.other/qual1.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.old-deja/g++.other/qual1.C,v
retrieving revision 1.5
diff -c -3 -p -r1.5 qual1.C
*** testsuite/g++.old-deja/g++.other/qual1.C	1 May 2003 02:02:50 -0000	1.5
--- testsuite/g++.old-deja/g++.other/qual1.C	1 Apr 2004 14:13:26 -0000
*************** class
*** 11,18 ****
  public:
    func_type *Function;
    // The following is DR 295 dependent
!   const func_type* function(void) { return Function; } // { dg-error "" } constifying
!   volatile func_type* functionv(void); // { dg-error "" } qualifier
  } action;
  
  void work(const char *source)
--- 11,18 ----
  public:
    func_type *Function;
    // The following is DR 295 dependent
!   const func_type* function(void) { return Function; }
!   volatile func_type* functionv(void);
  } action;
  
  void work(const char *source)
// Copyright (C) 2004 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 1 Apr 2004 <nathan@codesourcery.com>
// Origin:Matt Austern <austern@apple.com>

// PR:c++/14007

template <typename T> struct X {};  // #1
template <typename T> struct X<const T>; //#2
template struct X<int&>; //#3
// Copyright (C) 2004 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 1 Apr 2004 <nathan@codesourcery.com>

void Baz ();

template <typename T> void Foo1 (T *); // #1
template <typename T> void Foo1 (T const *a) {a (1);} // #2

template <typename T> T const *Foo2 (T *);

template <typename T> void Foo3 (T *, T const * = 0);

void Bar ()
{
  Foo1 (&Baz); // #1

  Foo2 (&Baz);

  Foo3 (&Baz);

  Foo3 (&Baz, &Baz); // { dg-error "no matching function" "" }
}

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