Re: C++ member function template id not matching linkage name (PR debug/49408)
diff mbox

Message ID 20110629200004.GA10065@host1.jankratochvil.net
State New
Headers show

Commit Message

Jan Kratochvil June 29, 2011, 8 p.m. UTC
On Mon, 27 Jun 2011 20:00:24 +0200, Jason Merrill wrote:
> They should be supressed whenever the function appears in an
> expression context, either as a pointer to member function (i.e. the
> operand of '&')

Done, therefore it is no longer restricted only to templates as before.


> or as the function being called in a call expression.

I implemented it in the patch below but I do not agree + understand it.

The call expression is in libiberty/testsuite/demangle-expected modified by
this patch as:

 # decltype/fn call test
 --format=gnu-v3
 _Z4add3IidEDTclL_Z1gEfp_fp0_EET_T0_
-decltype (g({parm#1}, {parm#2})) add3<int, double>(int, double)
+decltype (g) add3<int, double>(int, double)

I agree it is sufficient to determine the return type just from the function
type as return type cannot be overloaded by the function parameters.  But it
no longer matches a valid C++ source code now:

char g (int x, double y) { return 0; }
template <typename T, typename U>
decltype (g((T) 0, (U) 0)) add3 (T x, U y) { return 'z'; }
// error: ‘add3’ declared as function returning a function
// decltype (g) add3 (T x, U y) { return 'z'; }
int main () { add3<int, double> (1, 2.0); }

g++ -Wall -g -std=c++0x
g++ (GCC) 4.7.0 20110629 (experimental)


(Regression testing underway.)


Thanks,
Jan


libiberty/
2011-06-29  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* cp-demangle.c (d_print_comp): Suppress argument list for function
	references by the '&' unary operator.  Keep also already processed
	variant without the argument list.  Suppress argument list also for
	function call used in an expression.
	* testsuite/demangle-expected: Remove parameters from function call
	expressions of 6 testcases.  Create 3 new testcases for function
	references by the '&' unary operator..

Comments

Jason Merrill June 29, 2011, 8:56 p.m. UTC | #1
On 06/29/2011 04:00 PM, Jan Kratochvil wrote:
> On Mon, 27 Jun 2011 20:00:24 +0200, Jason Merrill wrote:
>> They should be supressed whenever the function appears in an
>> expression context, either as a pointer to member function (i.e. the
>> operand of '&')
> 
> Done, therefore it is no longer restricted only to templates as before.
> 
>> or as the function being called in a call expression.
> 
> I implemented it in the patch below but I do not agree + understand it.
> 
> The call expression is in libiberty/testsuite/demangle-expected modified by
> this patch as:
> 
>   # decltype/fn call test
>   --format=gnu-v3
>   _Z4add3IidEDTclL_Z1gEfp_fp0_EET_T0_
> -decltype (g({parm#1}, {parm#2})) add3<int, double>(int, double)
> +decltype (g) add3<int, double>(int, double)

Here you're suppressing the arguments to a call, which we want to keep;
we only want to suppress printing the parameter types (which are not
part of the source expression).

Jason
Jan Kratochvil June 29, 2011, 9:07 p.m. UTC | #2
On Wed, 29 Jun 2011 22:56:26 +0200, Jason Merrill wrote:
> On 06/29/2011 04:00 PM, Jan Kratochvil wrote:
> > On Mon, 27 Jun 2011 20:00:24 +0200, Jason Merrill wrote:
> >   # decltype/fn call test
> >   --format=gnu-v3
> >   _Z4add3IidEDTclL_Z1gEfp_fp0_EET_T0_
> > -decltype (g({parm#1}, {parm#2})) add3<int, double>(int, double)
> > +decltype (g) add3<int, double>(int, double)
> 
> Here you're suppressing the arguments to a call, which we want to keep;
> we only want to suppress printing the parameter types (which are not
> part of the source expression).

Sorry but what is therefore the expect output in this case?


Thanks,
Jan
Jason Merrill June 29, 2011, 10:27 p.m. UTC | #3
On 06/29/2011 05:07 PM, Jan Kratochvil wrote:
> On Wed, 29 Jun 2011 22:56:26 +0200, Jason Merrill wrote:
>> On 06/29/2011 04:00 PM, Jan Kratochvil wrote:
>>> On Mon, 27 Jun 2011 20:00:24 +0200, Jason Merrill wrote:
>>>    # decltype/fn call test
>>>    --format=gnu-v3
>>>    _Z4add3IidEDTclL_Z1gEfp_fp0_EET_T0_
>>> -decltype (g({parm#1}, {parm#2})) add3<int, double>(int, double)
>>> +decltype (g) add3<int, double>(int, double)
>>
>> Here you're suppressing the arguments to a call, which we want to keep;
>> we only want to suppress printing the parameter types (which are not
>> part of the source expression).
>
> Sorry but what is therefore the expect output in this case?

The earlier output was correct.  We just don't want to print "g(int, 
double)".

Jason

Patch
diff mbox

--- a/libiberty/cp-demangle.c
+++ b/libiberty/cp-demangle.c
@@ -4139,7 +4169,46 @@  d_print_comp (struct d_print_info *dpi, int options,
       return;
 
     case DEMANGLE_COMPONENT_UNARY:
-      if (d_left (dc)->type != DEMANGLE_COMPONENT_CAST)
+      if (d_left (dc)->type == DEMANGLE_COMPONENT_OPERATOR
+	  && d_left (dc)->u.s_operator.op->len == 1
+	  && d_left (dc)->u.s_operator.op->name[0] == '&'
+	  && d_right (dc)->type == DEMANGLE_COMPONENT_TYPED_NAME
+	  && d_left (d_right (dc))->type == DEMANGLE_COMPONENT_QUAL_NAME
+	  && d_right (d_right (dc))->type == DEMANGLE_COMPONENT_FUNCTION_TYPE)
+	{
+	  /* Address of a function (therefore in an expression context) must
+	     have its argument list suppressed.
+
+	     unary operator ... dc
+	       operator & ... d_left (dc)
+	       typed name ... d_right (dc)
+		 qualified name ... d_left (d_right (dc))
+		   <names>
+		 function type ... d_right (d_right (dc))
+		   argument list
+		     <arguments>  */
+
+	  d_print_expr_op (dpi, options, d_left (dc));
+	  d_print_comp (dpi, options, d_left (d_right (dc)));
+	  return;
+	}
+      else if (d_left (dc)->type == DEMANGLE_COMPONENT_OPERATOR
+	       && d_left (dc)->u.s_operator.op->len == 1
+	       && d_left (dc)->u.s_operator.op->name[0] == '&'
+	       && d_right (dc)->type == DEMANGLE_COMPONENT_QUAL_NAME)
+	{
+	  /* Keep also already processed variant without the argument list.
+
+	     unary operator ... dc
+	       operator & ... d_left (dc)
+	       qualified name ... d_right (dc)
+		 <names>  */
+
+	  d_print_expr_op (dpi, options, d_left (dc));
+	  d_print_comp (dpi, options, d_right (dc));
+	  return;
+	}
+      else if (d_left (dc)->type != DEMANGLE_COMPONENT_CAST)
 	d_print_expr_op (dpi, options, d_left (dc));
       else
 	{
@@ -4172,10 +4241,11 @@  d_print_comp (struct d_print_info *dpi, int options,
 	  d_print_comp (dpi, options, d_right (d_right (dc)));
 	  d_append_char (dpi, ']');
 	}
-      else
+      /* Function call used in an expression should not have the argument list
+	 printed.  */
+      else if (strcmp (d_left (dc)->u.s_operator.op->code, "cl") != 0)
 	{
-	  if (strcmp (d_left (dc)->u.s_operator.op->code, "cl") != 0)
-	    d_print_expr_op (dpi, options, d_left (dc));
+	  d_print_expr_op (dpi, options, d_left (dc));
 	  d_print_subexpr (dpi, options, d_right (d_right (dc)));
 	}
 
diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected
index bbd418c..da87282 100644
--- a/libiberty/testsuite/demangle-expected
+++ b/libiberty/testsuite/demangle-expected
@@ -3904,7 +3904,7 @@  decltype ({parm#1}+{parm#2}) add<int, double>(int, double)
 # decltype/fn call test
 --format=gnu-v3
 _Z4add3IidEDTclL_Z1gEfp_fp0_EET_T0_
-decltype (g({parm#1}, {parm#2})) add3<int, double>(int, double)
+decltype (g) add3<int, double>(int, double)
 # new (2008) built in types test
 --format=gnu-v3
 _Z1fDfDdDeDhDsDi
@@ -3916,15 +3916,15 @@  void f<int*, float*, double*>(int*, float*, double*)
 # '.' test
 --format=gnu-v3
 _Z1hI1AIiEdEDTcldtfp_1gIT0_EEET_S2_
-decltype (({parm#1}.(g<double>))()) h<A<int>, double>(A<int>, double)
+decltype (({parm#1}.(g<double>))) h<A<int>, double>(A<int>, double)
 # test for typed function in decltype
 --format=gnu-v3
 _ZN1AIiE1jIiEEDTplfp_clL_Z1xvEEET_
-decltype ({parm#1}+((x())())) A<int>::j<int>(int)
+decltype ({parm#1}+((x()))) A<int>::j<int>(int)
 # test for expansion of function parameter pack
 --format=gnu-v3
 _Z1gIIidEEDTclL_Z1fEspplfp_Li1EEEDpT_
-decltype (f(({parm#1}+(1))...)) g<int, double>(int, double)
+decltype (f) g<int, double>(int, double)
 # lambda tests
 --format=gnu-v3
 _ZZ1giENKUlvE_clEv
@@ -3949,10 +3949,10 @@  _Z1fIfLi4EEvDv_T0__T_
 void f<float, 4>(float __vector(4))
 --format=gnu-v3
 _Z1fI1AEDTclonplfp_fp_EET_
-decltype ((operator+)({parm#1}, {parm#1})) f<A>(A)
+decltype ((operator+)) f<A>(A)
 --format=gnu-v3
 _Z1hI1AEDTcldtfp_miEET_
-decltype (({parm#1}.(operator-))()) h<A>(A)
+decltype (({parm#1}.(operator-))) h<A>(A)
 --format=gnu-v3
 _Z1fDn
 f(decltype(nullptr))
@@ -3990,6 +3990,18 @@  outer(short (*)(int), long)
 _Z6outer2IsEPFilES1_
 outer2<short>(int (*)(long))
 #
+--format=gnu-v3 --no-params
+_ZN1KIXadL_ZN1S1mEiEEE1fEv
+K<&S::m>::f()
+K<&S::m>::f
+--format=gnu-v3
+_ZN1KILi1EXadL_ZN1S1mEiEEE1fEv
+K<1, &S::m>::f()
+# Here the `(int)' argument list of `S::m' is already removed.
+--format=gnu-v3
+_ZN1KILi1EXadL_ZN1S1mEEEE1fEv
+K<1, &S::m>::f()
+#
 # Ada (GNAT) tests.
 #
 # Simple test.