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] [PR14545] Constructor calls are not constant expressions (regression)


Hello Mark,

this patch fixes another latent problem exposed by my fix to
cp_parser_initializer_clause (to always fold non-dependent initializers), just
like your patch of yesterday for PR 14550. Here, we were failing to notice that
a constructor call in functional cast form is not an integral constant
expression.

The patch is a bit more complex because a functional cast can also be a cast to
a builtin type, which can be part of integral constant expressions. Thus, we
need to check if build_functional_cast returns a TARGET_EXPR. Moreover, within
templates, build_functional_cast does not perform any semantic building and
just returns a CAST_EXPR. I tried to change this (so that it would do the right
thing for non dependent types) but the patch was getting more and more complex,
and started to look a little too much invasive for 3.4.0. So I just added a
workaround with a FIXME for this situation.

This patch has been tested on i686-pc-linux-gnu with no new regressions. OK for
mainline and 3.4? The bug is clearly a showstopper for 3.4.0.

Giovanni Bajo



2004-03-16  Giovanni Bajo  <giovannibajo@gcc.gnu.org>

        PR c++/14545
        * parser.c (cp_parser_functional_cast): A call to a constructor
        is not an integral constant expression.


2004-03-16  Giovanni Bajo  <giovannibajo@gcc.gnu.org>

        PR c++/14545
        * g++.dg/parse/template15.C: New test.


Index: parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.182
diff -c -3 -p -r1.182 parser.c
*** parser.c 15 Mar 2004 16:16:11 -0000 1.182
--- parser.c 16 Mar 2004 15:17:43 -0000
*************** static tree
*** 14463,14474 ****
  cp_parser_functional_cast (cp_parser* parser, tree type)
  {
    tree expression_list;

    expression_list
      = cp_parser_parenthesized_expression_list (parser, false,
              /*non_constant_p=*/NULL);

!   return build_functional_cast (type, expression_list);
  }

  /* Save the tokens that make up the body of a member function defined
--- 14463,14491 ----
  cp_parser_functional_cast (cp_parser* parser, tree type)
  {
    tree expression_list;
+   tree cast;

    expression_list
      = cp_parser_parenthesized_expression_list (parser, false,
              /*non_constant_p=*/NULL);

!   cast = build_functional_cast (type, expression_list);
!   /* If the functional cast resolved to a constructor call, the
!      resulting expression is not an integral constant expression.  */
!   if (TREE_CODE (cast) == TARGET_EXPR
!       /* FIXME: build_functional_cast should generate TARGET_EXPRs
!    for non dependent class types in templates, but for now it
!    does not. We copy its logic here to understand if it is a
!    constructor call or not.  */
!       || (TREE_CODE (cast) == CAST_EXPR
!    && !type_dependent_expression_p (type)
!    && IS_AGGR_TYPE (TREE_TYPE (type))))
!     {
!       if (cp_parser_non_integral_constant_expression
!    (parser, "a call to a constructor"))
!  return error_mark_node;
!     }
!   return cast;
  }

  /* Save the tokens that make up the body of a member function defined



// { dg-do compile }
// Contributed by:
// PR c++/14545: constructor calls are not integer constant expressions

struct A1 { A1(); };
struct A2 { };

template <class T>
struct B
{
  void foo() {
    A1();
    A1 a1 = A1();

    A2();
    A2 a2 = A2();
  }
};

template struct B<void>;



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