This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH for c++/37540
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Date: Thu, 20 Nov 2008 13:40:38 -0500
- Subject: 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());
+ }