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 for PR c++/19076 and PR c++/6628


This patch for mainline CVS fixes C++ PRs 19076 and 6628 and
implements the resolution to DR 195 (unless -pedantic is specified, in
which case it warns first). It obsoletes my prior attempt at
http://gcc.gnu.org/ml/gcc-patches/2005-01/msg01341.html. Tested on
i686-pc-linux-gnu: no new regressions, the two new tests pass, and two
existing xfail'd tests now pass. All of the examples from the two PRs
this fixes (including Giovanni's test case from yesterday) work
properly. 

The patch is split into two parts: the C++ front end changes (-cp) and
the testsuite changes (-testsuite), with separate changelogs. There
are several places in the front end where it is assumed that function
types cannot have qualifiers. This is wrong: function types can have
qualifiers, but there are only a few ways in which these qualifiers
can be added:

  - cv-qualifier function types can be created with a typedef of a
    function, e.g.,

      typedef int foo(float) const;

  - cv-qualified function types can come from unifying a member
    pointer to a pointer to cv-qualified member function, e.g.,

      template<typename> struct X;
      template<typename T, typename Class> struct X<T Class::*> {};

      struct Y {};

      X<int (Y::*)(float, double) const>; // T = int(float, double) const

However, one cannot add qualifiers to a function type. For instance,
the second line of the following code does not add qualifiers to
"foo": 

  typedef int foo(float) const;
  typedef volatile foo foo_v; // #2

In C++98, the line marked #2 is an error. However, DR 295 makes this
code legal but drops the qualifiers, so "foo_v" will be the same type
as "foo". The patch therefore warns only when -pedantic is provided.

This is a largish patch with several parts, because there are several
intertwined changes:

  1) Remove all of the incorrect errors/warnings about qualifiers.
  2) Add errors/warnings where qualified function types cannot be
     used or where they will be dropped.
  3) Transfer qualifiers between the function type of a member pointer
     and the implicit object type of a member function pointer. 
  4) Unify member pointers to member function pointers.
  5) Print out qualifiers on function types (they are already mangled
     properly).

   Doug Gregor
   dgregor@cs.indiana.edu

Attachment: ChangeLog-cp
Description: Text document

Attachment: ChangeLog-testsuite
Description: Text document

