[PATCH?] PR optimization/5079: Help with C++ conversion functions

Roger Sayle roger@eyesopen.com
Sun Jul 6 18:05:00 GMT 2003


I need some help finding my way around the twisty turny maze of conversion
functions available to the C++ front-end.  The patch below resolves
PR optimization/5079, which I discovered by browsing bugzilla's most
frequently reported bugs list, but unfortunately it introduces a new
testsuite regression...

Consider the three functions below:

class Foo {
public:
static const int erf = 0;
static const int foo = 1;
};

int one()
{
  return Foo::foo;
}

int two()
{
  return Foo::foo + Foo:erf;
}

int three(int x)
{
  return x ? Foo::erf : Foo::foo;
}


With current mainline g++ functions "one" and "two" inline the initialized
static constants, but "three" doesn't.  [I appreciate this C++ example
may be ill-formed C++, but it serves to demonstrate the inconsistency.]

The difference appears to be that in the first two cases, the g++
front-end calls "convert" on the "var" which ends up replacing the
const variable with its initializer.  In the third, build_conditional_expr
doesn't call convert on its second and third operands, and hence the
variable reference is never replaced with its initializer.

The "proof of concept" patch below calls generic "convert" at the
appropriate places in g++'s build_conditional_expr, and indeed allows
function "three" above to be optimized by the compiler.  The problem
is that I'm fairly certain that "convert" is probably not the appropriate
function to use; perhaps cp_convert, or ocp_convert, or maybe even
perform_implicit_conversion.  In short, I'm lost.  Just to confirm how
lost, the patch below survives a complete "make bootstrap" on
i686-pc-linux-gnu, all languages except treelang, but with a single
testsuite regression: g++.old-deja/g++.other/array5.C, which reads:

extern int a1[];
extern int a2[];
int foo(int p)
{
  int x = (p ? a1 : a2)[1];
  return x;
}

which with my patch fails with the error message:
array5.C:8: error: conversion from `int[]' to non-scalar type
           `int[]' requested

Clearly, "convert" is not the precise function that's required.  Could
anyone who understands C++'s type system tell me the appropriate function?
If there isn't a conversion that will replace the initializer without
the above error, should I test for scalar types?  Is this approach the
correct solution?


Many thanks in advance,


2003-07-06  Roger Sayle  <roger@eyesopen.com>

	PR optimization/5079
	* call.c (build_conditional_expr): Call convert on operands of a
	conditional expression once the result type has been determined.


Index: call.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/call.c,v
retrieving revision 1.400
diff -c -3 -p -r1.400 call.c
*** call.c	5 Jul 2003 03:02:02 -0000	1.400
--- call.c	6 Jul 2003 14:09:13 -0000
*************** build_conditional_expr (tree arg1, tree
*** 3299,3304 ****
--- 3299,3308 ----
  	  return error_mark_node;
  	}

+       if (! VOID_TYPE_P (arg2_type))
+ 	arg2 = convert (result_type, arg2);
+       if (! VOID_TYPE_P (arg3_type))
+ 	arg3 = convert (result_type, arg3);
        lvalue_p = false;
        goto valid_operands;
      }
*************** build_conditional_expr (tree arg1, tree
*** 3356,3361 ****
--- 3360,3367 ----
        same_type_p (arg2_type, arg3_type))
      {
        result_type = arg2_type;
+       arg2 = convert (result_type, arg2);
+       arg3 = convert (result_type, arg3);
        goto valid_operands;
      }

*************** build_conditional_expr (tree arg1, tree
*** 3449,3455 ****
       --The second and third operands have the same type; the result  is  of
         that type.  */
    if (same_type_p (arg2_type, arg3_type))
!     result_type = arg2_type;
    /* [expr.cond]

       --The second and third operands have arithmetic or enumeration
--- 3455,3465 ----
       --The second and third operands have the same type; the result  is  of
         that type.  */
    if (same_type_p (arg2_type, arg3_type))
!     {
!       result_type = arg2_type;
!       arg2 = convert (result_type, arg2);
!       arg3 = convert (result_type, arg3);
!     }
    /* [expr.cond]

       --The second and third operands have arithmetic or enumeration

Roger
--
Roger Sayle,                         E-mail: roger@eyesopen.com
OpenEye Scientific Software,         WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road,     Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507.         Fax: (+1) 505-473-0833



More information about the Gcc-patches mailing list