This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH c++/19628 (take 2)
- From: Matt Austern <matt at lafstern dot org>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Sun, 30 Jan 2005 11:19:55 -0800
- Subject: PATCH c++/19628 (take 2)
This patch reenables accepting __builtin_constant_p in
constant-expressions. I don't believe there was a good reason, or even
a deliberate decision, to prohibit it.
There may be other builtins that we want to allow in
constant-expressions. If so, this patch will make it easy to add them
as desired.
OK to commit to mainline?
--Matt
* cp-tree.h (builtin_is_constant_p): Declare.
* tree.c (builtin_is_constant_p): New function.
* parser.c (cp_parser_postfix_expression): Allow function call in
constant expression if it's a builtin for which builtin_is_constant_p
returns true.
* semantics.c (finish_id_expression): Likewise.
* g++.dg/ext/builtin7.C: New test.
Index: gcc/cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.1097
diff -p -r1.1097 cp-tree.h
*** gcc/cp/cp-tree.h 20 Jan 2005 07:12:49 -0000 1.1097
--- gcc/cp/cp-tree.h 30 Jan 2005 19:04:41 -0000
*************** extern tree copy_binfo (tree,
tree, t
*** 4204,4209 ****
--- 4204,4210 ----
tree *, int);
extern int member_p (tree);
extern cp_lvalue_kind real_lvalue_p (tree);
+ extern bool builtin_is_constant_p (tree);
extern tree build_min (enum tree_code, tree,
...);
extern tree build_min_nt (enum tree_code, ...);
extern tree build_min_non_dep (enum tree_code, tree,
...);
Index: gcc/cp/parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.304
diff -p -r1.304 parser.c
*** gcc/cp/parser.c 29 Jan 2005 02:07:05 -0000 1.304
--- gcc/cp/parser.c 30 Jan 2005 19:04:41 -0000
*************** cp_parser_postfix_expression (cp_parser
*** 3988,3995 ****
/* Function calls are not permitted in
constant-expressions. */
! if (cp_parser_non_integral_constant_expression (parser,
! "a function
call"))
{
postfix_expression = error_mark_node;
break;
--- 3988,3996 ----
/* Function calls are not permitted in
constant-expressions. */
! if (! builtin_is_constant_p (postfix_expression)
! && cp_parser_non_integral_constant_expression (parser,
! "a
function call"))
{
postfix_expression = error_mark_node;
break;
Index: gcc/cp/semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/semantics.c,v
retrieving revision 1.458
diff -p -r1.458 semantics.c
*** gcc/cp/semantics.c 27 Jan 2005 07:32:25 -0000 1.458
--- gcc/cp/semantics.c 30 Jan 2005 19:04:41 -0000
*************** finish_id_expression (tree id_expression
*** 2658,2664 ****
expression. Enumerators and template parameters have already
been handled above. */
if (integral_constant_expression_p
! && !DECL_INTEGRAL_CONSTANT_VAR_P (decl))
{
if (!allow_non_integral_constant_expression_p)
{
--- 2658,2665 ----
expression. Enumerators and template parameters have already
been handled above. */
if (integral_constant_expression_p
! && ! DECL_INTEGRAL_CONSTANT_VAR_P (decl)
! && ! builtin_is_constant_p (decl))
{
if (!allow_non_integral_constant_expression_p)
{
Index: gcc/cp/tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/tree.c,v
retrieving revision 1.425
diff -p -r1.425 tree.c
*** gcc/cp/tree.c 18 Jan 2005 23:51:26 -0000 1.425
--- gcc/cp/tree.c 30 Jan 2005 19:04:47 -0000
*************** lvalue_p (tree ref)
*** 215,220 ****
--- 215,234 ----
(lvalue_p_1 (ref, /*class rvalue ok*/ 1) != clk_none);
}
+ /* Test whether DECL is a builtin that may appear in a
+ constant-expression. */
+
+ bool
+ builtin_is_constant_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
cvs diff: gcc/testsuite/g++.dg/ext/builtin7.C is a new entry, no
comparison available
[isolde:fsf]$ cvs -z3 diff -pN
Index: gcc/cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.1097
diff -p -r1.1097 cp-tree.h
*** gcc/cp/cp-tree.h 20 Jan 2005 07:12:49 -0000 1.1097
--- gcc/cp/cp-tree.h 30 Jan 2005 19:06:29 -0000
*************** extern tree copy_binfo (tree,
tree, t
*** 4204,4209 ****
--- 4204,4210 ----
tree *, int);
extern int member_p (tree);
extern cp_lvalue_kind real_lvalue_p (tree);
+ extern bool builtin_is_constant_p (tree);
extern tree build_min (enum tree_code, tree,
...);
extern tree build_min_nt (enum tree_code, ...);
extern tree build_min_non_dep (enum tree_code, tree,
...);
Index: gcc/cp/parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.304
diff -p -r1.304 parser.c
*** gcc/cp/parser.c 29 Jan 2005 02:07:05 -0000 1.304
--- gcc/cp/parser.c 30 Jan 2005 19:06:29 -0000
*************** cp_parser_postfix_expression (cp_parser
*** 3988,3995 ****
/* Function calls are not permitted in
constant-expressions. */
! if (cp_parser_non_integral_constant_expression (parser,
! "a function
call"))
{
postfix_expression = error_mark_node;
break;
--- 3988,3996 ----
/* Function calls are not permitted in
constant-expressions. */
! if (! builtin_is_constant_p (postfix_expression)
! && cp_parser_non_integral_constant_expression (parser,
! "a
function call"))
{
postfix_expression = error_mark_node;
break;
Index: gcc/cp/semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/semantics.c,v
retrieving revision 1.458
diff -p -r1.458 semantics.c
*** gcc/cp/semantics.c 27 Jan 2005 07:32:25 -0000 1.458
--- gcc/cp/semantics.c 30 Jan 2005 19:06:29 -0000
*************** finish_id_expression (tree id_expression
*** 2658,2664 ****
expression. Enumerators and template parameters have already
been handled above. */
if (integral_constant_expression_p
! && !DECL_INTEGRAL_CONSTANT_VAR_P (decl))
{
if (!allow_non_integral_constant_expression_p)
{
--- 2658,2665 ----
expression. Enumerators and template parameters have already
been handled above. */
if (integral_constant_expression_p
! && ! DECL_INTEGRAL_CONSTANT_VAR_P (decl)
! && ! builtin_is_constant_p (decl))
{
if (!allow_non_integral_constant_expression_p)
{
Index: gcc/cp/tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/tree.c,v
retrieving revision 1.425
diff -p -r1.425 tree.c
*** gcc/cp/tree.c 18 Jan 2005 23:51:26 -0000 1.425
--- gcc/cp/tree.c 30 Jan 2005 19:06:33 -0000
*************** lvalue_p (tree ref)
*** 215,220 ****
--- 215,234 ----
(lvalue_p_1 (ref, /*class rvalue ok*/ 1) != clk_none);
}
+ /* Test whether DECL is a builtin that may appear in a
+ constant-expression. */
+
+ bool
+ builtin_is_constant_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
Index: gcc/testsuite/g++.dg/ext/builtin7.C
===================================================================
RCS file: gcc/testsuite/g++.dg/ext/builtin7.C
diff -N gcc/testsuite/g++.dg/ext/builtin7.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/ext/builtin7.C 30 Jan 2005 19:06:35 -0000
***************
*** 0 ****
--- 1,14 ----
+ // PR c++/19628
+ // Verify that __builtin_constant_p may appear in a
constant-expression.
+
+ // { dg-do run }
+
+ int main()
+ {
+ switch (3) {
+ case (__builtin_constant_p(7) ? 3 : 8):
+ return 0;
+ default:
+ return 1;
+ }
+ }