From d377303fbe8d5a04666846331f9d37409adaaa45 Mon Sep 17 00:00:00 2001 From: mmitchel Date: Thu, 15 Jun 2006 03:26:38 +0000 Subject: [PATCH] 2006-06-14 Mark Mitchell PR c++/26559 * c-common.h (c_finish_omp_atomic): Adjust declaration. * c-omp.c (c_finish_omp_atomic): Return the expression to perform, rather than calling add_stmt on it. * c-parser.c (c_parser_omp_atomic): Adjust accordingly. 2006-06-14 Mark Mitchell PR c++/26559 * pt.c (tsubst_expr): Use finish_omp_atomic. (value_dependent_expression_p): All CALL_EXPRs are dependent. * semantics.c (finish_omp_atomic): Rework to use standard paradigms for handling non-dependent expressions. 2006-06-14 Mark Mitchell PR c++/26559 * g++.dg/template/builtin1.C: New test. * g++.dg/gomp/tpl-atomic-2.C: Remove XFAIL. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@114665 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 8 +++++++ gcc/c-common.h | 2 +- gcc/c-omp.c | 17 ++++++++------ gcc/c-parser.c | 5 ++++- gcc/cp/ChangeLog | 13 +++++++++++ gcc/cp/pt.c | 38 ++++++-------------------------- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/g++.dg/gomp/tpl-atomic-2.C | 3 +-- gcc/testsuite/g++.dg/template/builtin1.C | 11 +++++++++ 9 files changed, 59 insertions(+), 42 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/builtin1.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index defc39d..4713d2e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2006-06-14 Mark Mitchell + + PR c++/26559 + * c-common.h (c_finish_omp_atomic): Adjust declaration. + * c-omp.c (c_finish_omp_atomic): Return the expression to perform, + rather than calling add_stmt on it. + * c-parser.c (c_parser_omp_atomic): Adjust accordingly. + 2006-06-14 Andreas Krebbel PR middle-end/27959 diff --git a/gcc/c-common.h b/gcc/c-common.h index 92ab71d..4f4919e 100644 --- a/gcc/c-common.h +++ b/gcc/c-common.h @@ -948,7 +948,7 @@ extern tree c_finish_omp_master (tree); extern tree c_finish_omp_critical (tree, tree); extern tree c_finish_omp_ordered (tree); extern void c_finish_omp_barrier (void); -extern void c_finish_omp_atomic (enum tree_code, tree, tree); +extern tree c_finish_omp_atomic (enum tree_code, tree, tree); extern void c_finish_omp_flush (void); extern tree c_finish_omp_for (location_t, tree, tree, tree, tree, tree, tree); extern void c_split_parallel_clauses (tree, tree *, tree *); diff --git a/gcc/c-omp.c b/gcc/c-omp.c index ac107e6..fe56824 100644 --- a/gcc/c-omp.c +++ b/gcc/c-omp.c @@ -82,15 +82,18 @@ c_finish_omp_barrier (void) /* Complete a #pragma omp atomic construct. The expression to be - implemented atomically is LHS code= RHS. */ + implemented atomically is LHS code= RHS. The value returned is + either error_mark_node (if the construct was erroneous) or an + OMP_ATOMIC node which should be added to the current statement tree + with add_stmt. */ -void +tree c_finish_omp_atomic (enum tree_code code, tree lhs, tree rhs) { tree x, type, addr; if (lhs == error_mark_node || rhs == error_mark_node) - return; + return error_mark_node; /* ??? According to one reading of the OpenMP spec, complex type are supported, but there are no atomic stores for any architecture. @@ -102,7 +105,7 @@ c_finish_omp_atomic (enum tree_code code, tree lhs, tree rhs) && !SCALAR_FLOAT_TYPE_P (type)) { error ("invalid expression type for %<#pragma omp atomic%>"); - return; + return error_mark_node; } /* ??? Validate that rhs does not overlap lhs. */ @@ -111,7 +114,7 @@ c_finish_omp_atomic (enum tree_code code, tree lhs, tree rhs) via indirection. */ addr = build_unary_op (ADDR_EXPR, lhs, 0); if (addr == error_mark_node) - return; + return error_mark_node; addr = save_expr (addr); lhs = build_indirect_ref (addr, NULL); @@ -120,12 +123,12 @@ c_finish_omp_atomic (enum tree_code code, tree lhs, tree rhs) to do this, and then take it apart again. */ x = build_modify_expr (lhs, code, rhs); if (x == error_mark_node) - return; + return error_mark_node; gcc_assert (TREE_CODE (x) == MODIFY_EXPR); rhs = TREE_OPERAND (x, 1); /* Punt the actual generation of atomic operations to common code. */ - add_stmt (build2 (OMP_ATOMIC, void_type_node, addr, rhs)); + return build2 (OMP_ATOMIC, void_type_node, addr, rhs); } diff --git a/gcc/c-parser.c b/gcc/c-parser.c index 8afe79c..bca6a14 100644 --- a/gcc/c-parser.c +++ b/gcc/c-parser.c @@ -7214,6 +7214,7 @@ static void c_parser_omp_atomic (c_parser *parser) { tree lhs, rhs; + tree stmt; enum tree_code code; c_parser_skip_to_pragma_eol (parser); @@ -7280,7 +7281,9 @@ c_parser_omp_atomic (c_parser *parser) rhs = c_parser_expression (parser).value; break; } - c_finish_omp_atomic (code, lhs, rhs); + stmt = c_finish_omp_atomic (code, lhs, rhs); + if (stmt != error_mark_node) + add_stmt (stmt); c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); } diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f8721f7..abd63d9 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -4,6 +4,19 @@ 2006-06-14 Mark Mitchell + * parser.c (cp_parser_unqualified_id): Use constructor_name_p to + check destructor names. + (cp_parser_nested_name_specifier_opt): Remove invalid + optimization. + + * parser.c (cp_parser_declarator): Robustify. + + PR c++/26559 + * pt.c (tsubst_expr): Use finish_omp_atomic. + (value_dependent_expression_p): All CALL_EXPRs are dependent. + * semantics.c (finish_omp_atomic): Rework to use standard + paradigms for handling non-dependent expressions. + PR c++/28018 * typeck.c (build_modify_expr): Disallow array assignment. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 07963d6..0cc93fd 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -8546,10 +8546,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) tree op0, op1; op0 = tsubst_expr (TREE_OPERAND (t, 0), args, complain, in_decl); op1 = tsubst_expr (TREE_OPERAND (t, 1), args, complain, in_decl); - if (OMP_ATOMIC_DEPENDENT_P (t)) - c_finish_omp_atomic (OMP_ATOMIC_CODE (t), op0, op1); - else - add_stmt (build2 (OMP_ATOMIC, void_type_node, op0, op1)); + finish_omp_atomic (OMP_ATOMIC_CODE (t), op0, op1); } break; @@ -12473,7 +12470,8 @@ dependent_scope_ref_p (tree expression, bool criterion (tree)) } /* Returns TRUE if the EXPRESSION is value-dependent, in the sense of - [temp.dep.constexpr] */ + [temp.dep.constexpr]. EXPRESSION is already known to be a constant + expression. */ bool value_dependent_expression_p (tree expression) @@ -12564,32 +12562,10 @@ value_dependent_expression_p (tree expression) || value_dependent_expression_p (TREE_OPERAND (expression, 1))); case CALL_EXPR: - /* A CALL_EXPR is value-dependent if any argument is - value-dependent. Why do we have to handle CALL_EXPRs in this - function at all? First, some function calls, those for which - value_dependent_expression_p is true, man appear in constant - expressions. Second, there appear to be bugs which result in - other CALL_EXPRs reaching this point. */ - { - tree function = TREE_OPERAND (expression, 0); - tree args = TREE_OPERAND (expression, 1); - - if (value_dependent_expression_p (function)) - return true; - - if (! args) - return false; - - if (TREE_CODE (args) == TREE_LIST) - { - for (; args; args = TREE_CHAIN (args)) - if (value_dependent_expression_p (TREE_VALUE (args))) - return true; - return false; - } - - return value_dependent_expression_p (args); - } + /* A CALL_EXPR may appear in a constant expression if it is a + call to a builtin function, e.g., __builtin_constant_p. All + such calls are value-dependent. */ + return true; default: /* A constant expression is value-dependent if any subexpression is diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b5d4925..6615324 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,9 @@ 2006-06-14 Mark Mitchell + PR c++/26559 + * g++.dg/template/builtin1.C: New test. + * g++.dg/gomp/tpl-atomic-2.C: Remove XFAIL. + PR c++/28018 * g++.old-deja/g++.benjamin/14664-2.C: Expect error for array assignment. diff --git a/gcc/testsuite/g++.dg/gomp/tpl-atomic-2.C b/gcc/testsuite/g++.dg/gomp/tpl-atomic-2.C index 363bd10..c27f201 100644 --- a/gcc/testsuite/g++.dg/gomp/tpl-atomic-2.C +++ b/gcc/testsuite/g++.dg/gomp/tpl-atomic-2.C @@ -17,11 +17,10 @@ template void f2(float *f) } // Here the rhs is dependent, but not type dependent. -// ??? Fails. See the comment in finish_omp_atomic. template void f3(float *f) { #pragma omp atomic - *f |= sizeof (T); // { dg-error "invalid|evaluation" "" { xfail *-*-* } } + *f |= sizeof (T); // { dg-error "invalid|evaluation" } } // And the converse, no error here because we're never fed a T. diff --git a/gcc/testsuite/g++.dg/template/builtin1.C b/gcc/testsuite/g++.dg/template/builtin1.C new file mode 100644 index 0000000..a5b7271 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/builtin1.C @@ -0,0 +1,11 @@ +// PR c++/26559 + +template struct cond; + +template struct S { + void f(int i) { + cond<__builtin_constant_p(i)>(); + } +}; + +S<1> s; -- 2.7.4