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 for c++/37540


The problem here was that we weren't preserving the type of a non-dependent call in a template well enough; we need to remember the type of the called function as well, and it needs to be a pointer. Fixed thus. I also wrap the call in an implicit dereference as appropriate rather than just giving the stub CALL_EXPR the dereferenced type; I'm not sure this will make a difference, but it might affect something that wants to know if the call is an lvalue or not.

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


2008-11-20  Jason Merrill  <jason@redhat.com>

	PR c++/37540
cp/
	* call.c (build_over_call): Take the address of the function even
	in a template.
	(build_new_method_call): Remember the type of the called function
	in a template.
testsuite/
	* g++.dg/cpp0x/decltype14.C: New test.

Index: cp/call.c
===================================================================
*** cp/call.c	(revision 142052)
--- cp/call.c	(working copy)
*************** build_over_call (struct z_candidate *can
*** 5103,5109 ****
        tree expr;
        tree return_type;
        return_type = TREE_TYPE (TREE_TYPE (fn));
!       expr = build_call_list (return_type, fn, args);
        if (TREE_THIS_VOLATILE (fn) && cfun)
  	current_function_returns_abnormally = 1;
        if (!VOID_TYPE_P (return_type))
--- 5103,5109 ----
        tree expr;
        tree return_type;
        return_type = TREE_TYPE (TREE_TYPE (fn));
!       expr = build_call_list (return_type, build_addr_func (fn), args);
        if (TREE_THIS_VOLATILE (fn) && cfun)
  	current_function_returns_abnormally = 1;
        if (!VOID_TYPE_P (return_type))
*************** build_new_method_call (tree instance, tr
*** 5964,5973 ****
      }
  
    if (processing_template_decl && call != error_mark_node)
!     call = (build_min_non_dep_call_list
! 	    (call,
! 	     build_min_nt (COMPONENT_REF, orig_instance, orig_fns, NULL_TREE),
! 	     orig_args));
  
   /* Free all the conversions we allocated.  */
    obstack_free (&conversion_obstack, p);
--- 5964,5979 ----
      }
  
    if (processing_template_decl && call != error_mark_node)
!     {
!       if (TREE_CODE (call) == INDIRECT_REF)
! 	call = TREE_OPERAND (call, 0);
!       call = (build_min_non_dep_call_list
! 	      (call,
! 	       build_min (COMPONENT_REF, TREE_TYPE (CALL_EXPR_FN (call)),
! 			  orig_instance, orig_fns, NULL_TREE),
! 	       orig_args));
!       call = convert_from_reference (call);
!     }
  
   /* Free all the conversions we allocated.  */
    obstack_free (&conversion_obstack, p);
Index: testsuite/g++.dg/cpp0x/decltype14.C
===================================================================
*** testsuite/g++.dg/cpp0x/decltype14.C	(revision 0)
--- testsuite/g++.dg/cpp0x/decltype14.C	(revision 0)
***************
*** 0 ****
--- 1,17 ----
+ // PR c++/37540
+ 
+ struct A
+ {
+   int g() {return 0;}
+ };
+ 
+ template <typename T_> 
+ void f(A a)
+ {
+   __decltype(a.g()) i;
+ }
+ 
+ int main()
+ {
+   f<int>(A());
+ }

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