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]

C++: constant folding in a conditional expr


This test case fails if BROKEN is #defined:

class Foo
{
  public:

    static const unsigned ACONST = 0;
    static const unsigned BCONST = 1;

    void SetData(bool p);

  private:
    unsigned _data;
};

void Foo::SetData(bool p)
{
#ifdef BROKEN
    _data = p ? ACONST : BCONST;
#else
    if (p) 
        _data = ACONST;
    else
        _data = BCONST;
#endif
}

105527.o: In function `Foo::SetData(bool)':
105527.o(.text+0xd): undefined reference to `Foo::ACONST    '
105527.o(.text+0x17): undefined reference to `Foo::BCONST    '


This seems to be because build_conditional_expr treats 

   p ? ACONST : BCONST

as an lvalue and so doesn't subsitute the initializers for the const
members.  Of course, the static const members ACONST and BCONST are
never output, so we get a link error.

I've written a patch that doesn't treat the conditional expr as an
lvalue if either arm is read only, and that seems to fix the problem,
but is it the right fix?

Andrew.


Index: call.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/call.c,v
retrieving revision 1.265
diff -p -2 -c -r1.265 call.c
*** call.c      2001/03/23 01:49:10     1.265
--- call.c      2001/03/28 19:13:00
*************** build_conditional_expr (arg1, arg2, arg3
*** 3002,3006 ****
       If the second and third operands are lvalues and have the same
       type, the result is of that type and is an lvalue.  */
!   if (real_lvalue_p (arg2) && real_lvalue_p (arg3) && 
        same_type_p (arg2_type, arg3_type))
      {
--- 3002,3007 ----
       If the second and third operands are lvalues and have the same
       type, the result is of that type and is an lvalue.  */
!   if (! TREE_READONLY (arg2) && ! TREE_READONLY (arg3) &&
!       real_lvalue_p (arg2) && real_lvalue_p (arg3) && 
        same_type_p (arg2_type, arg3_type))
      {


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