This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] [PR14545] Constructor calls are not constant expressions (regression)
- From: "Giovanni Bajo" <giovannibajo at libero dot it>
- To: "Mark Mitchell" <mark at codesourcery dot com>
- Cc: <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 16 Mar 2004 17:31:24 +0100
- Subject: [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>;