Implemented Jason Merrill's suggestions on Array Notation C++.
gcc/ChangeLog 2013-06-28 Balaji V. Iyer <balaji.v.iyer@intel.com> * builtins.def: Fixed the function type of CILKPLUS_BUILTIN. gcc/c/ChangeLog 2013-06-28 Balaji V. Iyer <balaji.v.iyer@intel.com> * c-parser.c (c_parser_array_notation): Removed rejection of array notations in an array of function pointers. gcc/c-family/ChangeLog 2013-06-28 Balaji V. Iyer <balaji.v.iyer@intel.com> * array-notation-common.c (length_mismatch_in_expr_p): Collapsed two if-statements and compared the trees directly using tree_int_cst_equal. (find_rank): Checked for array notations in function name to handle array notations in function pointers. (extract_array_notation_exprs): Likewise. (replace_array_notations): Likewise. (cilkplus_extract_an_triplets): Replaced safe_push with safe_grow_cleared. Also removed an unnecessary check to see if the node is of type ARRAY_NOTATION_REF. (fix_sec_implicit_args): Removed an unnecessary check for ADDR_EXPR. Also switched two if-statements to remove an unnecessary comparison. gcc/cp/ChangeLog 2013-06-28 Balaji V. Iyer <balaji.v.iyer@intel.com> * parser.c (cp_parser_array_notation): Removed rejection array notation of type function pointers. Added handling of array expressions when Cilk Plus is enabled. Took out type-checking. (cp_parser_postfix_open_square_expression): Moved normal array expr. parsing into cp_parser_array_notation when cilkplus is enabled. (cp_parser_compound_statement): Removed expansion of array notations. (cp_parser_ctor_initializer_opt_and_function_body): Likewise. (cp_parser_function_definition_after_declarator): Likewise. (cp_parser_selection_statement): Removed error reporting. (cp_parser_iteration_statement): Likewise. (cp_parser_direct_declarator): Removed error checking/reporting if array notations are used in the declarator. * pt.c (instantiate_decl): Likewise. (type_unification_real): Removed a check for ARRAY_NOTATION_REF. (cxx_eval_constant_expression): Removed ARRAY_NOTATION_REF case. (potential_constant_expression_1): Returned false for ARRAY_NOTATION_REF case. * cp-gimplify.c (cp_genericize): Added expansion of array notation expressions here. * cp-array-notation.c (make_triplet_val_inv): Removed loc and cry parameters. Replaced build_decls with get_temp_regvar with type as ptrdiff. (create_array_refs): Made the type-casting to ptrdiff_type. (replace_invariant_var): Added a check for void return type before creating new var. Replaced build_decl and build_min_nt_loc with get_temp_regvar. (expand_an_in_modify_expr): Ditto. Replaced body of redundant else with gcc_unreachable. Removed few unwanted checks. Made induction variable type as ptrdiff_type. Removed loc and complain arguments passed into make_triplet_val_inv. Replaced all modify expression's code from NOP EXPR to INIT EXPR. Replaced all forceful appending into stmt. list with the non-forceful one. Replaced some integer conversion and equality-checking to using tree_int_cst_equal. (expand_sec_reduce_builtin): All changes mentioned in above function expand_an_in_modify_expr. Made the new variable type of SEC_REDUCE_ANY/ALL_{NON}ZERO intrinsic functions as bool. (expand_array_notation_exprs): Removed SWITCH_EXPR case. Moved all the error reporting from parser to this function. Removed unwanted statements and checks from SWITCH_STMT, WHILE_STMT, and DO_STMT cases. (cilkplus_an_triplet_types_ok_p): Removed rejection of array notation in function pointers. (cp_expand_cond_array_notations): Added a new if statements to check if condition has a zero rank. If so, then just return. (expand_return_expr): Added a check for return expressions with a rank. Replaced get_tmp_regvar with a create_temporary_var. (build_array_notation_ref): Simplified and removed unwanted if-stmts. Moved common code outside if-statements. Moved type-checking from parser to here. * semantics.c (finish_return_stmt): Removed a check for return exprs. with a rank. * call.c (convert_like_real): Removed a check for array notation expression in a function. (build_over_call): Likewise. (magic_varargs_p): Added a check for builtin array notation function. Made this function non-static and removed its prototype. * cp-tree.h (magic_varargs_p): New prototype. * typeck.c (cp_build_function_call_vec): Removed automatic setting of nargs to the param->length when builtin reduction function is used. (convert_arguments): Replaced check for a constant_p function with margic_varargs_p function call. (cp_build_binary_op): Removed calling of the function find_correct_array_notation_type. (cp_build_addr_expr_1): Removed an unwanted if-statement. (convert_for_assignment): Removed automatic return of rhs when array notation builtin function is used. gcc/testsuite/ChangeLog 2013-06-28 Balaji V. Iyer <balaji.v.iyer@intel.com> * c-c++-common/cilk-plus/AN/decl-ptr-colon.c (main): Made this testcase c specific. * c-c++-common/cilk-plus/AN/decl-ptr-colon.c (main): Changed dg-error strings to match the fixed error messages. * c-c++-common/cilk-plus/AN/misc.c (main): Likewise. * c-c++-common/cilk-plus/AN/rank_mismatch.c (main): Added a new error message check. From-SVN: r200554
This commit is contained in:
parent
e32e4c4a88
commit
1141ed3f71
|
@ -1,3 +1,7 @@
|
|||
2013-06-28 Balaji V. Iyer <balaji.v.iyer@intel.com>
|
||||
|
||||
* builtins.def: Fixed the function type of CILKPLUS_BUILTIN.
|
||||
|
||||
2013-06-28 Vladimir Makarov <vmakarov@redhat.com>
|
||||
|
||||
* lra-constraints.c (need_for_split_p): Check call used hard regs
|
||||
|
|
|
@ -158,9 +158,9 @@ along with GCC; see the file COPYING3. If not see
|
|||
(flag_asan || flag_tsan))
|
||||
|
||||
#undef DEF_CILKPLUS_BUILTIN
|
||||
#define DEF_CILKPLUS_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||
DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
||||
false, false, true, ATTRS, false, flag_enable_cilkplus)
|
||||
#define DEF_CILKPLUS_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||
DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, BT_FN_INT_VAR, BT_LAST, \
|
||||
false, false, false, ATTRS, false, flag_enable_cilkplus)
|
||||
|
||||
/* Define an attribute list for math functions that are normally
|
||||
"impure" because some of them may write into global memory for
|
||||
|
|
|
@ -101,15 +101,11 @@ length_mismatch_in_expr_p (location_t loc, vec<vec<an_parts> >list)
|
|||
/* If length is a INTEGER, and list[ii][jj] is an integer then
|
||||
check if they are equal. If they are not equal then return
|
||||
true. */
|
||||
if (TREE_CODE (list[ii][jj].length) == INTEGER_CST)
|
||||
{
|
||||
l_node = int_cst_value (list[ii][jj].length);
|
||||
l_length = int_cst_value (length);
|
||||
if (absu_hwi (l_length) != absu_hwi (l_node))
|
||||
{
|
||||
error_at (loc, "length mismatch in expression");
|
||||
return true;
|
||||
}
|
||||
if (TREE_CODE (list[ii][jj].length) == INTEGER_CST
|
||||
&& !tree_int_cst_equal (list[ii][jj].length, length))
|
||||
{
|
||||
error_at (loc, "length mismatch in expression");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -271,6 +267,8 @@ find_rank (location_t loc, tree orig_expr, tree expr, bool ignore_builtin_fn,
|
|||
/* If it is a built-in function, then we know it returns a
|
||||
scalar. */
|
||||
return true;
|
||||
if (!find_rank (loc, orig_expr, func_name, ignore_builtin_fn, rank))
|
||||
return false;
|
||||
FOR_EACH_CALL_EXPR_ARG (arg, iter, expr)
|
||||
{
|
||||
if (!find_rank (loc, orig_expr, arg, ignore_builtin_fn, rank))
|
||||
|
@ -358,6 +356,9 @@ extract_array_notation_exprs (tree node, bool ignore_builtin_fn,
|
|||
vec_safe_push (*array_list, node);
|
||||
return;
|
||||
}
|
||||
/* This will extract array notations in function pointers. */
|
||||
extract_array_notation_exprs (CALL_EXPR_FN (node), ignore_builtin_fn,
|
||||
array_list);
|
||||
FOR_EACH_CALL_EXPR_ARG (arg, iter, node)
|
||||
extract_array_notation_exprs (arg, ignore_builtin_fn, array_list);
|
||||
}
|
||||
|
@ -433,6 +434,9 @@ replace_array_notations (tree *orig, bool ignore_builtin_fn,
|
|||
}
|
||||
return;
|
||||
}
|
||||
/* Fixes array notations in array notations in function pointers. */
|
||||
replace_array_notations (&CALL_EXPR_FN (*orig), ignore_builtin_fn, list,
|
||||
array_operand);
|
||||
ii = 0;
|
||||
FOR_EACH_CALL_EXPR_ARG (arg, iter, *orig)
|
||||
{
|
||||
|
@ -575,53 +579,49 @@ cilkplus_extract_an_triplets (vec<tree, va_gc> *list, size_t size, size_t rank,
|
|||
vec<vec<struct cilkplus_an_parts> > *node)
|
||||
{
|
||||
vec<vec<tree> > array_exprs = vNULL;
|
||||
struct cilkplus_an_parts init = { NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE,
|
||||
false };
|
||||
|
||||
node->safe_grow_cleared (size);
|
||||
array_exprs.safe_grow_cleared (size);
|
||||
for (size_t ii = 0; ii < size; ii++)
|
||||
for (size_t jj = 0; jj < rank; jj++)
|
||||
{
|
||||
(*node)[ii].safe_push (init);
|
||||
array_exprs[ii].safe_push (NULL_TREE);
|
||||
}
|
||||
|
||||
if (rank > 0)
|
||||
for (size_t ii = 0; ii < size; ii++)
|
||||
{
|
||||
(*node)[ii].safe_grow_cleared (rank);
|
||||
array_exprs[ii].safe_grow_cleared (rank);
|
||||
}
|
||||
for (size_t ii = 0; ii < size; ii++)
|
||||
{
|
||||
size_t jj = 0;
|
||||
tree ii_tree = (*list)[ii];
|
||||
while (ii_tree)
|
||||
if (TREE_CODE (ii_tree) == ARRAY_NOTATION_REF)
|
||||
{
|
||||
array_exprs[ii][jj] = ii_tree;
|
||||
jj++;
|
||||
ii_tree = ARRAY_NOTATION_ARRAY (ii_tree);
|
||||
}
|
||||
else if (TREE_CODE (ii_tree) == ARRAY_REF)
|
||||
ii_tree = TREE_OPERAND (ii_tree, 0);
|
||||
else if (TREE_CODE (ii_tree) == VAR_DECL
|
||||
|| TREE_CODE (ii_tree) == CALL_EXPR
|
||||
|| TREE_CODE (ii_tree) == PARM_DECL)
|
||||
break;
|
||||
else
|
||||
gcc_unreachable ();
|
||||
{
|
||||
if (TREE_CODE (ii_tree) == ARRAY_NOTATION_REF)
|
||||
{
|
||||
array_exprs[ii][jj] = ii_tree;
|
||||
jj++;
|
||||
ii_tree = ARRAY_NOTATION_ARRAY (ii_tree);
|
||||
}
|
||||
else if (TREE_CODE (ii_tree) == ARRAY_REF)
|
||||
ii_tree = TREE_OPERAND (ii_tree, 0);
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (size_t ii = 0; ii < size; ii++)
|
||||
if (TREE_CODE ((*list)[ii]) == ARRAY_NOTATION_REF)
|
||||
for (size_t jj = 0; jj < rank; jj++)
|
||||
if (TREE_CODE (array_exprs[ii][jj]) == ARRAY_NOTATION_REF)
|
||||
{
|
||||
tree ii_tree = array_exprs[ii][jj];
|
||||
(*node)[ii][jj].is_vector = true;
|
||||
(*node)[ii][jj].value = ARRAY_NOTATION_ARRAY (ii_tree);
|
||||
(*node)[ii][jj].start = ARRAY_NOTATION_START (ii_tree);
|
||||
(*node)[ii][jj].length =
|
||||
fold_build1 (CONVERT_EXPR, integer_type_node,
|
||||
ARRAY_NOTATION_LENGTH (ii_tree));
|
||||
(*node)[ii][jj].stride =
|
||||
fold_build1 (CONVERT_EXPR, integer_type_node,
|
||||
ARRAY_NOTATION_STRIDE (ii_tree));
|
||||
}
|
||||
{
|
||||
tree ii_tree = array_exprs[ii][jj];
|
||||
(*node)[ii][jj].is_vector = true;
|
||||
(*node)[ii][jj].value = ARRAY_NOTATION_ARRAY (ii_tree);
|
||||
(*node)[ii][jj].start = ARRAY_NOTATION_START (ii_tree);
|
||||
(*node)[ii][jj].length =
|
||||
fold_build1 (CONVERT_EXPR, integer_type_node,
|
||||
ARRAY_NOTATION_LENGTH (ii_tree));
|
||||
(*node)[ii][jj].stride =
|
||||
fold_build1 (CONVERT_EXPR, integer_type_node,
|
||||
ARRAY_NOTATION_STRIDE (ii_tree));
|
||||
}
|
||||
}
|
||||
|
||||
/* Replaces all the __sec_implicit_arg functions in LIST with the induction
|
||||
|
@ -637,16 +637,15 @@ fix_sec_implicit_args (location_t loc, vec <tree, va_gc> *list,
|
|||
vec <tree, va_gc> *array_operand = NULL;
|
||||
for (size_t ii = 0; ii < vec_safe_length (list); ii++)
|
||||
if (TREE_CODE ((*list)[ii]) == CALL_EXPR
|
||||
&& TREE_CODE (CALL_EXPR_FN ((*list)[ii])) == ADDR_EXPR
|
||||
&& is_sec_implicit_index_fn (CALL_EXPR_FN ((*list)[ii])))
|
||||
{
|
||||
int idx = extract_sec_implicit_index_arg (loc, (*list)[ii]);
|
||||
if (idx < (int) rank && idx >= 0)
|
||||
vec_safe_push (array_operand, an_loop_info[idx].var);
|
||||
else if (idx == -1)
|
||||
if (idx < 0)
|
||||
/* In this case, the returning function would have emitted an
|
||||
error thus it is not necessary to do so again. */
|
||||
return NULL;
|
||||
else if (idx < (int) rank)
|
||||
vec_safe_push (array_operand, an_loop_info[idx].var);
|
||||
else
|
||||
{
|
||||
error_at (loc, "__sec_implicit_index argument %d must be "
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2013-06-28 Balaji V. Iyer <balaji.v.iyer@intel.com>
|
||||
|
||||
* c-parser.c (c_parser_array_notation): Removed rejection of array
|
||||
notations in an array of function pointers.
|
||||
|
||||
2013-06-21 Balaji V. Iyer <balaji.v.iyer@intel.com>
|
||||
|
||||
* c-array-notation.c (make_triplet_val_inv): New function.
|
||||
|
|
|
@ -11053,24 +11053,6 @@ c_parser_array_notation (location_t loc, c_parser *parser, tree initial_index,
|
|||
c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
|
||||
return error_mark_node;
|
||||
}
|
||||
if (TREE_CODE (array_type) == ARRAY_TYPE)
|
||||
{
|
||||
tree subtype = TREE_TYPE (array_type);
|
||||
while (subtype && TREE_CODE (subtype) == POINTER_TYPE)
|
||||
{
|
||||
/* Now this could be a function pointer. Find them and
|
||||
give out an error. */
|
||||
subtype = TREE_TYPE (subtype);
|
||||
if (subtype && TREE_CODE (subtype) == FUNCTION_TYPE)
|
||||
{
|
||||
error_at (loc, "array notations cannot be used with "
|
||||
"function pointer arrays");
|
||||
c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
|
||||
NULL);
|
||||
return error_mark_node;
|
||||
}
|
||||
}
|
||||
}
|
||||
array_type_domain = TYPE_DOMAIN (array_type);
|
||||
|
||||
if (!array_type_domain)
|
||||
|
@ -11114,27 +11096,6 @@ c_parser_array_notation (location_t loc, c_parser *parser, tree initial_index,
|
|||
c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
|
||||
return error_mark_node;
|
||||
}
|
||||
if (TREE_CODE (array_type) == ARRAY_TYPE
|
||||
|| TREE_CODE (array_type) == POINTER_TYPE)
|
||||
{
|
||||
tree subtype = TREE_TYPE (array_type);
|
||||
while (subtype
|
||||
&& (TREE_CODE (subtype) == POINTER_TYPE
|
||||
|| TREE_CODE (subtype) == ARRAY_TYPE))
|
||||
{
|
||||
/* Now this could be a function pointer. Find them and
|
||||
give out an error. */
|
||||
subtype = TREE_TYPE (subtype);
|
||||
if (subtype && TREE_CODE (subtype) == FUNCTION_TYPE)
|
||||
{
|
||||
error_at (loc, "array notations cannot be used with "
|
||||
"function pointer arrays");
|
||||
c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
|
||||
NULL);
|
||||
return error_mark_node;
|
||||
}
|
||||
}
|
||||
}
|
||||
c_parser_consume_token (parser); /* consume the ':' */
|
||||
end_index = c_parser_expression (parser).value;
|
||||
if (!end_index || end_index == error_mark_node)
|
||||
|
|
|
@ -1,3 +1,71 @@
|
|||
2013-06-28 Balaji V. Iyer <balaji.v.iyer@intel.com>
|
||||
|
||||
* parser.c (cp_parser_array_notation): Removed rejection array notation
|
||||
of type function pointers. Added handling of array expressions when
|
||||
Cilk Plus is enabled. Took out type-checking.
|
||||
(cp_parser_postfix_open_square_expression): Moved normal array expr.
|
||||
parsing into cp_parser_array_notation when cilkplus is enabled.
|
||||
(cp_parser_compound_statement): Removed expansion of array notations.
|
||||
(cp_parser_ctor_initializer_opt_and_function_body): Likewise.
|
||||
(cp_parser_function_definition_after_declarator): Likewise.
|
||||
(cp_parser_selection_statement): Removed error reporting.
|
||||
(cp_parser_iteration_statement): Likewise.
|
||||
(cp_parser_direct_declarator): Removed error checking/reporting if
|
||||
array notations are used in the declarator.
|
||||
* pt.c (instantiate_decl): Likewise.
|
||||
(type_unification_real): Removed a check for ARRAY_NOTATION_REF.
|
||||
(cxx_eval_constant_expression): Removed ARRAY_NOTATION_REF case.
|
||||
(potential_constant_expression_1): Returned false for
|
||||
ARRAY_NOTATION_REF case.
|
||||
* cp-gimplify.c (cp_genericize): Added expansion of array notation
|
||||
expressions here.
|
||||
* cp-array-notation.c (make_triplet_val_inv): Removed loc and cry
|
||||
parameters. Replaced build_decls with get_temp_regvar with type as
|
||||
ptrdiff.
|
||||
(create_array_refs): Made the type-casting to ptrdiff_type.
|
||||
(replace_invariant_var): Added a check for void return type before
|
||||
creating new var. Replaced build_decl and build_min_nt_loc with
|
||||
get_temp_regvar.
|
||||
(expand_an_in_modify_expr): Ditto. Replaced body of redundant else
|
||||
with gcc_unreachable. Removed few unwanted checks. Made induction
|
||||
variable type as ptrdiff_type. Removed loc and complain arguments
|
||||
passed into make_triplet_val_inv. Replaced all modify expression's
|
||||
code from NOP EXPR to INIT EXPR. Replaced all forceful appending
|
||||
into stmt. list with the non-forceful one. Replaced some integer
|
||||
conversion and equality-checking to using tree_int_cst_equal.
|
||||
(expand_sec_reduce_builtin): All changes mentioned in above function
|
||||
expand_an_in_modify_expr. Made the new variable type of
|
||||
SEC_REDUCE_ANY/ALL_{NON}ZERO intrinsic functions as bool.
|
||||
(expand_array_notation_exprs): Removed SWITCH_EXPR case. Moved all
|
||||
the error reporting from parser to this function. Removed unwanted
|
||||
statements and checks from SWITCH_STMT, WHILE_STMT, and DO_STMT cases.
|
||||
(cilkplus_an_triplet_types_ok_p): Removed rejection of array notation
|
||||
in function pointers.
|
||||
(cp_expand_cond_array_notations): Added a new if statements to check
|
||||
if condition has a zero rank. If so, then just return.
|
||||
(expand_return_expr): Added a check for return expressions with a rank.
|
||||
Replaced get_tmp_regvar with a create_temporary_var.
|
||||
(build_array_notation_ref): Simplified and removed unwanted if-stmts.
|
||||
Moved common code outside if-statements. Moved type-checking from
|
||||
parser to here.
|
||||
* semantics.c (finish_return_stmt): Removed a check for return exprs.
|
||||
with a rank.
|
||||
* call.c (convert_like_real): Removed a check for array notation
|
||||
expression in a function.
|
||||
(build_over_call): Likewise.
|
||||
(magic_varargs_p): Added a check for builtin array notation function.
|
||||
Made this function non-static and removed its prototype.
|
||||
* cp-tree.h (magic_varargs_p): New prototype.
|
||||
* typeck.c (cp_build_function_call_vec): Removed automatic setting of
|
||||
nargs to the param->length when builtin reduction function is used.
|
||||
(convert_arguments): Replaced check for a constant_p function with
|
||||
margic_varargs_p function call.
|
||||
(cp_build_binary_op): Removed calling of the function
|
||||
find_correct_array_notation_type.
|
||||
(cp_build_addr_expr_1): Removed an unwanted if-statement.
|
||||
(convert_for_assignment): Removed automatic return of rhs when array
|
||||
notation builtin function is used.
|
||||
|
||||
2013-06-28 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
PR c++/57682
|
||||
|
|
|
@ -216,7 +216,6 @@ static void add_candidates (tree, tree, const vec<tree, va_gc> *, tree, tree,
|
|||
bool, tree, tree, int, struct z_candidate **,
|
||||
tsubst_flags_t);
|
||||
static conversion *merge_conversion_sequences (conversion *, conversion *);
|
||||
static bool magic_varargs_p (tree);
|
||||
static tree build_temp (tree, tree, int, diagnostic_t *, tsubst_flags_t);
|
||||
|
||||
/* Returns nonzero iff the destructor name specified in NAME matches BASETYPE.
|
||||
|
@ -5857,16 +5856,9 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
|
|||
else if (t->kind == ck_identity)
|
||||
break;
|
||||
}
|
||||
|
||||
if (flag_enable_cilkplus
|
||||
&& (contains_array_notation_expr (expr)
|
||||
|| contains_array_notation_expr (fn)))
|
||||
/* If we are using array notations, we fix them up at a later stage
|
||||
and we will do these checks then. */
|
||||
;
|
||||
else if (permerror (loc, "invalid conversion from %qT to %qT",
|
||||
TREE_TYPE (expr), totype)
|
||||
&& fn)
|
||||
if (permerror (loc, "invalid conversion from %qT to %qT",
|
||||
TREE_TYPE (expr), totype)
|
||||
&& fn)
|
||||
inform (DECL_SOURCE_LOCATION (fn),
|
||||
"initializing argument %P of %qD", argnum, fn);
|
||||
|
||||
|
@ -6515,9 +6507,12 @@ convert_for_arg_passing (tree type, tree val, tsubst_flags_t complain)
|
|||
which no conversions at all should be done. This is true for some
|
||||
builtins which don't act like normal functions. */
|
||||
|
||||
static bool
|
||||
bool
|
||||
magic_varargs_p (tree fn)
|
||||
{
|
||||
if (flag_enable_cilkplus && is_cilkplus_reduce_builtin (fn) != BUILT_IN_NONE)
|
||||
return true;
|
||||
|
||||
if (DECL_BUILT_IN (fn))
|
||||
switch (DECL_FUNCTION_CODE (fn))
|
||||
{
|
||||
|
@ -6895,21 +6890,13 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
|
|||
" (you can disable this with -fno-deduce-init-list)");
|
||||
}
|
||||
}
|
||||
val = convert_like_with_context (conv, arg, fn, i - is_method,
|
||||
conversion_warning
|
||||
? complain
|
||||
: complain & (~tf_warning));
|
||||
|
||||
/* If the function call is builtin array notation function then no need
|
||||
to do any type conversion. */
|
||||
if (flag_enable_cilkplus
|
||||
&& is_cilkplus_reduce_builtin (fn) != BUILT_IN_NONE)
|
||||
val = arg;
|
||||
else
|
||||
{
|
||||
val = convert_like_with_context (conv, arg, fn, i - is_method,
|
||||
conversion_warning
|
||||
? complain
|
||||
: complain & (~tf_warning));
|
||||
|
||||
val = convert_for_arg_passing (type, val, complain);
|
||||
}
|
||||
val = convert_for_arg_passing (type, val, complain);
|
||||
|
||||
if (val == error_mark_node)
|
||||
return error_mark_node;
|
||||
else
|
||||
|
|
|
@ -59,7 +59,6 @@
|
|||
#include "diagnostic.h"
|
||||
#include "tree-iterator.h"
|
||||
#include "vec.h"
|
||||
#include "gimple.h"
|
||||
|
||||
/* Creates a FOR_STMT with INIT, COND, INCR and BODY as the initializer,
|
||||
condition, increment expression and the loop-body, respectively. */
|
||||
|
@ -82,17 +81,12 @@ create_an_loop (tree init, tree cond, tree incr, tree body)
|
|||
a variable to make it loop invariant for array notations. */
|
||||
|
||||
static inline void
|
||||
make_triplet_val_inv (location_t loc, tree *value, tsubst_flags_t cry)
|
||||
make_triplet_val_inv (tree *value)
|
||||
{
|
||||
tree var;
|
||||
if (TREE_CODE (*value) != INTEGER_CST
|
||||
&& TREE_CODE (*value) != PARM_DECL
|
||||
&& TREE_CODE (*value) != VAR_DECL)
|
||||
{
|
||||
var = build_decl (loc, VAR_DECL, NULL_TREE, integer_type_node);
|
||||
finish_expr_stmt (build_x_modify_expr (loc, var, NOP_EXPR, *value, cry));
|
||||
*value = var;
|
||||
}
|
||||
*value = get_temp_regvar (ptrdiff_type_node, *value);
|
||||
}
|
||||
|
||||
/* Returns a vector of size RANK that contains an ARRAY_REF. This vector is
|
||||
|
@ -112,47 +106,22 @@ create_array_refs (location_t loc, vec<vec<an_parts> > an_info,
|
|||
{
|
||||
tree ind_mult, ind_incr;
|
||||
vec<tree, va_gc> *array_operand = NULL;
|
||||
|
||||
for (size_t ii = 0; ii < size; ii++)
|
||||
if (an_info[ii][0].is_vector)
|
||||
{
|
||||
tree array_opr = an_info[ii][rank - 1].value;
|
||||
for (int s_jj = rank -1; s_jj >= 0; s_jj--)
|
||||
{
|
||||
tree str = NULL_TREE, v = NULL_TREE, st = NULL_TREE;
|
||||
tree start = an_info[ii][s_jj].start;
|
||||
tree stride = an_info[ii][s_jj].stride;
|
||||
tree var = an_loop_info[s_jj].var;
|
||||
tree start = cp_fold_convert (ptrdiff_type_node,
|
||||
an_info[ii][s_jj].start);
|
||||
tree stride = cp_fold_convert (ptrdiff_type_node,
|
||||
an_info[ii][s_jj].stride);
|
||||
tree var = cp_fold_convert (ptrdiff_type_node,
|
||||
an_loop_info[s_jj].var);
|
||||
|
||||
/* If stride and start are of same type and the induction var
|
||||
is not, convert induction variable to stride's type. */
|
||||
if (TREE_TYPE (start) == TREE_TYPE (stride)
|
||||
&& TREE_TYPE (stride) != TREE_TYPE (var))
|
||||
{
|
||||
st = start;
|
||||
str = stride;
|
||||
v = build_c_cast (loc, TREE_TYPE (str), var);
|
||||
}
|
||||
else if (TREE_TYPE (start) != TREE_TYPE (stride))
|
||||
{
|
||||
/* If we reach here, then the stride and start are of
|
||||
different types, and so it doesn't really matter what
|
||||
the induction variable type is, convert everything to
|
||||
integer. The reason why we pick an integer
|
||||
instead of something like size_t is because the stride
|
||||
and length can be + or -. */
|
||||
st = build_c_cast (loc, integer_type_node, start);
|
||||
str = build_c_cast (loc, integer_type_node, stride);
|
||||
v = build_c_cast (loc, integer_type_node, var);
|
||||
}
|
||||
else
|
||||
{
|
||||
st = start;
|
||||
str = stride;
|
||||
v = var;
|
||||
}
|
||||
|
||||
ind_mult = build2 (MULT_EXPR, TREE_TYPE (v), v, str);
|
||||
ind_incr = build2 (PLUS_EXPR, TREE_TYPE (v), st, ind_mult);
|
||||
ind_mult = build2 (MULT_EXPR, TREE_TYPE (var), var, stride);
|
||||
ind_incr = build2 (PLUS_EXPR, TREE_TYPE (var), start, ind_mult);
|
||||
/* Array [ start_index + (induction_var * stride)] */
|
||||
array_opr = grok_array_decl (loc, array_opr, ind_incr, false);
|
||||
}
|
||||
|
@ -192,7 +161,7 @@ replace_invariant_exprs (tree *node)
|
|||
{
|
||||
size_t ix = 0;
|
||||
tree node_list = NULL_TREE;
|
||||
tree t = NULL_TREE, new_var = NULL_TREE, new_node;
|
||||
tree t = NULL_TREE, new_var = NULL_TREE;
|
||||
struct inv_list data;
|
||||
|
||||
data.list_values = NULL;
|
||||
|
@ -204,17 +173,18 @@ replace_invariant_exprs (tree *node)
|
|||
{
|
||||
node_list = push_stmt_list ();
|
||||
for (ix = 0; vec_safe_iterate (data.list_values, ix, &t); ix++)
|
||||
{
|
||||
if (processing_template_decl || !TREE_TYPE (t))
|
||||
new_var = build_min_nt_loc (EXPR_LOCATION (t), VAR_DECL, NULL_TREE,
|
||||
NULL_TREE);
|
||||
else
|
||||
new_var = build_decl (EXPR_LOCATION (t), VAR_DECL, NULL_TREE,
|
||||
TREE_TYPE (t));
|
||||
gcc_assert (new_var != NULL_TREE && new_var != error_mark_node);
|
||||
new_node = build_x_modify_expr (EXPR_LOCATION (t), new_var, NOP_EXPR,
|
||||
t, tf_warning_or_error);
|
||||
finish_expr_stmt (new_node);
|
||||
{
|
||||
/* Sometimes, when comma_expr has a function call in it, it will
|
||||
typecast it to void. Find_inv_trees finds those nodes and so
|
||||
if it void type, then don't bother creating a new var to hold
|
||||
the return value. */
|
||||
if (VOID_TYPE_P (TREE_TYPE (t)))
|
||||
{
|
||||
finish_expr_stmt (t);
|
||||
new_var = void_zero_node;
|
||||
}
|
||||
else
|
||||
new_var = get_temp_regvar (TREE_TYPE (t), t);
|
||||
vec_safe_push (data.replacement, new_var);
|
||||
}
|
||||
cp_walk_tree (node, replace_inv_trees, (void *) &data, NULL);
|
||||
|
@ -235,7 +205,6 @@ expand_sec_reduce_builtin (tree an_builtin_fn, tree *new_var)
|
|||
tree new_var_type = NULL_TREE, func_parm, new_yes_expr, new_no_expr;
|
||||
tree array_ind_value = NULL_TREE, new_no_ind, new_yes_ind, new_no_list;
|
||||
tree new_yes_list, new_cond_expr, new_expr = NULL_TREE;
|
||||
tree new_var_init = NULL_TREE, new_exp_init = NULL_TREE;
|
||||
vec<tree, va_gc> *array_list = NULL, *array_operand = NULL;
|
||||
size_t list_size = 0, rank = 0, ii = 0;
|
||||
tree body, an_init, loop_with_init = alloc_stmt_list ();
|
||||
|
@ -305,7 +274,7 @@ expand_sec_reduce_builtin (tree an_builtin_fn, tree *new_var)
|
|||
case BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_ZERO:
|
||||
case BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_NONZERO:
|
||||
case BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_NONZERO:
|
||||
new_var_type = integer_type_node;
|
||||
new_var_type = boolean_type_node;
|
||||
break;
|
||||
case BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND:
|
||||
case BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND:
|
||||
|
@ -334,24 +303,30 @@ expand_sec_reduce_builtin (tree an_builtin_fn, tree *new_var)
|
|||
if (TREE_CODE ((*array_list)[ii]) == ARRAY_NOTATION_REF)
|
||||
{
|
||||
tree anode = (*array_list)[ii];
|
||||
make_triplet_val_inv (location, &ARRAY_NOTATION_START (anode),
|
||||
tf_warning_or_error);
|
||||
make_triplet_val_inv (location, &ARRAY_NOTATION_LENGTH (anode),
|
||||
tf_warning_or_error);
|
||||
make_triplet_val_inv (location, &ARRAY_NOTATION_STRIDE (anode),
|
||||
tf_warning_or_error);
|
||||
make_triplet_val_inv (&ARRAY_NOTATION_START (anode));
|
||||
make_triplet_val_inv (&ARRAY_NOTATION_LENGTH (anode));
|
||||
make_triplet_val_inv (&ARRAY_NOTATION_STRIDE (anode));
|
||||
}
|
||||
cilkplus_extract_an_triplets (array_list, list_size, rank, &an_info);
|
||||
for (ii = 0; ii < rank; ii++)
|
||||
{
|
||||
an_loop_info[ii].var = build_decl (location, VAR_DECL, NULL_TREE,
|
||||
TREE_TYPE (an_info[0][ii].start));
|
||||
an_loop_info[ii].ind_init = build_x_modify_expr
|
||||
(location, an_loop_info[ii].var, NOP_EXPR,
|
||||
build_zero_cst (TREE_TYPE (an_loop_info[ii].var)),
|
||||
tf_warning_or_error);
|
||||
tree typ = ptrdiff_type_node;
|
||||
|
||||
/* In this place, we are using get_temp_regvar instead of
|
||||
create_temporary_var if an_type is SEC_REDUCE_MAX/MIN_IND because
|
||||
the array_ind_value depends on this value being initalized to 0. */
|
||||
if (an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND
|
||||
|| an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND)
|
||||
an_loop_info[ii].var = get_temp_regvar (typ, build_zero_cst (typ));
|
||||
else
|
||||
{
|
||||
an_loop_info[ii].var = create_temporary_var (typ);
|
||||
add_decl_expr (an_loop_info[ii].var);
|
||||
}
|
||||
an_loop_info[ii].ind_init =
|
||||
build_x_modify_expr (location, an_loop_info[ii].var, INIT_EXPR,
|
||||
build_zero_cst (typ), tf_warning_or_error);
|
||||
}
|
||||
|
||||
array_operand = create_array_refs (location, an_info, an_loop_info,
|
||||
list_size, rank);
|
||||
replace_array_notations (&func_parm, true, array_list, array_operand);
|
||||
|
@ -360,26 +335,9 @@ expand_sec_reduce_builtin (tree an_builtin_fn, tree *new_var)
|
|||
TREE_TYPE (func_parm) = TREE_TYPE ((*array_list)[0]);
|
||||
|
||||
create_cmp_incr (location, &an_loop_info, rank, an_info, tf_warning_or_error);
|
||||
if (an_type != BUILT_IN_CILKPLUS_SEC_REDUCE_MUTATING)
|
||||
{
|
||||
if (processing_template_decl)
|
||||
*new_var = build_decl (location, VAR_DECL, NULL_TREE, new_var_type);
|
||||
else
|
||||
*new_var = create_tmp_var (new_var_type, NULL);
|
||||
}
|
||||
else
|
||||
/* We do not require a new variable for mutating. The "identity value"
|
||||
itself is the variable. */
|
||||
*new_var = NULL_TREE;
|
||||
|
||||
if (an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND
|
||||
|| an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND)
|
||||
{
|
||||
array_ind_value = create_tmp_var (TREE_TYPE (func_parm), NULL);
|
||||
gcc_assert (array_ind_value && (array_ind_value != error_mark_node));
|
||||
DECL_INITIAL (array_ind_value) = NULL_TREE;
|
||||
pushdecl (array_ind_value);
|
||||
}
|
||||
|| an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND)
|
||||
array_ind_value = get_temp_regvar (TREE_TYPE (func_parm), func_parm);
|
||||
|
||||
array_op0 = (*array_operand)[0];
|
||||
switch (an_type)
|
||||
|
@ -394,35 +352,36 @@ expand_sec_reduce_builtin (tree an_builtin_fn, tree *new_var)
|
|||
break;
|
||||
case BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_ZERO:
|
||||
case BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_NONZERO:
|
||||
code = (an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_ZERO) ? EQ_EXPR
|
||||
: NE_EXPR;
|
||||
code = ((an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_ZERO) ? EQ_EXPR
|
||||
: NE_EXPR);
|
||||
init = build_zero_cst (new_var_type);
|
||||
cond_init = build_one_cst (new_var_type);
|
||||
comp_node = build_zero_cst (TREE_TYPE (func_parm));
|
||||
break;
|
||||
case BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_ZERO:
|
||||
case BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_NONZERO:
|
||||
code = (an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_ZERO) ? NE_EXPR
|
||||
: EQ_EXPR;
|
||||
code = ((an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_ZERO) ? NE_EXPR
|
||||
: EQ_EXPR);
|
||||
init = build_one_cst (new_var_type);
|
||||
cond_init = build_zero_cst (new_var_type);
|
||||
comp_node = build_zero_cst (TREE_TYPE (func_parm));
|
||||
break;
|
||||
case BUILT_IN_CILKPLUS_SEC_REDUCE_MAX:
|
||||
code = MAX_EXPR;
|
||||
init = TYPE_MIN_VALUE (new_var_type) ? TYPE_MIN_VALUE (new_var_type)
|
||||
: func_parm;
|
||||
init = (TYPE_MIN_VALUE (new_var_type) ? TYPE_MIN_VALUE (new_var_type)
|
||||
: func_parm);
|
||||
break;
|
||||
case BUILT_IN_CILKPLUS_SEC_REDUCE_MIN:
|
||||
code = MIN_EXPR;
|
||||
init = TYPE_MAX_VALUE (new_var_type) ? TYPE_MAX_VALUE (new_var_type)
|
||||
: func_parm;
|
||||
init = (TYPE_MAX_VALUE (new_var_type) ? TYPE_MAX_VALUE (new_var_type)
|
||||
: func_parm);
|
||||
break;
|
||||
case BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND:
|
||||
case BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND:
|
||||
code = an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND ? LE_EXPR
|
||||
: GE_EXPR;
|
||||
code = (an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND ? LE_EXPR
|
||||
: GE_EXPR);
|
||||
init = an_loop_info[0].var;
|
||||
break;
|
||||
case BUILT_IN_CILKPLUS_SEC_REDUCE:
|
||||
init = identity_value;
|
||||
break;
|
||||
|
@ -433,9 +392,11 @@ expand_sec_reduce_builtin (tree an_builtin_fn, tree *new_var)
|
|||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
if (init)
|
||||
new_var_init = build_x_modify_expr (location, *new_var, NOP_EXPR, init,
|
||||
tf_warning_or_error);
|
||||
if (an_type != BUILT_IN_CILKPLUS_SEC_REDUCE_MUTATING)
|
||||
*new_var = get_temp_regvar (new_var_type, init);
|
||||
else
|
||||
*new_var = NULL_TREE;
|
||||
|
||||
switch (an_type)
|
||||
{
|
||||
case BUILT_IN_CILKPLUS_SEC_REDUCE_ADD:
|
||||
|
@ -470,8 +431,6 @@ expand_sec_reduce_builtin (tree an_builtin_fn, tree *new_var)
|
|||
break;
|
||||
case BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND:
|
||||
case BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND:
|
||||
new_exp_init = build_x_modify_expr (location, array_ind_value, NOP_EXPR,
|
||||
func_parm, tf_warning_or_error);
|
||||
new_yes_expr = build_x_modify_expr (location, array_ind_value, NOP_EXPR,
|
||||
func_parm, tf_warning_or_error);
|
||||
new_no_expr = build_x_modify_expr (location, array_ind_value, NOP_EXPR,
|
||||
|
@ -521,21 +480,8 @@ expand_sec_reduce_builtin (tree an_builtin_fn, tree *new_var)
|
|||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
/* The reason we are putting initial variable twice is because the
|
||||
new exp init below depends on this value being initialized. */
|
||||
for (ii = 0; ii < rank; ii++)
|
||||
finish_expr_stmt (an_loop_info[ii].ind_init);
|
||||
|
||||
if (an_type != BUILT_IN_CILKPLUS_SEC_REDUCE_MUTATING)
|
||||
finish_expr_stmt (new_var_init);
|
||||
|
||||
if (an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND
|
||||
|| an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND)
|
||||
finish_expr_stmt (new_exp_init);
|
||||
|
||||
an_init = pop_stmt_list (an_init);
|
||||
append_to_statement_list_force (an_init, &loop_with_init);
|
||||
append_to_statement_list (an_init, &loop_with_init);
|
||||
body = new_expr;
|
||||
|
||||
for (ii = 0; ii < rank; ii++)
|
||||
|
@ -545,7 +491,7 @@ expand_sec_reduce_builtin (tree an_builtin_fn, tree *new_var)
|
|||
an_loop_info[ii].incr, body);
|
||||
body = pop_stmt_list (new_loop);
|
||||
}
|
||||
append_to_statement_list_force (body, &loop_with_init);
|
||||
append_to_statement_list (body, &loop_with_init);
|
||||
|
||||
an_info.release ();
|
||||
an_loop_info.release ();
|
||||
|
@ -634,10 +580,7 @@ expand_an_in_modify_expr (location_t location, tree lhs,
|
|||
return an_init;
|
||||
}
|
||||
else
|
||||
{
|
||||
pop_stmt_list (an_init);
|
||||
return NULL_TREE;
|
||||
}
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
/* If for some reason location is not set, then find if LHS or RHS has
|
||||
|
@ -659,8 +602,6 @@ expand_an_in_modify_expr (location_t location, tree lhs,
|
|||
|
||||
if (lhs_rank == 0 && rhs_rank != 0)
|
||||
{
|
||||
if (location == UNKNOWN_LOCATION && EXPR_HAS_LOCATION (rhs))
|
||||
location = EXPR_LOCATION (rhs);
|
||||
error_at (location, "%qD cannot be scalar when %qD is not", lhs, rhs);
|
||||
return error_mark_node;
|
||||
}
|
||||
|
@ -675,17 +616,17 @@ expand_an_in_modify_expr (location_t location, tree lhs,
|
|||
for (ii = 0; ii < lhs_list_size; ii++)
|
||||
{
|
||||
tree anode = (*lhs_list)[ii];
|
||||
make_triplet_val_inv (location, &ARRAY_NOTATION_START (anode), complain);
|
||||
make_triplet_val_inv (location, &ARRAY_NOTATION_LENGTH (anode), complain);
|
||||
make_triplet_val_inv (location, &ARRAY_NOTATION_STRIDE (anode), complain);
|
||||
make_triplet_val_inv (&ARRAY_NOTATION_START (anode));
|
||||
make_triplet_val_inv (&ARRAY_NOTATION_LENGTH (anode));
|
||||
make_triplet_val_inv (&ARRAY_NOTATION_STRIDE (anode));
|
||||
}
|
||||
for (ii = 0; ii < rhs_list_size; ii++)
|
||||
if ((*rhs_list)[ii] && TREE_CODE ((*rhs_list)[ii]) == ARRAY_NOTATION_REF)
|
||||
{
|
||||
tree aa = (*rhs_list)[ii];
|
||||
make_triplet_val_inv (location, &ARRAY_NOTATION_START (aa), complain);
|
||||
make_triplet_val_inv (location, &ARRAY_NOTATION_LENGTH (aa), complain);
|
||||
make_triplet_val_inv (location, &ARRAY_NOTATION_STRIDE (aa), complain);
|
||||
make_triplet_val_inv (&ARRAY_NOTATION_START (aa));
|
||||
make_triplet_val_inv (&ARRAY_NOTATION_LENGTH (aa));
|
||||
make_triplet_val_inv (&ARRAY_NOTATION_STRIDE (aa));
|
||||
}
|
||||
lhs_an_loop_info.safe_grow_cleared (lhs_rank);
|
||||
|
||||
|
@ -705,31 +646,29 @@ expand_an_in_modify_expr (location_t location, tree lhs,
|
|||
pop_stmt_list (an_init);
|
||||
return error_mark_node;
|
||||
}
|
||||
tree rhs_len = (rhs_list_size > 0 && rhs_rank > 0) ?
|
||||
rhs_an_info[0][0].length : NULL_TREE;
|
||||
tree lhs_len = (lhs_list_size > 0 && lhs_rank > 0) ?
|
||||
lhs_an_info[0][0].length : NULL_TREE;
|
||||
tree rhs_len = ((rhs_list_size > 0 && rhs_rank > 0) ?
|
||||
rhs_an_info[0][0].length : NULL_TREE);
|
||||
tree lhs_len = ((lhs_list_size > 0 && lhs_rank > 0) ?
|
||||
lhs_an_info[0][0].length : NULL_TREE);
|
||||
if (lhs_list_size > 0 && rhs_list_size > 0 && lhs_rank > 0 && rhs_rank > 0
|
||||
&& TREE_CODE (lhs_len) == INTEGER_CST && rhs_len
|
||||
&& TREE_CODE (rhs_len) == INTEGER_CST)
|
||||
{
|
||||
HOST_WIDE_INT l_length = int_cst_value (lhs_len);
|
||||
HOST_WIDE_INT r_length = int_cst_value (rhs_len);
|
||||
if (absu_hwi (l_length) != absu_hwi (r_length))
|
||||
{
|
||||
error_at (location, "length mismatch between LHS and RHS");
|
||||
pop_stmt_list (an_init);
|
||||
return error_mark_node;
|
||||
}
|
||||
&& TREE_CODE (rhs_len) == INTEGER_CST
|
||||
&& !tree_int_cst_equal (rhs_len, lhs_len))
|
||||
{
|
||||
error_at (location, "length mismatch between LHS and RHS");
|
||||
pop_stmt_list (an_init);
|
||||
return error_mark_node;
|
||||
}
|
||||
for (ii = 0; ii < lhs_rank; ii++)
|
||||
if (lhs_an_info[0][ii].start && TREE_TYPE (lhs_an_info[0][ii].start))
|
||||
lhs_an_loop_info[ii].var =
|
||||
build_decl (location, VAR_DECL, NULL_TREE,
|
||||
TREE_TYPE (lhs_an_info[0][ii].start));
|
||||
else
|
||||
lhs_an_loop_info[ii].var = build_decl (location, VAR_DECL, NULL_TREE,
|
||||
integer_type_node);
|
||||
for (ii = 0; ii < lhs_rank; ii++)
|
||||
{
|
||||
tree typ = ptrdiff_type_node;
|
||||
lhs_an_loop_info[ii].var = create_temporary_var (typ);
|
||||
add_decl_expr (lhs_an_loop_info[ii].var);
|
||||
lhs_an_loop_info[ii].ind_init = build_x_modify_expr
|
||||
(location, lhs_an_loop_info[ii].var, INIT_EXPR, build_zero_cst (typ),
|
||||
complain);
|
||||
}
|
||||
|
||||
if (rhs_list_size > 0)
|
||||
{
|
||||
rhs_array_operand = fix_sec_implicit_args (location, rhs_list,
|
||||
|
@ -743,24 +682,15 @@ expand_an_in_modify_expr (location_t location, tree lhs,
|
|||
rhs_list = NULL;
|
||||
extract_array_notation_exprs (rhs, true, &rhs_list);
|
||||
rhs_list_size = vec_safe_length (rhs_list);
|
||||
|
||||
for (ii = 0; ii < lhs_rank; ii++)
|
||||
if (lhs_an_info[0][ii].is_vector)
|
||||
{
|
||||
lhs_an_loop_info[ii].ind_init = build_x_modify_expr
|
||||
(location, lhs_an_loop_info[ii].var, NOP_EXPR,
|
||||
build_zero_cst (TREE_TYPE (lhs_an_loop_info[ii].var)), complain);
|
||||
}
|
||||
|
||||
for (ii = 0; ii < rhs_rank; ii++)
|
||||
{
|
||||
/* When we have a polynomial, we assume that the indices are of type
|
||||
integer. */
|
||||
rhs_an_loop_info[ii].var =
|
||||
build_decl (location, VAR_DECL, NULL_TREE,
|
||||
TREE_TYPE (rhs_an_info[0][ii].start));
|
||||
tree typ = ptrdiff_type_node;
|
||||
rhs_an_loop_info[ii].var = create_temporary_var (typ);
|
||||
add_decl_expr (rhs_an_loop_info[ii].var);
|
||||
rhs_an_loop_info[ii].ind_init = build_x_modify_expr
|
||||
(location, rhs_an_loop_info[ii].var, NOP_EXPR,
|
||||
build_zero_cst (TREE_TYPE (rhs_an_loop_info[ii].var)), complain);
|
||||
(location, rhs_an_loop_info[ii].var, INIT_EXPR, build_zero_cst (typ),
|
||||
complain);
|
||||
}
|
||||
|
||||
if (lhs_rank)
|
||||
|
@ -809,12 +739,12 @@ expand_an_in_modify_expr (location_t location, tree lhs,
|
|||
else if (ii < lhs_rank && ii >= rhs_rank)
|
||||
cond_expr[ii] = lhs_an_loop_info[ii].cmp;
|
||||
else
|
||||
/* No need to compare ii < rhs_rank && ii >= lhs_rank because valid Array
|
||||
notation expression cannot RHS's rank cannot be greater than LHS. */
|
||||
/* No need to compare ii < rhs_rank && ii >= lhs_rank because in a valid
|
||||
Array notation expression, rank of RHS cannot be greater than LHS. */
|
||||
gcc_unreachable ();
|
||||
|
||||
an_init = pop_stmt_list (an_init);
|
||||
append_to_statement_list_force (an_init, &loop_with_init);
|
||||
append_to_statement_list (an_init, &loop_with_init);
|
||||
body = array_expr;
|
||||
for (ii = 0; ii < MAX (lhs_rank, rhs_rank); ii++)
|
||||
{
|
||||
|
@ -824,17 +754,13 @@ expand_an_in_modify_expr (location_t location, tree lhs,
|
|||
|
||||
if (lhs_rank)
|
||||
{
|
||||
append_to_statement_list_force (lhs_an_loop_info[ii].ind_init,
|
||||
&init_list);
|
||||
append_to_statement_list_force (lhs_an_loop_info[ii].incr,
|
||||
&incr_list);
|
||||
append_to_statement_list (lhs_an_loop_info[ii].ind_init, &init_list);
|
||||
append_to_statement_list (lhs_an_loop_info[ii].incr, &incr_list);
|
||||
}
|
||||
if (rhs_rank)
|
||||
{
|
||||
append_to_statement_list_force (rhs_an_loop_info[ii].ind_init,
|
||||
&init_list);
|
||||
append_to_statement_list_force (rhs_an_loop_info[ii].incr,
|
||||
&incr_list);
|
||||
append_to_statement_list (rhs_an_loop_info[ii].ind_init, &init_list);
|
||||
append_to_statement_list (rhs_an_loop_info[ii].incr, &incr_list);
|
||||
}
|
||||
create_an_loop (init_list, cond_expr[ii], incr_list, body);
|
||||
body = pop_stmt_list (new_loop);
|
||||
|
@ -867,7 +793,6 @@ cp_expand_cond_array_notations (tree orig_stmt)
|
|||
tree an_init, body, stmt = NULL_TREE;
|
||||
tree builtin_loop, new_var = NULL_TREE;
|
||||
tree loop_with_init = alloc_stmt_list ();
|
||||
tsubst_flags_t complain = tf_warning_or_error;
|
||||
location_t location = UNKNOWN_LOCATION;
|
||||
vec<vec<an_parts> > an_info = vNULL;
|
||||
vec<an_loop_parts> an_loop_info = vNULL;
|
||||
|
@ -884,13 +809,17 @@ cp_expand_cond_array_notations (tree orig_stmt)
|
|||
|| find_rank (EXPR_LOCATION (no_expr), no_expr, no_expr, true,
|
||||
&no_rank))
|
||||
return error_mark_node;
|
||||
if (cond_rank != 0 && cond_rank != yes_rank && yes_rank != 0)
|
||||
/* If the condition has a zero rank, then handle array notations in body
|
||||
seperately. */
|
||||
if (cond_rank == 0)
|
||||
return orig_stmt;
|
||||
if (cond_rank != yes_rank && yes_rank != 0)
|
||||
{
|
||||
error_at (EXPR_LOCATION (yes_expr), "rank mismatch with controlling"
|
||||
" expression of parent if-statement");
|
||||
return error_mark_node;
|
||||
}
|
||||
else if (cond_rank != 0 && cond_rank != no_rank && no_rank != 0)
|
||||
else if (cond_rank != no_rank && no_rank != 0)
|
||||
{
|
||||
error_at (EXPR_LOCATION (no_expr), "rank mismatch with controlling "
|
||||
"expression of parent if-statement");
|
||||
|
@ -911,13 +840,17 @@ cp_expand_cond_array_notations (tree orig_stmt)
|
|||
&& !find_rank (EXPR_LOCATION (no_expr), no_expr, no_expr, true,
|
||||
&no_rank)))
|
||||
return error_mark_node;
|
||||
if (cond_rank != 0 && cond_rank != yes_rank && yes_rank != 0)
|
||||
|
||||
/* Same reasoning as for COND_EXPR. */
|
||||
if (cond_rank == 0)
|
||||
return orig_stmt;
|
||||
else if (cond_rank != yes_rank && yes_rank != 0)
|
||||
{
|
||||
error_at (EXPR_LOCATION (yes_expr), "rank mismatch with controlling"
|
||||
" expression of parent if-statement");
|
||||
return error_mark_node;
|
||||
}
|
||||
else if (cond_rank != 0 && cond_rank != no_rank && no_rank != 0)
|
||||
else if (cond_rank != no_rank && no_rank != 0)
|
||||
{
|
||||
error_at (EXPR_LOCATION (no_expr), "rank mismatch with controlling "
|
||||
"expression of parent if-statement");
|
||||
|
@ -949,11 +882,11 @@ cp_expand_cond_array_notations (tree orig_stmt)
|
|||
vec_safe_push (new_var_list, new_var);
|
||||
replace_array_notations (&orig_stmt, false, sub_list,
|
||||
new_var_list);
|
||||
append_to_statement_list_force (builtin_loop, &stmt);
|
||||
append_to_statement_list (builtin_loop, &stmt);
|
||||
}
|
||||
}
|
||||
}
|
||||
append_to_statement_list_force (orig_stmt, &stmt);
|
||||
append_to_statement_list (orig_stmt, &stmt);
|
||||
rank = 0;
|
||||
array_list = NULL;
|
||||
if (!find_rank (EXPR_LOCATION (stmt), stmt, stmt, true, &rank))
|
||||
|
@ -977,37 +910,28 @@ cp_expand_cond_array_notations (tree orig_stmt)
|
|||
for (ii = 0; ii < list_size; ii++)
|
||||
{
|
||||
tree anode = (*array_list)[ii];
|
||||
make_triplet_val_inv (location, &ARRAY_NOTATION_START (anode), complain);
|
||||
make_triplet_val_inv (location, &ARRAY_NOTATION_LENGTH (anode), complain);
|
||||
make_triplet_val_inv (location, &ARRAY_NOTATION_STRIDE (anode), complain);
|
||||
make_triplet_val_inv (&ARRAY_NOTATION_START (anode));
|
||||
make_triplet_val_inv (&ARRAY_NOTATION_LENGTH (anode));
|
||||
make_triplet_val_inv (&ARRAY_NOTATION_STRIDE (anode));
|
||||
}
|
||||
cilkplus_extract_an_triplets (array_list, list_size, rank, &an_info);
|
||||
for (ii = 0; ii < rank; ii++)
|
||||
if (TREE_TYPE (an_info[0][ii].start)
|
||||
&& TREE_CODE (TREE_TYPE (an_info[0][ii].start)) != TEMPLATE_TYPE_PARM)
|
||||
{
|
||||
an_loop_info[ii].var = build_decl (location, VAR_DECL, NULL_TREE,
|
||||
TREE_TYPE (an_info[0][ii].start));
|
||||
an_loop_info[ii].ind_init = build_x_modify_expr
|
||||
(location, an_loop_info[ii].var, NOP_EXPR,
|
||||
build_zero_cst (TREE_TYPE (an_loop_info[ii].var)),
|
||||
tf_warning_or_error);
|
||||
}
|
||||
else
|
||||
{
|
||||
an_loop_info[ii].var = build_min_nt_loc (location, VAR_DECL,
|
||||
NULL_TREE, NULL_TREE);
|
||||
an_loop_info[ii].ind_init =
|
||||
build_x_modify_expr (location, an_loop_info[ii].var, NOP_EXPR,
|
||||
integer_zero_node, tf_warning_or_error);
|
||||
}
|
||||
|
||||
for (ii = 0; ii < rank; ii++)
|
||||
{
|
||||
tree typ = ptrdiff_type_node;
|
||||
an_loop_info[ii].var = create_temporary_var (typ);
|
||||
add_decl_expr (an_loop_info[ii].var);
|
||||
an_loop_info[ii].ind_init =
|
||||
build_x_modify_expr (location, an_loop_info[ii].var, INIT_EXPR,
|
||||
build_zero_cst (typ), tf_warning_or_error);
|
||||
}
|
||||
array_operand = create_array_refs (location, an_info, an_loop_info,
|
||||
list_size, rank);
|
||||
replace_array_notations (&stmt, true, array_list, array_operand);
|
||||
create_cmp_incr (location, &an_loop_info, rank, an_info, tf_warning_or_error);
|
||||
|
||||
an_init = pop_stmt_list (an_init);
|
||||
append_to_statement_list_force (an_init, &loop_with_init);
|
||||
append_to_statement_list (an_init, &loop_with_init);
|
||||
body = stmt;
|
||||
|
||||
for (ii = 0; ii < rank; ii++)
|
||||
|
@ -1017,7 +941,7 @@ cp_expand_cond_array_notations (tree orig_stmt)
|
|||
an_loop_info[ii].incr, body);
|
||||
body = pop_stmt_list (new_loop);
|
||||
}
|
||||
append_to_statement_list_force (body, &loop_with_init);
|
||||
append_to_statement_list (body, &loop_with_init);
|
||||
|
||||
an_info.release ();
|
||||
an_loop_info.release ();
|
||||
|
@ -1062,14 +986,14 @@ expand_unary_array_notation_exprs (tree orig_stmt)
|
|||
{
|
||||
vec<tree, va_gc> *sub_list = NULL, *new_var_list = NULL;
|
||||
stmt = alloc_stmt_list ();
|
||||
append_to_statement_list_force (builtin_loop, &stmt);
|
||||
append_to_statement_list (builtin_loop, &stmt);
|
||||
vec_safe_push (sub_list, list_node);
|
||||
vec_safe_push (new_var_list, new_var);
|
||||
replace_array_notations (&orig_stmt, false, sub_list, new_var_list);
|
||||
}
|
||||
}
|
||||
if (stmt != NULL_TREE)
|
||||
append_to_statement_list_force (finish_expr_stmt (orig_stmt), &stmt);
|
||||
append_to_statement_list (finish_expr_stmt (orig_stmt), &stmt);
|
||||
else
|
||||
stmt = orig_stmt;
|
||||
rank = 0;
|
||||
|
@ -1089,22 +1013,19 @@ expand_unary_array_notation_exprs (tree orig_stmt)
|
|||
for (ii = 0; ii < list_size; ii++)
|
||||
{
|
||||
tree array_node = (*array_list)[ii];
|
||||
make_triplet_val_inv (location, &ARRAY_NOTATION_START (array_node),
|
||||
tf_warning_or_error);
|
||||
make_triplet_val_inv (location, &ARRAY_NOTATION_LENGTH (array_node),
|
||||
tf_warning_or_error);
|
||||
make_triplet_val_inv (location, &ARRAY_NOTATION_STRIDE (array_node),
|
||||
tf_warning_or_error);
|
||||
make_triplet_val_inv (&ARRAY_NOTATION_START (array_node));
|
||||
make_triplet_val_inv (&ARRAY_NOTATION_LENGTH (array_node));
|
||||
make_triplet_val_inv (&ARRAY_NOTATION_STRIDE (array_node));
|
||||
}
|
||||
cilkplus_extract_an_triplets (array_list, list_size, rank, &an_info);
|
||||
|
||||
for (ii = 0; ii < rank; ii++)
|
||||
{
|
||||
an_loop_info[ii].var = build_decl (location, VAR_DECL, NULL_TREE,
|
||||
TREE_TYPE (an_info[0][ii].start));
|
||||
tree typ = ptrdiff_type_node;
|
||||
an_loop_info[ii].var = create_temporary_var (typ);
|
||||
add_decl_expr (an_loop_info[ii].var);
|
||||
an_loop_info[ii].ind_init = build_x_modify_expr
|
||||
(location, an_loop_info[ii].var, NOP_EXPR,
|
||||
build_zero_cst (TREE_TYPE (an_loop_info[ii].var)),
|
||||
(location, an_loop_info[ii].var, INIT_EXPR, build_zero_cst (typ),
|
||||
tf_warning_or_error);
|
||||
}
|
||||
array_operand = create_array_refs (location, an_info, an_loop_info,
|
||||
|
@ -1113,7 +1034,7 @@ expand_unary_array_notation_exprs (tree orig_stmt)
|
|||
create_cmp_incr (location, &an_loop_info, rank, an_info, tf_warning_or_error);
|
||||
|
||||
an_init = pop_stmt_list (an_init);
|
||||
append_to_statement_list_force (an_init, &loop_with_init);
|
||||
append_to_statement_list (an_init, &loop_with_init);
|
||||
body = stmt;
|
||||
|
||||
for (ii = 0; ii < rank; ii++)
|
||||
|
@ -1123,7 +1044,7 @@ expand_unary_array_notation_exprs (tree orig_stmt)
|
|||
an_loop_info[ii].incr, body);
|
||||
body = pop_stmt_list (new_loop);
|
||||
}
|
||||
append_to_statement_list_force (body, &loop_with_init);
|
||||
append_to_statement_list (body, &loop_with_init);
|
||||
|
||||
an_info.release ();
|
||||
an_loop_info.release ();
|
||||
|
@ -1139,21 +1060,35 @@ static tree
|
|||
expand_return_expr (tree expr)
|
||||
{
|
||||
tree new_mod_list, new_var, new_mod, retval_expr;
|
||||
|
||||
size_t rank = 0;
|
||||
location_t loc = EXPR_LOCATION (expr);
|
||||
if (TREE_CODE (expr) != RETURN_EXPR)
|
||||
return expr;
|
||||
|
||||
if (!find_rank (loc, expr, expr, false, &rank))
|
||||
return error_mark_node;
|
||||
|
||||
location_t loc = EXPR_LOCATION (expr);
|
||||
new_mod_list = alloc_stmt_list ();
|
||||
/* If the return expression contains array notations, then flag it as
|
||||
error. */
|
||||
if (rank >= 1)
|
||||
{
|
||||
error_at (loc, "array notation expression cannot be used as a return "
|
||||
"value");
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
new_mod_list = push_stmt_list ();
|
||||
retval_expr = TREE_OPERAND (expr, 0);
|
||||
new_var = build_decl (loc, VAR_DECL, NULL_TREE, TREE_TYPE (retval_expr));
|
||||
new_var = create_temporary_var (TREE_TYPE (retval_expr));
|
||||
add_decl_expr (new_var);
|
||||
new_mod = expand_an_in_modify_expr (loc, new_var, NOP_EXPR,
|
||||
TREE_OPERAND (retval_expr, 1),
|
||||
tf_warning_or_error);
|
||||
TREE_OPERAND (retval_expr, 1),
|
||||
tf_warning_or_error);
|
||||
TREE_OPERAND (retval_expr, 1) = new_var;
|
||||
TREE_OPERAND (expr, 0) = retval_expr;
|
||||
append_to_statement_list_force (new_mod, &new_mod_list);
|
||||
append_to_statement_list_force (expr, &new_mod_list);
|
||||
add_stmt (new_mod);
|
||||
add_stmt (expr);
|
||||
new_mod_list = pop_stmt_list (new_mod_list);
|
||||
return new_mod_list;
|
||||
}
|
||||
|
||||
|
@ -1290,19 +1225,21 @@ expand_array_notation_exprs (tree t)
|
|||
else
|
||||
t = expand_array_notation_exprs (t);
|
||||
return t;
|
||||
|
||||
case SWITCH_EXPR:
|
||||
t = cp_expand_cond_array_notations (t);
|
||||
if (TREE_CODE (t) == SWITCH_EXPR)
|
||||
SWITCH_BODY (t) = expand_array_notation_exprs (SWITCH_BODY (t));
|
||||
else
|
||||
t = expand_array_notation_exprs (t);
|
||||
return t;
|
||||
case FOR_STMT:
|
||||
case FOR_STMT:
|
||||
if (contains_array_notation_expr (FOR_COND (t)))
|
||||
{
|
||||
error_at (EXPR_LOCATION (FOR_COND (t)),
|
||||
"array notation cannot be used in a condition for "
|
||||
"a for-loop");
|
||||
return error_mark_node;
|
||||
}
|
||||
/* FIXME: Add a check for CILK_FOR_STMT here when we add Cilk tasking
|
||||
keywords. */
|
||||
if (TREE_CODE (t) == FOR_STMT)
|
||||
FOR_BODY (t) = expand_array_notation_exprs (FOR_BODY (t));
|
||||
{
|
||||
FOR_BODY (t) = expand_array_notation_exprs (FOR_BODY (t));
|
||||
FOR_EXPR (t) = expand_array_notation_exprs (FOR_EXPR (t));
|
||||
}
|
||||
else
|
||||
t = expand_array_notation_exprs (t);
|
||||
return t;
|
||||
|
@ -1322,44 +1259,39 @@ expand_array_notation_exprs (tree t)
|
|||
t = expand_array_notation_exprs (t);
|
||||
return t;
|
||||
case SWITCH_STMT:
|
||||
t = cp_expand_cond_array_notations (t);
|
||||
/* If the above function added some extra instructions above the original
|
||||
switch statement, then we can't assume it is still SWITCH_STMT so we
|
||||
have to check again. */
|
||||
if (TREE_CODE (t) == SWITCH_STMT)
|
||||
if (contains_array_notation_expr (SWITCH_STMT_COND (t)))
|
||||
{
|
||||
if (SWITCH_STMT_BODY (t))
|
||||
SWITCH_STMT_BODY (t) =
|
||||
expand_array_notation_exprs (SWITCH_STMT_BODY (t));
|
||||
error_at (EXPR_LOCATION (SWITCH_STMT_COND (t)),
|
||||
"array notation cannot be used as a condition for "
|
||||
"switch statement");
|
||||
return error_mark_node;
|
||||
}
|
||||
else
|
||||
t = expand_array_notation_exprs (t);
|
||||
if (SWITCH_STMT_BODY (t))
|
||||
SWITCH_STMT_BODY (t) =
|
||||
expand_array_notation_exprs (SWITCH_STMT_BODY (t));
|
||||
return t;
|
||||
case WHILE_STMT:
|
||||
t = cp_expand_cond_array_notations (t);
|
||||
/* If the above function added some extra instructions above the original
|
||||
while statement, then we can't assume it is still WHILE_STMTso we
|
||||
have to check again. */
|
||||
if (TREE_CODE (t) == WHILE_STMT)
|
||||
if (contains_array_notation_expr (WHILE_COND (t)))
|
||||
{
|
||||
if (WHILE_BODY (t))
|
||||
WHILE_BODY (t) = expand_array_notation_exprs (WHILE_BODY (t));
|
||||
if (EXPR_LOCATION (WHILE_COND (t)) != UNKNOWN_LOCATION)
|
||||
loc = EXPR_LOCATION (WHILE_COND (t));
|
||||
error_at (loc, "array notation cannot be used as a condition for "
|
||||
"while statement");
|
||||
return error_mark_node;
|
||||
}
|
||||
else
|
||||
t = expand_array_notation_exprs (t);
|
||||
if (WHILE_BODY (t))
|
||||
WHILE_BODY (t) = expand_array_notation_exprs (WHILE_BODY (t));
|
||||
return t;
|
||||
case DO_STMT:
|
||||
t = cp_expand_cond_array_notations (t);
|
||||
/* If the above function added some extra instructions above the original
|
||||
do-while statement, then we can't assume it is still DO_STMT so we
|
||||
have to check again. */
|
||||
if (TREE_CODE (t) == DO_STMT)
|
||||
{
|
||||
if (DO_BODY (t))
|
||||
DO_BODY (t) = expand_array_notation_exprs (DO_BODY (t));
|
||||
if (contains_array_notation_expr (DO_COND (t)))
|
||||
{
|
||||
error_at (EXPR_LOCATION (DO_COND (t)),
|
||||
"array notation cannot be used as a condition for a "
|
||||
"do-while statement");
|
||||
return error_mark_node;
|
||||
}
|
||||
else
|
||||
t = expand_array_notation_exprs (t);
|
||||
if (DO_BODY (t))
|
||||
DO_BODY (t) = expand_array_notation_exprs (DO_BODY (t));
|
||||
return t;
|
||||
default:
|
||||
if (is_expr)
|
||||
|
@ -1380,59 +1312,66 @@ expand_array_notation_exprs (tree t)
|
|||
return t;
|
||||
}
|
||||
|
||||
/* Given the base of an array (ARRAY), the START_INDEX, the number of elements
|
||||
to be accessed (LENGTH) and the STRIDE, construct an ARRAY_NOTATION_REF tree
|
||||
of type TYPE and return it. Restrictions on START_INDEX, LENGTH and STRIDE
|
||||
are the same as that of index field passed into ARRAY_REF. The only
|
||||
additional restriction is that, unlike index in ARRAY_REF, stride, length
|
||||
and start_index cannot contain array notations. */
|
||||
/* Given the base of an array (ARRAY), the START (start_index), the number of
|
||||
elements to be accessed (LENGTH) and the STRIDE, construct an
|
||||
ARRAY_NOTATION_REF tree of type TYPE and return it. Restrictions on START,
|
||||
LENGTH and STRIDE are the same as that of index field passed into ARRAY_REF.
|
||||
The only additional restriction is that, unlike index in ARRAY_REF, stride,
|
||||
length and start_index cannot contain array notations. */
|
||||
|
||||
tree
|
||||
build_array_notation_ref (location_t loc, tree array, tree start_index,
|
||||
tree length, tree stride, tree type)
|
||||
build_array_notation_ref (location_t loc, tree array, tree start, tree length,
|
||||
tree stride, tree type)
|
||||
{
|
||||
tree array_ntn_expr = NULL_TREE;
|
||||
|
||||
/* If we enter the then-case of the if-statement below, we have hit a case
|
||||
like this: ARRAY [:]. */
|
||||
if (!start && !length)
|
||||
{
|
||||
if (TREE_CODE (type) != ARRAY_TYPE)
|
||||
{
|
||||
error_at (loc, "start-index and length fields necessary for "
|
||||
"using array notation in pointers or records");
|
||||
return error_mark_node;
|
||||
}
|
||||
tree domain = TYPE_DOMAIN (type);
|
||||
if (!domain)
|
||||
{
|
||||
error_at (loc, "start-index and length fields necessary for "
|
||||
"using array notation with array of unknown bound");
|
||||
return error_mark_node;
|
||||
}
|
||||
start = cp_fold_convert (ptrdiff_type_node, TYPE_MINVAL (domain));
|
||||
length = size_binop (PLUS_EXPR, TYPE_MAXVAL (domain), size_one_node);
|
||||
length = cp_fold_convert (ptrdiff_type_node, length);
|
||||
}
|
||||
|
||||
if (!stride)
|
||||
stride = build_one_cst (ptrdiff_type_node);
|
||||
|
||||
/* When dealing with templates, do the type checking at a later time. */
|
||||
if (processing_template_decl || !type)
|
||||
{
|
||||
if (!type && TREE_TYPE (array))
|
||||
type = TREE_TYPE (array);
|
||||
array_ntn_expr = build_min_nt_loc (loc, ARRAY_NOTATION_REF, array,
|
||||
start_index, length, stride, type,
|
||||
NULL_TREE);
|
||||
TREE_TYPE (array_ntn_expr) = type;
|
||||
}
|
||||
if (!stride)
|
||||
{
|
||||
if (TREE_CONSTANT (start_index) && TREE_CONSTANT (length)
|
||||
&& TREE_CODE (start_index) != VAR_DECL
|
||||
&& TREE_CODE (length) != VAR_DECL
|
||||
&& tree_int_cst_lt (length, start_index))
|
||||
stride = build_int_cst (TREE_TYPE (start_index), -1);
|
||||
else
|
||||
stride = build_int_cst (TREE_TYPE (start_index), 1);
|
||||
/* When dealing with templates, triplet type-checking will be done in pt.c
|
||||
after type substitution. */
|
||||
if (processing_template_decl
|
||||
&& (type_dependent_expression_p (array)
|
||||
|| type_dependent_expression_p (length)
|
||||
|| type_dependent_expression_p (start)
|
||||
|| type_dependent_expression_p (stride)))
|
||||
array_ntn_expr = build_min_nt_loc (loc, ARRAY_NOTATION_REF, array, start,
|
||||
length, stride, NULL_TREE);
|
||||
else
|
||||
{
|
||||
if (!cilkplus_an_triplet_types_ok_p (loc, start, length, stride, type))
|
||||
return error_mark_node;
|
||||
array_ntn_expr = build4 (ARRAY_NOTATION_REF, NULL_TREE, array, start,
|
||||
length, stride);
|
||||
}
|
||||
if (TREE_CODE (type) == ARRAY_TYPE || TREE_CODE (type) == POINTER_TYPE)
|
||||
TREE_TYPE (array_ntn_expr) = TREE_TYPE (type);
|
||||
else
|
||||
gcc_unreachable ();
|
||||
|
||||
if (!cilkplus_an_triplet_types_ok_p (loc, start_index, length, stride, type))
|
||||
return error_mark_node;
|
||||
|
||||
if (!processing_template_decl)
|
||||
{
|
||||
array_ntn_expr = build4 (ARRAY_NOTATION_REF, NULL_TREE, NULL_TREE,
|
||||
NULL_TREE, NULL_TREE, NULL_TREE);
|
||||
ARRAY_NOTATION_ARRAY (array_ntn_expr) = array;
|
||||
ARRAY_NOTATION_START (array_ntn_expr) = start_index;
|
||||
ARRAY_NOTATION_LENGTH (array_ntn_expr) = length;
|
||||
ARRAY_NOTATION_STRIDE (array_ntn_expr) = stride;
|
||||
if (type && (TREE_CODE (type) == ARRAY_TYPE
|
||||
|| TREE_CODE (type) == POINTER_TYPE))
|
||||
TREE_TYPE (array_ntn_expr) = TREE_TYPE (type);
|
||||
else
|
||||
TREE_TYPE (array_ntn_expr) = type;
|
||||
}
|
||||
SET_EXPR_LOCATION (array_ntn_expr, loc);
|
||||
|
||||
return array_ntn_expr;
|
||||
}
|
||||
|
||||
|
@ -1462,20 +1401,9 @@ cilkplus_an_triplet_types_ok_p (location_t loc, tree start_index, tree length,
|
|||
}
|
||||
if (!TREE_CODE (type) == FUNCTION_TYPE)
|
||||
{
|
||||
error_at (loc, "array notations cannot be used with function type");
|
||||
error_at (loc, "array notation cannot be used with function type");
|
||||
return false;
|
||||
}
|
||||
while (type && (TREE_CODE (type) == POINTER_TYPE
|
||||
|| TREE_CODE (type) == ARRAY_TYPE))
|
||||
{
|
||||
type = TREE_TYPE (type);
|
||||
if (type && TREE_CODE (type) == FUNCTION_TYPE)
|
||||
{
|
||||
error_at (loc, "array notations cannot be used with function pointer"
|
||||
" arrays");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!find_rank (loc, start_index, start_index, false, &start_rank)
|
||||
|| !find_rank (loc, length, length, false, &length_rank)
|
||||
|| !find_rank (loc, stride, stride, false, &stride_rank))
|
||||
|
|
|
@ -1207,6 +1207,12 @@ cp_genericize (tree fndecl)
|
|||
if (DECL_CLONED_FUNCTION_P (fndecl))
|
||||
return;
|
||||
|
||||
/* Expand all the array notations here. */
|
||||
if (flag_enable_cilkplus
|
||||
&& contains_array_notation_expr (DECL_SAVED_TREE (fndecl)))
|
||||
DECL_SAVED_TREE (fndecl) =
|
||||
expand_array_notation_exprs (DECL_SAVED_TREE (fndecl));
|
||||
|
||||
/* We do want to see every occurrence of the parms, so we can't just use
|
||||
walk_tree's hash functionality. */
|
||||
cp_genericize_tree (&DECL_SAVED_TREE (fndecl));
|
||||
|
|
|
@ -4974,6 +4974,7 @@ extern bool pragma_java_exceptions;
|
|||
|
||||
/* in call.c */
|
||||
extern bool check_dtor_name (tree, tree);
|
||||
bool magic_varargs_p (tree);
|
||||
|
||||
extern tree build_conditional_expr (location_t, tree, tree, tree,
|
||||
tsubst_flags_t);
|
||||
|
|
407
gcc/cp/parser.c
407
gcc/cp/parser.c
|
@ -6062,41 +6062,31 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
|
|||
return error_mark_node;
|
||||
}
|
||||
|
||||
/* This function parses Cilk Plus array notations. The starting index is
|
||||
passed in INIT_INDEX and the array name is passed in ARRAY_VALUE. If the
|
||||
INIT_INDEX is NULL, then we have special case were the entire array is
|
||||
accessed (e.g. A[:]). The return value of this function is a tree node
|
||||
called VALUE_TREE of type ARRAY_NOTATION_REF. If some error occurred it
|
||||
returns error_mark_node. */
|
||||
/* This function parses Cilk Plus array notations. If a normal array expr. is
|
||||
parsed then the array index is passed back to the caller through *INIT_INDEX
|
||||
and the function returns a NULL_TREE. If array notation expr. is parsed,
|
||||
then *INIT_INDEX is ignored by the caller and the function returns
|
||||
a tree of type ARRAY_NOTATION_REF. If some error occurred it returns
|
||||
error_mark_node. */
|
||||
|
||||
static tree
|
||||
cp_parser_array_notation (location_t loc, cp_parser *parser, tree init_index,
|
||||
cp_parser_array_notation (location_t loc, cp_parser *parser, tree *init_index,
|
||||
tree array_value)
|
||||
{
|
||||
cp_token *token = NULL;
|
||||
tree start_index = NULL_TREE, length_index = NULL_TREE, stride = NULL_TREE;
|
||||
tree value_tree, type, array_type, array_type_domain;
|
||||
double_int x;
|
||||
bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
|
||||
|
||||
tree length_index, stride = NULL_TREE, value_tree, array_type;
|
||||
if (!array_value || array_value == error_mark_node)
|
||||
{
|
||||
cp_parser_skip_to_end_of_statement (parser);
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
array_type = TREE_TYPE (array_value);
|
||||
|
||||
if (processing_template_decl)
|
||||
{
|
||||
array_type = TREE_TYPE (array_value);
|
||||
type = TREE_TYPE (array_type);
|
||||
}
|
||||
else
|
||||
{
|
||||
array_type = TREE_TYPE (array_value);
|
||||
gcc_assert (array_type);
|
||||
type = array_type;
|
||||
}
|
||||
bool saved_colon_corrects = parser->colon_corrects_to_scope_p;
|
||||
parser->colon_corrects_to_scope_p = false;
|
||||
token = cp_lexer_peek_token (parser->lexer);
|
||||
|
||||
if (!token)
|
||||
{
|
||||
cp_parser_error (parser, "expected %<:%> or numeral");
|
||||
|
@ -6104,125 +6094,57 @@ cp_parser_array_notation (location_t loc, cp_parser *parser, tree init_index,
|
|||
}
|
||||
else if (token->type == CPP_COLON)
|
||||
{
|
||||
if (!init_index)
|
||||
{
|
||||
/* If we are here, then we have a case like this A[:]. */
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
|
||||
if (cp_lexer_peek_token (parser->lexer)->type != CPP_CLOSE_SQUARE)
|
||||
{
|
||||
cp_parser_error (parser, "expected %<]%>");
|
||||
cp_parser_skip_to_end_of_statement (parser);
|
||||
return error_mark_node;
|
||||
}
|
||||
if (TREE_CODE (array_type) == RECORD_TYPE
|
||||
|| TREE_CODE (array_type) == POINTER_TYPE)
|
||||
{
|
||||
error_at (loc, "start-index and length fields necessary for "
|
||||
"using array notations in pointers or records");
|
||||
cp_parser_skip_to_end_of_statement (parser);
|
||||
return error_mark_node;
|
||||
}
|
||||
if (TREE_CODE (array_type) == ARRAY_TYPE)
|
||||
{
|
||||
tree subtype = TREE_TYPE (array_type);
|
||||
while (subtype && TREE_CODE (subtype) == POINTER_TYPE)
|
||||
{
|
||||
/* This could be a function ptr. If so, then emit error. */
|
||||
subtype = TREE_TYPE (subtype);
|
||||
if (subtype && TREE_CODE (subtype) == FUNCTION_TYPE)
|
||||
{
|
||||
error_at (loc, "array notations cannot be used with"
|
||||
" function pointer arrays");
|
||||
cp_parser_skip_to_end_of_statement (parser);
|
||||
return error_mark_node;
|
||||
}
|
||||
}
|
||||
}
|
||||
array_type_domain = TYPE_DOMAIN (array_type);
|
||||
if (!array_type_domain)
|
||||
{
|
||||
error_at (loc, "start-index and length fields necessary for "
|
||||
"using array notations in dimensionless arrays");
|
||||
cp_parser_skip_to_end_of_statement (parser);
|
||||
return error_mark_node;
|
||||
}
|
||||
start_index = TYPE_MINVAL (array_type_domain);
|
||||
start_index = fold_build1 (CONVERT_EXPR, ptrdiff_type_node,
|
||||
start_index);
|
||||
x = TREE_INT_CST (TYPE_MAXVAL (array_type_domain));
|
||||
x.low++;
|
||||
length_index = double_int_to_tree (integer_type_node, x);
|
||||
length_index = fold_build1 (CONVERT_EXPR, ptrdiff_type_node,
|
||||
length_index);
|
||||
stride = build_int_cst (integer_type_node, 1);
|
||||
stride = fold_build1 (CONVERT_EXPR, ptrdiff_type_node, stride);
|
||||
}
|
||||
else if (init_index != error_mark_node)
|
||||
{
|
||||
/* If we hare here, then there are 2 possibilities:
|
||||
1. Array [ EXPR : EXPR ]
|
||||
2. Array [ EXPR : EXPR : EXPR ]
|
||||
*/
|
||||
start_index = init_index;
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
|
||||
saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
|
||||
/* The ':' is used in array notation. Thus compiler cannot do scope
|
||||
correction automatically. */
|
||||
parser->colon_corrects_to_scope_p = false;
|
||||
length_index = cp_parser_expression (parser, false, NULL);
|
||||
parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
|
||||
if (!length_index || length_index == error_mark_node)
|
||||
cp_parser_skip_to_end_of_statement (parser);
|
||||
|
||||
if (cp_lexer_peek_token (parser->lexer)->type == CPP_COLON)
|
||||
{
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
saved_colon_corrects_to_scope_p =
|
||||
parser->colon_corrects_to_scope_p;
|
||||
/* Disable correcting single colon correcting to scope. */
|
||||
parser->colon_corrects_to_scope_p = false;
|
||||
stride = cp_parser_expression (parser, false, NULL);
|
||||
parser->colon_corrects_to_scope_p =
|
||||
saved_colon_corrects_to_scope_p;
|
||||
if (!stride || stride == error_mark_node)
|
||||
{
|
||||
cp_parser_skip_to_end_of_statement (parser);
|
||||
if (cp_lexer_peek_token (parser->lexer)->type
|
||||
== CPP_CLOSE_SQUARE)
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
}
|
||||
}
|
||||
else
|
||||
stride = build_one_cst (integer_type_node);
|
||||
}
|
||||
else
|
||||
/* Consume the ':'. */
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
|
||||
/* If we are here, then we have a case like this A[:]. */
|
||||
if (cp_lexer_peek_token (parser->lexer)->type != CPP_CLOSE_SQUARE)
|
||||
{
|
||||
cp_parser_error (parser, "expected %<]%>");
|
||||
cp_parser_skip_to_end_of_statement (parser);
|
||||
return error_mark_node;
|
||||
}
|
||||
*init_index = NULL_TREE;
|
||||
stride = NULL_TREE;
|
||||
length_index = NULL_TREE;
|
||||
}
|
||||
|
||||
if (start_index == error_mark_node || length_index == error_mark_node
|
||||
|| stride == error_mark_node || !start_index || !length_index
|
||||
|| !stride)
|
||||
else
|
||||
{
|
||||
/* If we are here, then there are three valid possibilities:
|
||||
1. ARRAY [ EXP ]
|
||||
2. ARRAY [ EXP : EXP ]
|
||||
3. ARRAY [ EXP : EXP : EXP ] */
|
||||
|
||||
*init_index = cp_parser_expression (parser, false, NULL);
|
||||
if (cp_lexer_peek_token (parser->lexer)->type != CPP_COLON)
|
||||
{
|
||||
/* This indicates that we have a normal array expression. */
|
||||
parser->colon_corrects_to_scope_p = saved_colon_corrects;
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Consume the ':'. */
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
length_index = cp_parser_expression (parser, false, NULL);
|
||||
if (cp_lexer_peek_token (parser->lexer)->type == CPP_COLON)
|
||||
{
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
stride = cp_parser_expression (parser, false, NULL);
|
||||
}
|
||||
}
|
||||
parser->colon_corrects_to_scope_p = saved_colon_corrects;
|
||||
|
||||
if (*init_index == error_mark_node || length_index == error_mark_node
|
||||
|| stride == error_mark_node)
|
||||
{
|
||||
if (cp_lexer_peek_token (parser->lexer)->type == CPP_CLOSE_SQUARE)
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
return error_mark_node;
|
||||
}
|
||||
cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
|
||||
|
||||
/* We fold all 3 of the values to make things easier when we transform
|
||||
them later. */
|
||||
start_index = fold (start_index);
|
||||
length_index = fold (length_index);
|
||||
stride = fold (stride);
|
||||
|
||||
value_tree = build_array_notation_ref (input_location, array_value,
|
||||
start_index, length_index, stride,
|
||||
type);
|
||||
value_tree = build_array_notation_ref (loc, array_value, *init_index,
|
||||
length_index, stride, array_type);
|
||||
return value_tree;
|
||||
}
|
||||
|
||||
|
@ -6241,84 +6163,68 @@ cp_parser_postfix_open_square_expression (cp_parser *parser,
|
|||
bool for_offsetof,
|
||||
bool decltype_p)
|
||||
{
|
||||
tree index;
|
||||
tree index = NULL_TREE;
|
||||
location_t loc = cp_lexer_peek_token (parser->lexer)->location;
|
||||
|
||||
/* Consume the `[' token. */
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
|
||||
if (flag_enable_cilkplus
|
||||
&& cp_lexer_peek_token (parser->lexer)->type == CPP_COLON)
|
||||
/* If we are here, then we have something like this:
|
||||
ARRAY[:]
|
||||
*/
|
||||
postfix_expression = cp_parser_array_notation (loc, parser, NULL_TREE,
|
||||
postfix_expression);
|
||||
/* Parse the index expression. */
|
||||
/* ??? For offsetof, there is a question of what to allow here. If
|
||||
offsetof is not being used in an integral constant expression context,
|
||||
then we *could* get the right answer by computing the value at runtime.
|
||||
If we are in an integral constant expression context, then we might
|
||||
could accept any constant expression; hard to say without analysis.
|
||||
Rather than open the barn door too wide right away, allow only integer
|
||||
constant expressions here. */
|
||||
if (for_offsetof)
|
||||
index = cp_parser_constant_expression (parser, false, NULL);
|
||||
else
|
||||
{
|
||||
/* Here are have these options:
|
||||
1. ARRAY[EXPR] -- This is the normal array call.
|
||||
2. ARRAY[EXPR : EXPR] -- Array notation expr with default stride
|
||||
of 1.
|
||||
3. ARRAY[EXPR : EXPR : EXPR] -- Array Notation with userdefined stride.
|
||||
4. Array[Braced List] -- This is handled by braced list.
|
||||
*/
|
||||
|
||||
/* Parse the index expression. */
|
||||
/* ??? For offsetof, there is a question of what to allow here. If
|
||||
offsetof is not being used in an integral constant expression context,
|
||||
then we *could* get the right answer by computing the value at runtime.
|
||||
If we are in an integral constant expression context, then we might
|
||||
could accept any constant expression; hard to say without analysis.
|
||||
Rather than open the barn door too wide right away, allow only integer
|
||||
constant expressions here. */
|
||||
if (for_offsetof)
|
||||
index = cp_parser_constant_expression (parser, false, NULL);
|
||||
else
|
||||
if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
|
||||
{
|
||||
bool saved_colon_corrects_to_scope_p =
|
||||
parser->colon_corrects_to_scope_p;
|
||||
if (flag_enable_cilkplus)
|
||||
parser->colon_corrects_to_scope_p = false;
|
||||
if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
|
||||
bool expr_nonconst_p;
|
||||
maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
|
||||
index = cp_parser_braced_list (parser, &expr_nonconst_p);
|
||||
if (flag_enable_cilkplus
|
||||
&& cp_lexer_peek_token (parser->lexer)->type == CPP_COLON)
|
||||
{
|
||||
bool expr_nonconst_p;
|
||||
maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
|
||||
index = cp_parser_braced_list (parser, &expr_nonconst_p);
|
||||
if (flag_enable_cilkplus
|
||||
&& cp_lexer_peek_token (parser->lexer)->type == CPP_COLON)
|
||||
{
|
||||
error_at (cp_lexer_peek_token (parser->lexer)->location,
|
||||
"braced list index is not allowed with array "
|
||||
"notations");
|
||||
index = error_mark_node;
|
||||
}
|
||||
error_at (cp_lexer_peek_token (parser->lexer)->location,
|
||||
"braced list index is not allowed with array "
|
||||
"notation");
|
||||
cp_parser_skip_to_end_of_statement (parser);
|
||||
return error_mark_node;
|
||||
}
|
||||
else
|
||||
index = cp_parser_expression (parser, /*cast_p=*/false, NULL);
|
||||
parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
|
||||
}
|
||||
if (flag_enable_cilkplus
|
||||
&& cp_lexer_peek_token (parser->lexer)->type == CPP_COLON)
|
||||
postfix_expression = cp_parser_array_notation (loc, parser, index,
|
||||
postfix_expression);
|
||||
else
|
||||
else if (flag_enable_cilkplus)
|
||||
{
|
||||
/* Look for the closing `]'. */
|
||||
cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
|
||||
|
||||
/* Build the ARRAY_REF. */
|
||||
postfix_expression = grok_array_decl (loc, postfix_expression,
|
||||
index, decltype_p);
|
||||
|
||||
/* When not doing offsetof, array references are not permitted in
|
||||
constant-expressions. */
|
||||
if (!for_offsetof
|
||||
&& (cp_parser_non_integral_constant_expression (parser,
|
||||
NIC_ARRAY_REF)))
|
||||
postfix_expression = error_mark_node;
|
||||
/* Here are have these two options:
|
||||
ARRAY[EXP : EXP] - Array notation expr with default
|
||||
stride of 1.
|
||||
ARRAY[EXP : EXP : EXP] - Array Notation with user-defined
|
||||
stride. */
|
||||
tree an_exp = cp_parser_array_notation (loc, parser, &index,
|
||||
postfix_expression);
|
||||
if (an_exp)
|
||||
return an_exp;
|
||||
}
|
||||
else
|
||||
index = cp_parser_expression (parser, /*cast_p=*/false, NULL);
|
||||
}
|
||||
|
||||
/* Look for the closing `]'. */
|
||||
cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
|
||||
|
||||
/* Build the ARRAY_REF. */
|
||||
postfix_expression = grok_array_decl (loc, postfix_expression,
|
||||
index, decltype_p);
|
||||
|
||||
/* When not doing offsetof, array references are not permitted in
|
||||
constant-expressions. */
|
||||
if (!for_offsetof
|
||||
&& (cp_parser_non_integral_constant_expression (parser, NIC_ARRAY_REF)))
|
||||
postfix_expression = error_mark_node;
|
||||
|
||||
return postfix_expression;
|
||||
}
|
||||
|
||||
|
@ -9553,8 +9459,6 @@ cp_parser_compound_statement (cp_parser *parser, tree in_statement_expr,
|
|||
/* Consume the `}'. */
|
||||
cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
|
||||
|
||||
if (flag_enable_cilkplus && contains_array_notation_expr (compound_stmt))
|
||||
compound_stmt = expand_array_notation_exprs (compound_stmt);
|
||||
return compound_stmt;
|
||||
}
|
||||
|
||||
|
@ -9747,14 +9651,6 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p)
|
|||
|
||||
/* Now we're all done with the switch-statement. */
|
||||
finish_switch_stmt (statement);
|
||||
if (flag_enable_cilkplus
|
||||
&& contains_array_notation_expr (condition))
|
||||
{
|
||||
error_at (EXPR_LOCATION (condition),
|
||||
"array notations cannot be used as a condition for "
|
||||
"switch statement");
|
||||
statement = error_mark_node;
|
||||
}
|
||||
}
|
||||
|
||||
return statement;
|
||||
|
@ -10312,12 +10208,6 @@ cp_parser_iteration_statement (cp_parser* parser)
|
|||
parser->in_statement = in_statement;
|
||||
/* We're done with the while-statement. */
|
||||
finish_while_stmt (statement);
|
||||
if (flag_enable_cilkplus && contains_array_notation_expr (condition))
|
||||
{
|
||||
error_at (EXPR_LOCATION (condition), "array notations cannot be "
|
||||
"used as a condition for while statement");
|
||||
statement = error_mark_node;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -10344,15 +10234,6 @@ cp_parser_iteration_statement (cp_parser* parser)
|
|||
cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
|
||||
/* Look for the `;'. */
|
||||
cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
|
||||
if (flag_enable_cilkplus
|
||||
&& contains_array_notation_expr (DO_COND (statement)))
|
||||
{
|
||||
error_at (EXPR_LOCATION (DO_COND (statement)),
|
||||
"array notations cannot be used as a condition for a "
|
||||
"do-while statement");
|
||||
statement = error_mark_node;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -10371,17 +10252,8 @@ cp_parser_iteration_statement (cp_parser* parser)
|
|||
cp_parser_already_scoped_statement (parser);
|
||||
parser->in_statement = in_statement;
|
||||
|
||||
if (flag_enable_cilkplus
|
||||
&& contains_array_notation_expr (FOR_COND (statement)))
|
||||
{
|
||||
error_at (EXPR_LOCATION (FOR_COND (statement)),
|
||||
"array notations cannot be used in a condition for a "
|
||||
"for-loop");
|
||||
statement = error_mark_node;
|
||||
}
|
||||
else
|
||||
/* We're done with the for-statement. */
|
||||
finish_for_stmt (statement);
|
||||
/* We're done with the for-statement. */
|
||||
finish_for_stmt (statement);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -16954,54 +16826,30 @@ cp_parser_direct_declarator (cp_parser* parser,
|
|||
if (token->type != CPP_CLOSE_SQUARE)
|
||||
{
|
||||
bool non_constant_p;
|
||||
|
||||
if (flag_enable_cilkplus
|
||||
&& cp_lexer_next_token_is (parser->lexer, CPP_COLON))
|
||||
bounds
|
||||
= cp_parser_constant_expression (parser,
|
||||
/*allow_non_constant=*/true,
|
||||
&non_constant_p);
|
||||
if (!non_constant_p)
|
||||
/* OK */;
|
||||
else if (error_operand_p (bounds))
|
||||
/* Already gave an error. */;
|
||||
else if (!parser->in_function_body
|
||||
|| current_binding_level->kind == sk_function_parms)
|
||||
{
|
||||
/* Normally, the array bound must be an integral constant
|
||||
expression. However, as an extension, we allow VLAs
|
||||
in function scopes as long as they aren't part of a
|
||||
parameter declaration. */
|
||||
cp_parser_error (parser,
|
||||
"array bound is not an integer constant");
|
||||
bounds = error_mark_node;
|
||||
error_at (cp_lexer_peek_token (parser->lexer)->location,
|
||||
"array notations cannot be used in declaration");
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
}
|
||||
else
|
||||
else if (processing_template_decl)
|
||||
{
|
||||
bounds
|
||||
= cp_parser_constant_expression (parser,
|
||||
/*allow_non_constant=*/true,
|
||||
&non_constant_p);
|
||||
if (!non_constant_p)
|
||||
/* OK */;
|
||||
else if (error_operand_p (bounds))
|
||||
/* Already gave an error. */;
|
||||
else if (!parser->in_function_body
|
||||
|| current_binding_level->kind == sk_function_parms)
|
||||
{
|
||||
/* Normally, the array bound must be an integral constant
|
||||
expression. However, as an extension, we allow VLAs
|
||||
in function scopes as long as they aren't part of a
|
||||
parameter declaration. */
|
||||
cp_parser_error (parser,
|
||||
"array bound is not an integer constant");
|
||||
bounds = error_mark_node;
|
||||
}
|
||||
else if (processing_template_decl)
|
||||
{
|
||||
/* Remember this wasn't a constant-expression. */
|
||||
bounds = build_nop (TREE_TYPE (bounds), bounds);
|
||||
TREE_SIDE_EFFECTS (bounds) = 1;
|
||||
}
|
||||
if (flag_enable_cilkplus
|
||||
&& cp_lexer_next_token_is (parser->lexer, CPP_COLON))
|
||||
{
|
||||
location_t loc =
|
||||
cp_lexer_peek_token (parser->lexer)->location;
|
||||
while (cp_lexer_next_token_is_not (parser->lexer,
|
||||
CPP_CLOSE_SQUARE))
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
error_at (loc, "array notations cannot be used in "
|
||||
"declaration");
|
||||
bounds = error_mark_node;
|
||||
}
|
||||
/* Remember this wasn't a constant-expression. */
|
||||
bounds = build_nop (TREE_TYPE (bounds), bounds);
|
||||
TREE_SIDE_EFFECTS (bounds) = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -18372,11 +18220,6 @@ cp_parser_ctor_initializer_opt_and_function_body (cp_parser *parser,
|
|||
cp_parser_function_body (parser, in_function_try_block);
|
||||
if (check_body_p)
|
||||
check_constexpr_ctor_body (last, list);
|
||||
|
||||
/* Transform all array notations to the equivalent array refs and loop. */
|
||||
if (flag_enable_cilkplus && contains_array_notation_expr (body))
|
||||
body = expand_array_notation_exprs (body);
|
||||
|
||||
/* Finish the function body. */
|
||||
finish_function_body (body);
|
||||
|
||||
|
@ -22356,12 +22199,6 @@ cp_parser_function_definition_after_declarator (cp_parser* parser,
|
|||
|
||||
finish_lambda_scope ();
|
||||
|
||||
/* Expand all array notation expressions here. */
|
||||
if (flag_enable_cilkplus && current_function_decl
|
||||
&& contains_array_notation_expr (DECL_SAVED_TREE (current_function_decl)))
|
||||
DECL_SAVED_TREE (current_function_decl) =
|
||||
expand_array_notation_exprs (DECL_SAVED_TREE (current_function_decl));
|
||||
|
||||
/* Finish the function. */
|
||||
fn = finish_function ((ctor_initializer_p ? 1 : 0) |
|
||||
(inline_p ? 2 : 0));
|
||||
|
|
11
gcc/cp/pt.c
11
gcc/cp/pt.c
|
@ -13762,9 +13762,6 @@ tsubst_copy_and_build (tree t,
|
|||
start_index = RECUR (ARRAY_NOTATION_START (t));
|
||||
length = RECUR (ARRAY_NOTATION_LENGTH (t));
|
||||
stride = RECUR (ARRAY_NOTATION_STRIDE (t));
|
||||
if (!cilkplus_an_triplet_types_ok_p (loc, start_index, length, stride,
|
||||
TREE_TYPE (op1)))
|
||||
RETURN (error_mark_node);
|
||||
RETURN (build_array_notation_ref (EXPR_LOCATION (t), op1, start_index,
|
||||
length, stride, TREE_TYPE (op1)));
|
||||
}
|
||||
|
@ -15747,9 +15744,6 @@ type_unification_real (tree tparms,
|
|||
arg = args[ia];
|
||||
++ia;
|
||||
|
||||
if (flag_enable_cilkplus && TREE_CODE (arg) == ARRAY_NOTATION_REF)
|
||||
return 1;
|
||||
|
||||
if (unify_one_argument (tparms, targs, parm, arg, subr, strict,
|
||||
flags, explain_p))
|
||||
return 1;
|
||||
|
@ -19170,11 +19164,6 @@ instantiate_decl (tree d, int defer_ok,
|
|||
pointer_map_destroy (local_specializations);
|
||||
local_specializations = saved_local_specializations;
|
||||
|
||||
/* We expand all the array notation expressions here. */
|
||||
if (flag_enable_cilkplus
|
||||
&& contains_array_notation_expr (DECL_SAVED_TREE (d)))
|
||||
DECL_SAVED_TREE (d) = expand_array_notation_exprs (DECL_SAVED_TREE (d));
|
||||
|
||||
/* Finish the function. */
|
||||
d = finish_function (0);
|
||||
expand_or_defer_fn (d);
|
||||
|
|
|
@ -779,22 +779,6 @@ finish_return_stmt (tree expr)
|
|||
tree r;
|
||||
bool no_warning;
|
||||
|
||||
if (flag_enable_cilkplus && contains_array_notation_expr (expr))
|
||||
{
|
||||
size_t rank = 0;
|
||||
|
||||
if (!find_rank (input_location, expr, expr, false, &rank))
|
||||
return error_mark_node;
|
||||
|
||||
/* If the return expression contains array notations, then flag it as
|
||||
error. */
|
||||
if (rank >= 1)
|
||||
{
|
||||
error_at (input_location, "array notation expression cannot be "
|
||||
"used as a return value");
|
||||
return error_mark_node;
|
||||
}
|
||||
}
|
||||
expr = check_return_expr (expr, &no_warning);
|
||||
|
||||
if (flag_openmp && !check_omp_return ())
|
||||
|
@ -8089,7 +8073,6 @@ cxx_eval_constant_expression (const constexpr_call *call, tree t,
|
|||
non_constant_p, overflow_p);
|
||||
break;
|
||||
|
||||
case ARRAY_NOTATION_REF:
|
||||
case ARRAY_REF:
|
||||
r = cxx_eval_array_reference (call, t, allow_non_constant, addr,
|
||||
non_constant_p, overflow_p);
|
||||
|
@ -8901,7 +8884,6 @@ potential_constant_expression_1 (tree t, bool want_rval, tsubst_flags_t flags)
|
|||
want_rval = true;
|
||||
/* Fall through. */
|
||||
case ARRAY_REF:
|
||||
case ARRAY_NOTATION_REF:
|
||||
case ARRAY_RANGE_REF:
|
||||
case MEMBER_REF:
|
||||
case DOTSTAR_EXPR:
|
||||
|
@ -8912,6 +8894,9 @@ potential_constant_expression_1 (tree t, bool want_rval, tsubst_flags_t flags)
|
|||
return false;
|
||||
return true;
|
||||
|
||||
case ARRAY_NOTATION_REF:
|
||||
return false;
|
||||
|
||||
case FMA_EXPR:
|
||||
case VEC_PERM_EXPR:
|
||||
for (i = 0; i < 3; ++i)
|
||||
|
|
|
@ -3493,10 +3493,6 @@ cp_build_function_call_vec (tree function, vec<tree, va_gc> **params,
|
|||
params = &allocated;
|
||||
}
|
||||
|
||||
if (flag_enable_cilkplus
|
||||
&& is_cilkplus_reduce_builtin (fndecl) != BUILT_IN_NONE)
|
||||
nargs = (*params)->length ();
|
||||
else
|
||||
nargs = convert_arguments (parm_types, params, fndecl, LOOKUP_NORMAL,
|
||||
complain);
|
||||
if (nargs < 0)
|
||||
|
@ -3660,8 +3656,7 @@ convert_arguments (tree typelist, vec<tree, va_gc> **values, tree fndecl,
|
|||
}
|
||||
else
|
||||
{
|
||||
if (fndecl && DECL_BUILT_IN (fndecl)
|
||||
&& DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CONSTANT_P)
|
||||
if (fndecl && magic_varargs_p (fndecl))
|
||||
/* Don't do ellipsis conversion for __built_in_constant_p
|
||||
as this will result in spurious errors for non-trivial
|
||||
types. */
|
||||
|
@ -3956,15 +3951,8 @@ cp_build_binary_op (location_t location,
|
|||
}
|
||||
}
|
||||
|
||||
if (flag_enable_cilkplus && contains_array_notation_expr (op0))
|
||||
type0 = find_correct_array_notation_type (op0);
|
||||
else
|
||||
type0 = TREE_TYPE (op0);
|
||||
|
||||
if (flag_enable_cilkplus && contains_array_notation_expr (op1))
|
||||
type1 = find_correct_array_notation_type (op1);
|
||||
else
|
||||
type1 = TREE_TYPE (op1);
|
||||
type0 = TREE_TYPE (op0);
|
||||
type1 = TREE_TYPE (op1);
|
||||
|
||||
/* The expression codes of the data types of the arguments tell us
|
||||
whether the arguments are integers, floating, pointers, etc. */
|
||||
|
@ -5182,13 +5170,6 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain)
|
|||
|
||||
gcc_assert (!identifier_p (arg) || !IDENTIFIER_OPNAME_P (arg));
|
||||
|
||||
if (flag_enable_cilkplus && TREE_CODE (arg) == ARRAY_NOTATION_REF)
|
||||
{
|
||||
val = build_address (arg);
|
||||
if (TREE_CODE (arg) == OFFSET_REF)
|
||||
PTRMEM_OK_P (val) = PTRMEM_OK_P (arg);
|
||||
return val;
|
||||
}
|
||||
if (TREE_CODE (arg) == COMPONENT_REF && type_unknown_p (arg)
|
||||
&& !really_overloaded_fn (TREE_OPERAND (arg, 1)))
|
||||
{
|
||||
|
@ -7867,13 +7848,6 @@ convert_for_assignment (tree type, tree rhs,
|
|||
tree rhstype;
|
||||
enum tree_code coder;
|
||||
|
||||
/* If we are dealing with built-in array notation function then we don't need
|
||||
to convert them. They will be broken up into modify exprs in future,
|
||||
during which all these checks will be done. */
|
||||
if (flag_enable_cilkplus
|
||||
&& is_cilkplus_reduce_builtin (fndecl) != BUILT_IN_NONE)
|
||||
return rhs;
|
||||
|
||||
/* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */
|
||||
if (TREE_CODE (rhs) == NON_LVALUE_EXPR)
|
||||
rhs = TREE_OPERAND (rhs, 0);
|
||||
|
|
|
@ -1,3 +1,13 @@
|
|||
2013-06-28 Balaji V. Iyer <balaji.v.iyer@intel.com>
|
||||
|
||||
* c-c++-common/cilk-plus/AN/decl-ptr-colon.c (main): Made this testcase
|
||||
c specific.
|
||||
* c-c++-common/cilk-plus/AN/decl-ptr-colon.c (main): Changed dg-error
|
||||
strings to match the fixed error messages.
|
||||
* c-c++-common/cilk-plus/AN/misc.c (main): Likewise.
|
||||
* c-c++-common/cilk-plus/AN/rank_mismatch.c (main): Added a new error
|
||||
message check.
|
||||
|
||||
2013-06-28 Michael Meissner <meissner@linux.vnet.ibm.com>
|
||||
|
||||
PR target/57744
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* { dg-do compile { target c } } */
|
||||
/* { dg-options "-fcilkplus" } */
|
||||
|
||||
int main(void)
|
||||
|
|
|
@ -5,6 +5,6 @@ extern int *b;
|
|||
|
||||
void foo()
|
||||
{
|
||||
a[:] = 5; // { dg-error "start-index and length fields necessary for using array notations in dimensionless arrays" }
|
||||
b[:] = 5; // { dg-error "start-index and length fields necessary for using array notations in pointers" }
|
||||
a[:] = 5; // { dg-error "start-index and length fields necessary for using array notation" }
|
||||
b[:] = 5; // { dg-error "start-index and length fields necessary for using" }
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-fcilkplus" } */
|
||||
|
||||
typedef int (*foo)(int);
|
||||
|
@ -10,11 +11,11 @@ int main(void)
|
|||
foo ***func_array_ptr;
|
||||
int argc = 5;
|
||||
|
||||
array[:] = func_array[:](10); /* { dg-error "array notations cannot be used with function pointer arrays" } */
|
||||
func_array[0:5](10); /* { dg-error "array notations cannot be used with function pointer arrays" } */
|
||||
func_array2[0:5][:](10); /* { dg-error "array notations cannot be used with function pointer arrays" } */
|
||||
array2[0:5][:] = func_array2[0:5][:](10); /* { dg-error "array notations cannot be used with function pointer arrays" } */
|
||||
func_array_ptr[0:5][0:4][0:argc:2](argc); /* { dg-error "array notations cannot be used with function pointer arrays" } */
|
||||
array[:] = func_array[:](10);
|
||||
func_array[0:5](10);
|
||||
func_array2[0:5][:](10);
|
||||
array2[0:5][:] = func_array2[0:5][:](10);
|
||||
func_array_ptr[0:5][0:4][0:argc:2](argc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ int main (void)
|
|||
int array[10], array2[10][10];
|
||||
int x, ii, jj ;
|
||||
|
||||
switch (array[:]) { /* { dg-error "array notations cannot be used as a condition for switch statement" } */
|
||||
switch (array[:]) { /* { dg-error "cannot be used as a condition for switch statement" } */
|
||||
case 1:
|
||||
x = 5;
|
||||
break;
|
||||
|
@ -17,7 +17,7 @@ int main (void)
|
|||
x = 9;
|
||||
}
|
||||
|
||||
switch (array2[:][:]) { /* { dg-error "array notations cannot be used as a condition for switch statement" } */
|
||||
switch (array2[:][:]) { /* { dg-error "cannot be used as a condition for switch statement" } */
|
||||
case 1:
|
||||
x = 5;
|
||||
break;
|
||||
|
@ -28,7 +28,7 @@ int main (void)
|
|||
x = 9;
|
||||
}
|
||||
|
||||
switch (array[:] + x) { /* { dg-error "array notations cannot be used as a condition for switch statement" } */
|
||||
switch (array[:] + x) { /* { dg-error "cannot be used as a condition for switch statement" } */
|
||||
case 1:
|
||||
x = 5;
|
||||
break;
|
||||
|
@ -39,7 +39,7 @@ int main (void)
|
|||
x = 9;
|
||||
}
|
||||
|
||||
switch (array2[:][1:x:4] + x) { /* { dg-error "array notations cannot be used as a condition for switch statement" } */
|
||||
switch (array2[:][1:x:4] + x) { /* { dg-error "cannot be used as a condition for switch statement" } */
|
||||
case 1:
|
||||
x = 5;
|
||||
break;
|
||||
|
@ -50,36 +50,36 @@ int main (void)
|
|||
x = 9;
|
||||
}
|
||||
|
||||
for (ii = 0; ii < array[:]; ii++) /* { dg-error "array notations cannot be used in a condition for a for-loop" } */
|
||||
for (ii = 0; ii < array[:]; ii++) /* { dg-error "cannot be used in a condition for a for-loop" } */
|
||||
{
|
||||
x = 2;
|
||||
}
|
||||
|
||||
for (ii = 0; ii < array2[:][:]; ii++) /* { dg-error "array notations cannot be used in a condition for a for-loop" } */
|
||||
for (ii = 0; ii < array2[:][:]; ii++) /* { dg-error "cannot be used in a condition for a for-loop" } */
|
||||
{
|
||||
x = 3;
|
||||
}
|
||||
|
||||
for (; array2[:][:] < 2;) /* { dg-error "array notations cannot be used in a condition for a for-loop" } */
|
||||
for (; array2[:][:] < 2;) /* { dg-error "cannot be used in a condition for a for-loop" } */
|
||||
x = 4;
|
||||
|
||||
|
||||
while (array2[:][:]) /* { dg-error "array notations cannot be used as a condition for while statement" } */
|
||||
while (array2[:][:]) /* { dg-error "cannot be used as a condition for while statement" } */
|
||||
x = 3;
|
||||
|
||||
while (array[1:1:1]) /* { dg-error "array notations cannot be used as a condition for while statement" } */
|
||||
while (array[1:1:1]) /* { dg-error "cannot be used as a condition for while statement" } */
|
||||
x = 1;
|
||||
|
||||
while (ii != array2[1:x:3][1:2:1]) /* { dg-error "array notations cannot be used as a condition for while statement" } */
|
||||
while (ii != array2[1:x:3][1:2:1]) /* { dg-error "cannot be used as a condition for while statement" } */
|
||||
x = 2;
|
||||
|
||||
do { /* { dg-error "array notations cannot be used as a condition for a do-while statement" "" { target c } } */
|
||||
do { /* { dg-error "cannot be used as a condition for a do-while statement" "" { target c } } */
|
||||
x = 3;
|
||||
} while (ii != array2[:][:]); /* { dg-error "array notations cannot be used as a condition for a do-while statement" "" { target c++ } } */
|
||||
} while (ii != array2[:][:]); /* { dg-error "cannot be used as a condition for a do-while statement" "" { target c++ } } */
|
||||
|
||||
do { /* { dg-error "array notations cannot be used as a condition for a do-while statement" "" { target c } } */
|
||||
do { /* { dg-error "cannot be used as a condition for a do-while statement" "" { target c } } */
|
||||
x = 2;
|
||||
} while (ii != (x + array2[:][1:x:2]) + 2); /* { dg-error "array notations cannot be used as a condition for a do-while statement" "" { target c++ } } */
|
||||
} while (ii != (x + array2[:][1:x:2]) + 2); /* { dg-error "cannot be used as a condition for a do-while statement" "" { target c++ } } */
|
||||
|
||||
do {
|
||||
x += 3;
|
||||
|
|
|
@ -10,6 +10,7 @@ int main (void)
|
|||
int array[10][10], array2[10];
|
||||
|
||||
array[:][:] = array[:]; /* { dg-error "rank mismatch between" } */
|
||||
/* { dg-error "invalid conversion" "" { target c++ } 12 } */
|
||||
|
||||
x = array2[:]; /* { dg-error "cannot be scalar when" } */
|
||||
|
||||
|
|
Loading…
Reference in New Issue