This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: PR 21619
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 5 Jun 2005 09:53:07 -0700
- Subject: C++ PATCH: PR 21619
- Reply-to: mark at codesourcery dot com
This patch mostly fixes PR c++/21619. When we started correctly
checking integral constant-expressions we became too strict; the
arguments to __builtin_constant_p are allowed to be non-constant, even
if the call appears in a constant expression. However, the test case
assumes that &"hello"[1] is a constant; the 4.0 branch does not agree,
though 4.1 does. So, while I put the patch on both branches, the test
case is only on 4.1.
Tested on x86_64-unknown-linux-gnu, applied on the mainline and 4.0
branch.
--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com
2005-06-05 Mark Mitchell <mark@codesourcery.com>
PR c++/21619
* cp-tree.h (DECL_IS_BUILTIN_CONSTANT_P): New macro.
* parser.c (cp_parser_postfix_expression): Allow non-constant
expressions as arguments to __builtin_constant_p.
* tree.c (builtin_valid_in_constant_expr_p): Use
DECL_IS_BUILTIN_CONSTANT_P.
2005-06-05 Mark Mitchell <mark@codesourcery.com>
PR c++/21619
* g++.dg/ext/builtin9.C: New test.
Index: gcc/cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.1140
diff -c -5 -p -r1.1140 cp-tree.h
*** gcc/cp/cp-tree.h 3 Jun 2005 16:16:10 -0000 1.1140
--- gcc/cp/cp-tree.h 5 Jun 2005 16:28:54 -0000
*************** struct lang_decl GTY(())
*** 1785,1794 ****
--- 1785,1800 ----
constructor or a destructor with an extra in-charge parameter to
control whether or not virtual bases are constructed. */
#define DECL_HAS_IN_CHARGE_PARM_P(NODE) \
(DECL_LANG_SPECIFIC (NODE)->decl_flags.has_in_charge_parm_p)
+ /* Nonzero if DECL is a declaration of __builtin_constant_p. */
+ #define DECL_IS_BUILTIN_CONSTANT_P(NODE) \
+ (TREE_CODE (NODE) == FUNCTION_DECL \
+ && DECL_BUILT_IN_CLASS (NODE) == BUILT_IN_NORMAL \
+ && DECL_FUNCTION_CODE (NODE) == BUILT_IN_CONSTANT_P)
+
/* Nonzero for _DECL means that this decl appears in (or will appear
in) as a member in a RECORD_TYPE or UNION_TYPE node. It is also for
detecting circularity in case members are multiply defined. In the
case of a VAR_DECL, it is also used to determine how program storage
should be allocated. */
Index: gcc/cp/parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.335
diff -c -5 -p -r1.335 parser.c
*** gcc/cp/parser.c 27 May 2005 23:17:14 -0000 1.335
--- gcc/cp/parser.c 5 Jun 2005 16:28:54 -0000
*************** cp_parser_postfix_expression (cp_parser
*** 4119,4132 ****
case CPP_OPEN_PAREN:
/* postfix-expression ( expression-list [opt] ) */
{
bool koenig_p;
! tree args = (cp_parser_parenthesized_expression_list
! (parser, false,
! /*cast_p=*/false,
! /*non_constant_p=*/NULL));
if (args == error_mark_node)
{
postfix_expression = error_mark_node;
break;
--- 4119,4156 ----
case CPP_OPEN_PAREN:
/* postfix-expression ( expression-list [opt] ) */
{
bool koenig_p;
! bool is_builtin_constant_p;
! bool saved_integral_constant_expression_p = false;
! bool saved_non_integral_constant_expression_p = false;
! tree args;
!
! is_builtin_constant_p
! = DECL_IS_BUILTIN_CONSTANT_P (postfix_expression);
! if (is_builtin_constant_p)
! {
! /* The whole point of __builtin_constant_p is to allow
! non-constant expressions to appear as arguments. */
! saved_integral_constant_expression_p
! = parser->integral_constant_expression_p;
! saved_non_integral_constant_expression_p
! = parser->non_integral_constant_expression_p;
! parser->integral_constant_expression_p = false;
! }
! args = (cp_parser_parenthesized_expression_list
! (parser, /*is_attribute_list=*/false,
! /*cast_p=*/false,
! /*non_constant_p=*/NULL));
! if (is_builtin_constant_p)
! {
! parser->integral_constant_expression_p
! = saved_integral_constant_expression_p;
! parser->non_integral_constant_expression_p
! = saved_non_integral_constant_expression_p;
! }
if (args == error_mark_node)
{
postfix_expression = error_mark_node;
break;
Index: gcc/cp/tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/tree.c,v
retrieving revision 1.435
diff -c -5 -p -r1.435 tree.c
*** gcc/cp/tree.c 27 May 2005 23:17:20 -0000 1.435
--- gcc/cp/tree.c 5 Jun 2005 16:28:54 -0000
*************** lvalue_p (tree ref)
*** 223,235 ****
bool
builtin_valid_in_constant_expr_p (tree decl)
{
/* At present BUILT_IN_CONSTANT_P is the only builtin we're allowing
in constant-expressions. We may want to add other builtins later. */
! return TREE_CODE (decl) == FUNCTION_DECL
! && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
! && DECL_FUNCTION_CODE (decl) == BUILT_IN_CONSTANT_P;
}
/* Build a TARGET_EXPR, initializing the DECL with the VALUE. */
static tree
--- 223,233 ----
bool
builtin_valid_in_constant_expr_p (tree decl)
{
/* At present BUILT_IN_CONSTANT_P is the only builtin we're allowing
in constant-expressions. We may want to add other builtins later. */
! return DECL_IS_BUILTIN_CONSTANT_P (decl);
}
/* Build a TARGET_EXPR, initializing the DECL with the VALUE. */
static tree
Index: gcc/testsuite/g++.dg/ext/builtin9.C
===================================================================
RCS file: gcc/testsuite/g++.dg/ext/builtin9.C
diff -N gcc/testsuite/g++.dg/ext/builtin9.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/ext/builtin9.C 5 Jun 2005 16:28:54 -0000
***************
*** 0 ****
--- 1,3 ----
+ // PR c++/21619
+ // { dg-options "" }
+ int f[__builtin_constant_p(&"Hello"[0])?1:-1];