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 to tsubst for c++/28385


When Doug Gregor allowed cv-qualifiers on FUNCTION_TYPEs in order to support

typedef void fntype() const;

we started applying them incorrectly from template substitution as well. Fixed thus.

Tested x86_64-pc-linux-gnu, applied to trunk.

2006-08-16  Jason Merrill  <jason@redhat.com>

	PR c++/28385
	* pt.c (tsubst) [TEMPLATE_TYPE_PARM]: Ignore quals from template
	if arg is a function.

Index: pt.c
===================================================================
*** pt.c	(revision 116184)
--- pt.c	(working copy)
*************** tsubst (tree t, tree args, tsubst_flags_
*** 7238,7247 ****
  	  {
  	    if (TREE_CODE (t) == TEMPLATE_TYPE_PARM)
  	      {
  		gcc_assert (TYPE_P (arg));
  		return cp_build_qualified_type_real
! 		  (arg, cp_type_quals (arg) | cp_type_quals (t),
! 		   complain | tf_ignore_bad_quals);
  	      }
  	    else if (TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM)
  	      {
--- 7238,7257 ----
  	  {
  	    if (TREE_CODE (t) == TEMPLATE_TYPE_PARM)
  	      {
+ 		int quals;
  		gcc_assert (TYPE_P (arg));
+ 
+ 		/* cv-quals from the template are discarded when
+ 		   substituting in a function or reference type.  */
+ 		if (TREE_CODE (arg) == FUNCTION_TYPE
+ 		    || TREE_CODE (arg) == METHOD_TYPE
+ 		    || TREE_CODE (arg) == REFERENCE_TYPE)
+ 		  quals = cp_type_quals (arg);
+ 		else
+ 		  quals = cp_type_quals (arg) | cp_type_quals (t);
+ 		  
  		return cp_build_qualified_type_real
! 		  (arg, quals, complain | tf_ignore_bad_quals);
  	      }
  	    else if (TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM)
  	      {
Index: /home/jason/ged/template/const1.C
===================================================================
*** /home/jason/ged/template/const1.C	(revision 0)
--- /home/jason/ged/template/const1.C	(revision 0)
***************
*** 0 ****
--- 1,30 ----
+ // PR c++/28385
+ // instantiating op() with void()() was making the compiler think that 'fcn'
+ // was const, so it could eliminate the call.
+ 
+ // { dg-do run }
+ 
+ extern "C" void abort (void);
+ 
+ int barcnt = 0;
+ 
+ class Foo {
+   public:
+     template<typename T>
+     void operator()(const T& fcn) {
+       fcn();
+     }
+ };
+ 
+ void bar() {
+   barcnt++;
+ }
+ 
+ int main() {
+   Foo myFoo;
+   myFoo(bar);
+   myFoo(&bar);
+   if (barcnt != 2)
+     abort ();
+   return 0;
+ }

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