Index: cp-tree.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.1097
diff -c -3 -p -b -r1.1097 cp-tree.h
*** cp-tree.h	20 Jan 2005 07:12:49 -0000	1.1097
--- cp-tree.h	22 Jan 2005 21:02:28 -0000
*************** extern tree build_ptrmemfunc			(tree, tr
*** 4306,4311 ****
--- 4306,4312 ----
  extern int cp_type_quals                        (tree);
  extern bool cp_has_mutable_p                     (tree);
  extern bool at_least_as_qualified_p              (tree, tree);
+ extern void cp_apply_type_quals_to_decl         (int, tree);
  extern tree build_ptrmemfunc1                   (tree, tree, tree);
  extern void expand_ptrmemfunc_cst               (tree, tree *, tree *);
  extern tree pfn_from_ptrmemfunc                 (tree);
Index: decl.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.1354
diff -c -3 -p -b -r1.1354 decl.c
*** decl.c	18 Jan 2005 23:49:35 -0000	1.1354
--- decl.c	22 Jan 2005 21:02:31 -0000
*************** grokdeclarator (const cp_declarator *dec
*** 6900,6905 ****
--- 6900,6919 ----
      error ("qualifiers are not allowed on declaration of %<operator %T%>",
             ctor_return_type);
  
+   if (TREE_CODE (type) == FUNCTION_TYPE 
+       && type_quals != TYPE_UNQUALIFIED)
+     {
+       /* This was an error in C++98 (cv-qualifiers cannot be added to
+          a function type), but DR 295 makes the code well-formed by
+          dropping the extra qualifiers. */
+       if (pedantic)
+         {
+           tree bad_type = build_qualified_type (type, type_quals);
+           pedwarn ("ignoring %qV qualifiers added to function type %qT",
+                    bad_type, type);
+         }
+       type_quals = TYPE_UNQUALIFIED;
+     }
    type_quals |= cp_type_quals (type);
    type = cp_build_qualified_type_real
      (type, type_quals, ((typedef_decl && !DECL_ARTIFICIAL (typedef_decl)
*************** grokdeclarator (const cp_declarator *dec
*** 7261,7266 ****
--- 7275,7281 ----
  	      }
  
              type = build_function_type (type, arg_types);
+             type = cp_build_qualified_type (type, quals);
  	  }
  	  break;
  
*************** grokdeclarator (const cp_declarator *dec
*** 7293,7298 ****
--- 7308,7319 ----
  	      && (TREE_CODE (type) == FUNCTION_TYPE
  		  || (quals && TREE_CODE (type) == METHOD_TYPE)))
  	    {
+               /* If the type is a FUNCTION_TYPE, pick up the
+                  qualifiers from that function type. No other
+                  qualifiers may be supplied. */
+               if (TREE_CODE (type) == FUNCTION_TYPE)
+                 quals = cp_type_quals (type);
+ 
  	      tree dummy = build_decl (TYPE_DECL, NULL_TREE, type);
  	      grok_method_quals (declarator->u.pointer.class_type,
  				 dummy, quals);
*************** grokdeclarator (const cp_declarator *dec
*** 7587,7597 ****
  	{
  	  if (ctype == NULL_TREE)
  	    {
! 	      if (TREE_CODE (type) != METHOD_TYPE)
! 		error ("%Jinvalid type qualifier for non-member function type",
! 		       decl);
! 	      else
  		ctype = TYPE_METHOD_BASETYPE (type);
  	    }
  	  if (ctype != NULL_TREE)
  	    grok_method_quals (ctype, decl, quals);
--- 7608,7619 ----
  	{
  	  if (ctype == NULL_TREE)
  	    {
!               if (TREE_CODE (type) == METHOD_TYPE)
                  ctype = TYPE_METHOD_BASETYPE (type);
+               /* Any qualifiers on a function type typedef have
+                  already been dealt with. */
+               else if (TREE_CODE (type) == FUNCTION_TYPE)
+                 quals = TYPE_UNQUALIFIED;
  	    }
  	  if (ctype != NULL_TREE)
  	    grok_method_quals (ctype, decl, quals);
*************** grokdeclarator (const cp_declarator *dec
*** 7634,7639 ****
--- 7656,7678 ----
  	}
  
        parms = nreverse (decls);
+ 
+       if (decl_context != TYPENAME)
+         {
+           /* A cv-qualifier-seq shall only be part of the function type
+              for a non-static member function. [8.3.5/4 dcl.fct] */ 
+           if (cp_type_quals (type) != TYPE_UNQUALIFIED
+               && (current_class_type == NULL_TREE || staticp) )
+             {
+               error ("qualified function types cannot be used to declare %s functions",
+                      (staticp? "static member" : "free"));
+               type = TYPE_MAIN_VARIANT (type);
+             }
+           
+           /* The qualifiers on the function type become the qualifiers on
+              the non-static member function. */
+           quals |= cp_type_quals (type);
+         }
      }
  
    /* If this is a type name (such as, in a cast or sizeof),
*************** grokdeclarator (const cp_declarator *dec
*** 8166,8172 ****
         when processing a template; we'll do this for the instantiated
         declaration based on the type of DECL.  */
      if (!processing_template_decl)
!       c_apply_type_quals_to_decl (type_quals, decl);
  
      return decl;
    }
--- 8205,8211 ----
         when processing a template; we'll do this for the instantiated
         declaration based on the type of DECL.  */
      if (!processing_template_decl)
!       cp_apply_type_quals_to_decl (type_quals, decl);
  
      return decl;
    }
*************** start_preparsed_function (tree decl1, tr
*** 9945,9951 ****
        DECL_IGNORED_P (resdecl) = 1;
        DECL_RESULT (decl1) = resdecl;
  
!       c_apply_type_quals_to_decl (cp_type_quals (restype), resdecl);
      }
  
    /* Initialize RTL machinery.  We cannot do this until
--- 9984,9990 ----
        DECL_IGNORED_P (resdecl) = 1;
        DECL_RESULT (decl1) = resdecl;
  
!       cp_apply_type_quals_to_decl (cp_type_quals (restype), resdecl);
      }
  
    /* Initialize RTL machinery.  We cannot do this until
Index: decl2.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cp/decl2.c,v
retrieving revision 1.764
diff -c -3 -p -b -r1.764 decl2.c
*** decl2.c	5 Jan 2005 10:02:11 -0000	1.764
--- decl2.c	22 Jan 2005 21:02:32 -0000
*************** grokclassfn (tree ctype, tree function, 
*** 300,306 ****
        this_quals |= TYPE_QUAL_CONST;
        qual_type = cp_build_qualified_type (type, this_quals);
        parm = build_artificial_parm (this_identifier, qual_type);
!       c_apply_type_quals_to_decl (this_quals, parm);
        TREE_CHAIN (parm) = DECL_ARGUMENTS (function);
        DECL_ARGUMENTS (function) = parm;
      }
--- 300,306 ----
        this_quals |= TYPE_QUAL_CONST;
        qual_type = cp_build_qualified_type (type, this_quals);
        parm = build_artificial_parm (this_identifier, qual_type);
!       cp_apply_type_quals_to_decl (this_quals, parm);
        TREE_CHAIN (parm) = DECL_ARGUMENTS (function);
        DECL_ARGUMENTS (function) = parm;
      }
Index: error.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cp/error.c,v
retrieving revision 1.275
diff -c -3 -p -b -r1.275 error.c
*** error.c	21 Dec 2004 17:54:23 -0000	1.275
--- error.c	22 Jan 2005 21:02:32 -0000
*************** dump_type_suffix (tree t, int flags)
*** 613,618 ****
--- 613,620 ----
  	if (TREE_CODE (t) == METHOD_TYPE)
            pp_cxx_cv_qualifier_seq
              (cxx_pp, TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))));
+         else
+           pp_cxx_cv_qualifier_seq(cxx_pp, t);
  	dump_exception_spec (TYPE_RAISES_EXCEPTIONS (t), flags);
  	dump_type_suffix (TREE_TYPE (t), flags);
  	break;
Index: pt.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.968
diff -c -3 -p -b -r1.968 pt.c
*** pt.c	21 Jan 2005 02:27:09 -0000	1.968
--- pt.c	22 Jan 2005 21:02:34 -0000
*************** tsubst_decl (tree t, tree args, tsubst_f
*** 6510,6516 ****
  
  	type = tsubst (TREE_TYPE (t), args, complain, in_decl);
  	TREE_TYPE (r) = type;
! 	c_apply_type_quals_to_decl (cp_type_quals (type), r);
  
  	if (DECL_INITIAL (r))
  	  {
--- 6510,6516 ----
  
  	type = tsubst (TREE_TYPE (t), args, complain, in_decl);
  	TREE_TYPE (r) = type;
! 	cp_apply_type_quals_to_decl (cp_type_quals (type), r);
  
  	if (DECL_INITIAL (r))
  	  {
*************** tsubst_decl (tree t, tree args, tsubst_f
*** 6540,6546 ****
  	if (type == error_mark_node)
  	  return error_mark_node;
  	TREE_TYPE (r) = type;
! 	c_apply_type_quals_to_decl (cp_type_quals (type), r);
  
  	/* We don't have to set DECL_CONTEXT here; it is set by
  	   finish_member_declaration.  */
--- 6540,6546 ----
  	if (type == error_mark_node)
  	  return error_mark_node;
  	TREE_TYPE (r) = type;
! 	cp_apply_type_quals_to_decl (cp_type_quals (type), r);
  
  	/* We don't have to set DECL_CONTEXT here; it is set by
  	   finish_member_declaration.  */
*************** tsubst_decl (tree t, tree args, tsubst_f
*** 6640,6646 ****
  	else if (DECL_SELF_REFERENCE_P (t))
  	  SET_DECL_SELF_REFERENCE_P (r);
  	TREE_TYPE (r) = type;
! 	c_apply_type_quals_to_decl (cp_type_quals (type), r);
  	DECL_CONTEXT (r) = ctx;
  	/* Clear out the mangled name and RTL for the instantiation.  */
  	SET_DECL_ASSEMBLER_NAME (r, NULL_TREE);
--- 6640,6646 ----
  	else if (DECL_SELF_REFERENCE_P (t))
  	  SET_DECL_SELF_REFERENCE_P (r);
  	TREE_TYPE (r) = type;
! 	cp_apply_type_quals_to_decl (cp_type_quals (type), r);
  	DECL_CONTEXT (r) = ctx;
  	/* Clear out the mangled name and RTL for the instantiation.  */
  	SET_DECL_ASSEMBLER_NAME (r, NULL_TREE);
*************** tsubst (tree t, tree args, tsubst_flags_
*** 7259,7280 ****
  	gcc_assert (TREE_CODE (type) != METHOD_TYPE);
  	if (TREE_CODE (type) == FUNCTION_TYPE)
  	  {
! 	    /* This is really a method type. The cv qualifiers of the
! 	       this pointer should _not_ be determined by the cv
! 	       qualifiers of the class type.  They should be held
! 	       somewhere in the FUNCTION_TYPE, but we don't do that at
! 	       the moment.  Consider
! 		  typedef void (Func) () const;
! 
! 		  template <typename T1> void Foo (Func T1::*);
! 
! 		*/
  	    tree method_type;
! 
! 	    method_type = build_method_type_directly (TYPE_MAIN_VARIANT (r),
  						      TREE_TYPE (type),
  						      TYPE_ARG_TYPES (type));
! 	    return build_ptrmemfunc_type (build_pointer_type (method_type));
  	  }
  	else
  	  return cp_build_qualified_type_real (build_ptrmem_type (r, type),
--- 7259,7276 ----
  	gcc_assert (TREE_CODE (type) != METHOD_TYPE);
  	if (TREE_CODE (type) == FUNCTION_TYPE)
            {
!             /* The type of the implicit object parameter gets its
!                cv-qualifiers from the FUNCTION_TYPE. */
              tree method_type;
!             tree this_type = cp_build_qualified_type (TYPE_MAIN_VARIANT (r),
!                                                       cp_type_quals (type));
!             tree memptr;
!             method_type = build_method_type_directly (this_type,
                                                        TREE_TYPE (type),
                                                        TYPE_ARG_TYPES (type));
!             memptr = build_ptrmemfunc_type (build_pointer_type (method_type));
!             return cp_build_qualified_type_real (memptr, cp_type_quals (t),
!                                                  complain);
  	  }
  	else
  	  return cp_build_qualified_type_real (build_ptrmem_type (r, type),
*************** unify (tree tparms, tree targs, tree par
*** 10287,10292 ****
--- 10283,10319 ----
  				    DEDUCE_EXACT, 0, -1);
  
      case OFFSET_TYPE:
+       /* Unify a pointer to member with a pointer to member function, which
+          deduces the type of the member as a function type. */
+       if (TYPE_PTRMEMFUNC_P (arg))
+         {
+           tree method_type;
+           tree fntype;
+           cp_cv_quals cv_quals;
+ 
+           /* Check top-level cv qualifiers */
+           if (!check_cv_quals_for_unify (UNIFY_ALLOW_NONE, arg, parm))
+             return 1;
+ 
+           if (unify (tparms, targs, TYPE_OFFSET_BASETYPE (parm),
+                      TYPE_PTRMEMFUNC_OBJECT_TYPE (arg), UNIFY_ALLOW_NONE))
+             return 1;
+ 
+           /* Determine the type of the function we are unifying against. */
+           method_type = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (arg));
+           fntype = 
+             build_function_type (TREE_TYPE (method_type),
+                                  TREE_CHAIN (TYPE_ARG_TYPES (method_type)));
+ 
+           /* Extract the cv-qualifiers of the member function from the
+              implicit object parameter and place them on the function
+              type to be restored later. */
+           cv_quals = 
+             cp_type_quals(TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (method_type))));
+           fntype = build_qualified_type (fntype, cv_quals);
+           return unify (tparms, targs, TREE_TYPE (parm), fntype, strict);
+         }
+ 
        if (TREE_CODE (arg) != OFFSET_TYPE)
  	return 1;
        if (unify (tparms, targs, TYPE_OFFSET_BASETYPE (parm),
Index: tree.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cp/tree.c,v
retrieving revision 1.425
diff -c -3 -p -b -r1.425 tree.c
*** tree.c	18 Jan 2005 23:51:26 -0000	1.425
--- tree.c	22 Jan 2005 21:02:35 -0000
*************** cp_build_qualified_type_real (tree type,
*** 486,496 ****
        return build_ptrmemfunc_type (t);
      }
  
!   /* A reference, function or method type shall not be cv qualified.
       [dcl.ref], [dct.fct]  */
    if (type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE)
        && (TREE_CODE (type) == REFERENCE_TYPE
- 	  || TREE_CODE (type) == FUNCTION_TYPE
  	  || TREE_CODE (type) == METHOD_TYPE))
      {
        bad_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
--- 486,495 ----
        return build_ptrmemfunc_type (t);
      }
  
!   /* A reference or method type shall not be cv qualified.
       [dcl.ref], [dct.fct]  */
    if (type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE)
        && (TREE_CODE (type) == REFERENCE_TYPE
  	  || TREE_CODE (type) == METHOD_TYPE))
      {
        bad_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
*************** cp_build_qualified_type_real (tree type,
*** 498,507 ****
      }
  
    /* A restrict-qualified type must be a pointer (or reference)
!      to object or incomplete type.  */
    if ((type_quals & TYPE_QUAL_RESTRICT)
        && TREE_CODE (type) != TEMPLATE_TYPE_PARM
        && TREE_CODE (type) != TYPENAME_TYPE
        && !POINTER_TYPE_P (type))
      {
        bad_quals |= TYPE_QUAL_RESTRICT;
--- 497,507 ----
      }
  
    /* A restrict-qualified type must be a pointer (or reference)
!      to object or incomplete type, or a function type. */
    if ((type_quals & TYPE_QUAL_RESTRICT)
        && TREE_CODE (type) != TEMPLATE_TYPE_PARM
        && TREE_CODE (type) != TYPENAME_TYPE
+       && TREE_CODE (type) != FUNCTION_TYPE
        && !POINTER_TYPE_P (type))
      {
        bad_quals |= TYPE_QUAL_RESTRICT;
Index: typeck.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cp/typeck.c,v
retrieving revision 1.608
diff -c -3 -p -b -r1.608 typeck.c
*** typeck.c	20 Jan 2005 07:12:50 -0000	1.608
--- typeck.c	22 Jan 2005 21:02:36 -0000
*************** cp_has_mutable_p (tree type)
*** 6440,6445 ****
--- 6440,6474 ----
    return CLASS_TYPE_P (type) && CLASSTYPE_HAS_MUTABLE (type);
  }
  
+ /* Apply the TYPE_QUALS to the new DECL.  */
+ void
+ cp_apply_type_quals_to_decl (int type_quals, tree decl)
+ {
+   tree type = TREE_TYPE (decl);
+ 
+   if (type == error_mark_node)
+     return;
+ 
+   if (TREE_CODE (type) == FUNCTION_TYPE 
+       && type_quals != TYPE_UNQUALIFIED)
+     {
+       /* This was an error in C++98 (cv-qualifiers cannot be added to
+          a function type), but DR 295 makes the code well-formed by
+          dropping the extra qualifiers. */
+       if (pedantic)
+         {
+           tree bad_type = build_qualified_type (type, type_quals);
+           pedwarn ("ignoring %qV qualifiers added to function type %qT",
+                    bad_type, type);
+         }
+ 
+       TREE_TYPE (decl) = TYPE_MAIN_VARIANT (type);
+       return;
+     }
+ 
+   c_apply_type_quals_to_decl (type_quals, decl);
+ }
+ 
  /* Subroutine of casts_away_constness.  Make T1 and T2 point at
     exemplar types such that casting T1 to T2 is casting away constness
     if and only if there is no implicit conversion from T1 to T2.  */
Index: g++.dg/other/cv_func.C
===================================================================
RCS file: g++.dg/other/cv_func.C
diff -N g++.dg/other/cv_func.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- g++.dg/other/cv_func.C	22 Jan 2005 17:10:30 -0000
***************
*** 0 ****
--- 1,32 ----
+ // { dg-do compile }
+ // { dg-options "-pedantic -pedantic-errors" }
+ typedef int FIC(int) const;
+ typedef int FI(int);
+ 
+ FIC f; // { dg-error "qualified" }
+ // { dg-error "ignoring" "" { target *-*-* } 6 }
+ struct S {
+   FIC f; // OK
+ 
+   const FI g; // { dg-error "qualifier" }
+ 
+   int h(int) const;
+ 
+ };
+ FIC S::*pm = &S::f;
+ const FI S::*pm2 = &S::f; // { dg-error "qualifier" }
+ // { dg-error "cannot convert" "" { target *-*-* } 17 }
+ const FIC S::*pm3 = &S::f; // { dg-error "qualifier" }
+ 
+ int S::f(int) const
+ {
+   return 17;
+ }
+ 
+ 
+ int foo(float) const // { dg-error "qualifier" }
+ {
+   return 0;
+ }
+ 
+ int bar(float) volatile; // { dg-error "qualifier" }
Index: g++.dg/template/mem_func_ptr.C
===================================================================
RCS file: g++.dg/template/mem_func_ptr.C
diff -N g++.dg/template/mem_func_ptr.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- g++.dg/template/mem_func_ptr.C	22 Jan 2005 17:10:30 -0000
***************
*** 0 ****
--- 1,57 ----
+ // { dg-do compile }
+ template<typename T> struct takes_member_ptr;
+ template<typename T, typename Class> struct takes_member_ptr<T Class::*> {};
+ 
+ template<typename T, typename Class>
+ void fun_takes_member_ptr(T Class::*) {}
+ 
+ 
+ template<typename T> struct order_member_ptrs;
+ template<typename T, typename Class> struct order_member_ptrs<T Class::*> {};
+ template<typename R, typename T1, typename Class> 
+   struct order_member_ptrs<R (Class::*)(T1)>
+   {
+     typedef int type;
+   };
+ 
+ template<typename R, typename T1, typename Class>
+   struct order_member_ptrs<R (Class::*)(T1) const>
+   {
+     typedef int c_type;
+   };
+ 
+ template<typename R, typename T1, typename Class>
+   struct order_member_ptrs<R (Class::*)(T1) volatile>
+   {
+     typedef int v_type;
+   };
+ 
+ template<typename R, typename T1, typename Class>
+   struct order_member_ptrs<R (Class::*)(T1) const volatile>
+   {
+     typedef int cv_type;
+   };
+ 
+ 	  
+ struct X {
+   void bar(float) {}
+   void bar_c(float) const {}
+   void bar_v(float) volatile {}
+   void bar_cv(float) const volatile {}
+ };
+ 
+ void foo()
+ {
+   sizeof(takes_member_ptr<void (X::*)(float)>);
+   sizeof(takes_member_ptr<void (X::*)(float) const>);
+   sizeof(takes_member_ptr<void (X::*)(float) volatile>);
+   sizeof(takes_member_ptr<void (X::*)(float) const volatile>);
+   sizeof(order_member_ptrs<void (X::*)(float)>::type);
+   sizeof(order_member_ptrs<void (X::*)(float) const>::c_type);
+   sizeof(order_member_ptrs<void (X::*)(float) volatile>::v_type);
+   sizeof(order_member_ptrs<void (X::*)(float) const volatile>::cv_type);
+   fun_takes_member_ptr(&X::bar);
+   fun_takes_member_ptr(&X::bar_c);
+   fun_takes_member_ptr(&X::bar_v);
+   fun_takes_member_ptr(&X::bar_cv);
+ }
Index: g++.dg/template/qualttp20.C
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/testsuite/g++.dg/template/qualttp20.C,v
retrieving revision 1.7
diff -c -3 -p -b -r1.7 qualttp20.C
*** g++.dg/template/qualttp20.C	10 Oct 2004 21:36:41 -0000	1.7
--- g++.dg/template/qualttp20.C	22 Jan 2005 17:10:30 -0000
***************
*** 1,4 ****
--- 1,5 ----
  // { dg-do compile }
+ // { dg-options "-pedantic -pedantic-errors" }
  
  // Copyright (C) 2001 Free Software Foundation, Inc.
  // Contributed by Nathan Sidwell 15 Dec 2001 <nathan@codesourcery.com>
*************** struct AS
*** 16,22 ****
  template <typename T> struct B1 : T
  {
    typedef typename T::L __restrict__ r;// { dg-error "'__restrict__' qualifiers cannot" "" }
!   typedef typename T::myT __restrict__ p;// { dg-warning "ignoring '__restrict__'" "" { xfail *-*-* } }
  
    // The following are DR 295 dependent
    typedef typename T::myT volatile *myvolatile;
--- 17,23 ----
  template <typename T> struct B1 : T
  {
    typedef typename T::L __restrict__ r;// { dg-error "'__restrict__' qualifiers cannot" "" }
!   typedef typename T::myT __restrict__ p;// { dg-error "ignoring '__restrict__'" }
  
    // The following are DR 295 dependent
    typedef typename T::myT volatile *myvolatile;
Index: g++.old-deja/g++.pt/ptrmem5.C
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/testsuite/g++.old-deja/g++.pt/ptrmem5.C,v
retrieving revision 1.3
diff -c -3 -p -b -r1.3 ptrmem5.C
*** g++.old-deja/g++.pt/ptrmem5.C	1 May 2003 02:02:55 -0000	1.3
--- g++.old-deja/g++.pt/ptrmem5.C	22 Jan 2005 17:10:31 -0000
*************** struct Null {
*** 14,17 ****
  int *pd = NULL;
  int (*pf)() = NULL;
  int Null::*pmd = NULL;
! int (Null::*pmf)() = NULL; // { dg-bogus "" "" { xfail *-*-* } }  - cannot convert - 
--- 14,17 ----
  int *pd = NULL;
  int (*pf)() = NULL;
  int Null::*pmd = NULL;
! int (Null::*pmf)() = NULL; 

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