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] [PR14448] Fold non-dependent initializers in templates (regression)


Hello,

PR c++/14448 exposed two different bugs.

- The testcase was segfaulting deep into pt.c because of another
tsubst_copy_and_build -> tsubst_copy fallback. For the logs, the problem is
that fold_non_dependent_expr (called for the template argument "n+1") does not
setup local_specializations, so tsubst_decl cannot work correctly (and I'm not
sure if there is something wrong in this or not). Anyway, it's my understanding
that tsubst_copy is obsolete now and should be removed, so adding support for
the missing tree in tsubst_copy_and_build is enough to fix the crash.

- After that, we get a meaningful error message, which says that "((int)n)+1 is
non-constant". It appears that the problem is that the initializer of the
static const variable was never folded correctly because it is within a
template. I added a call to fold_non_dependent_expr at the right spot of the
parser.

Tested on i686-pc-linux-gnu with no new regressions. OK for mainline and 3.4?

Giovanni Bajo



cp/
2004-03-08  Giovanni Bajo  <giovannibajo@gcc.gnu.org>

        PR c++/14448
        * parser.c (cp_parser_initializer_clause): Fold initializer if it is
        non-dependent.
        * pt.c (tsubst_copy_and_build): Handle NOP_EXPRs.


testsuite/
2004-03-08  Giovanni Bajo  <giovannibajo@gcc.gnu.org>

        PR c++/14448
        * g++.dg/parse/crash14.C: New test.


Index: parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.174
diff -c -3 -p -r1.174 parser.c
*** parser.c 19 Feb 2004 03:06:09 -0000 1.174
--- parser.c 8 Mar 2004 01:29:34 -0000
*************** cp_parser_initializer_clause (cp_parser*
*** 11505,11514 ****
    /* If it is not a `{', then we are looking at an
       assignment-expression.  */
    if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE))
!     initializer
!       = cp_parser_constant_expression (parser,
!            /*allow_non_constant_p=*/true,
!            non_constant_p);
    else
      {
        /* Consume the `{' token.  */
--- 11520,11533 ----
    /* If it is not a `{', then we are looking at an
       assignment-expression.  */
    if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE))
!     {
!       initializer
!  = cp_parser_constant_expression (parser,
!      /*allow_non_constant_p=*/true,
!      non_constant_p);
!       if (!*non_constant_p)
!  initializer = fold_non_dependent_expr (initializer);
!     }
    else
      {
        /* Consume the `{' token.  */
Index: pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.830
diff -c -3 -p -r1.830 pt.c
*** pt.c 14 Feb 2004 11:28:59 -0000 1.830
--- pt.c 8 Mar 2004 01:42:32 -0000
*************** tsubst_copy_and_build (tree t,
*** 8165,8170 ****
--- 8177,8187 ----
      case INDIRECT_REF:
        return build_x_indirect_ref (RECUR (TREE_OPERAND (t, 0)), "unary *");

+     case NOP_EXPR:
+       return build_nop
+  (tsubst (TREE_TYPE (t), args, complain, in_decl),
+   RECUR (TREE_OPERAND (t, 0)));
+
      case CAST_EXPR:
        return build_functional_cast
   (tsubst (TREE_TYPE (t), args, complain, in_decl),




// { dg-do compile }
// Contributed by: Giovanni Bajo <giovannibajo at libero dot it>
// PR c++/14448: Fold constant initializers in templates

template <int> struct A
{
    A();
};


template<typename T> void foo(T)
{
  static const int n=1;
  A<n+1> a;
}

void bar()
{
    foo(0);
}



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