mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-25 23:41:28 +08:00
re PR c++/26559 (ICE with __builtin_constant_p in template argument)
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 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. From-SVN: r114665
This commit is contained in:
parent
801522dead
commit
fe89d79748
@ -1,3 +1,11 @@
|
||||
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
|
||||
|
@ -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 *);
|
||||
|
17
gcc/c-omp.c
17
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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 %<;%>");
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,19 @@
|
||||
|
||||
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.
|
||||
|
||||
|
38
gcc/cp/pt.c
38
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
|
||||
|
@ -1,5 +1,9 @@
|
||||
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.
|
||||
|
@ -17,11 +17,10 @@ template<typename T> void f2(float *f)
|
||||
}
|
||||
|
||||
// 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.
|
||||
|
11
gcc/testsuite/g++.dg/template/builtin1.C
Normal file
11
gcc/testsuite/g++.dg/template/builtin1.C
Normal file
@ -0,0 +1,11 @@
|
||||
// PR c++/26559
|
||||
|
||||
template<bool> struct cond;
|
||||
|
||||
template<int> struct S {
|
||||
void f(int i) {
|
||||
cond<__builtin_constant_p(i)>();
|
||||
}
|
||||
};
|
||||
|
||||
S<1> s;
|
Loading…
x
Reference in New Issue
Block a user