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 <mark@codesourcery.com>
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 <mark@codesourcery.com>
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
+2006-06-14 Mark Mitchell <mark@codesourcery.com>
+
+ 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 <krebbel1@de.ibm.com>
PR middle-end/27959
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 *);
/* 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.
&& !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. */
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);
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);
}
c_parser_omp_atomic (c_parser *parser)
{
tree lhs, rhs;
+ tree stmt;
enum tree_code code;
c_parser_skip_to_pragma_eol (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 %<;%>");
}
2006-06-14 Mark Mitchell <mark@codesourcery.com>
+ * 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.
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;
}
/* 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)
|| 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
2006-06-14 Mark Mitchell <mark@codesourcery.com>
+ 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.
}
// Here the rhs is dependent, but not type dependent.
-// ??? Fails. See the comment in finish_omp_atomic.
template<typename T> 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.
--- /dev/null
+// PR c++/26559
+
+template<bool> struct cond;
+
+template<int> struct S {
+ void f(int i) {
+ cond<__builtin_constant_p(i)>();
+ }
+};
+
+S<1> s;